WebPack: How to look both for bower.json and .bower.json - node.js

I have been able to get webpack to look for components inside bower_components. I'm running in to issues when a bower component only includes .bower.json and not a bower.json file (notice that the first filename is preceded by a .).
A simplified version of my webpack.config.js file looks as follows:
var ResolverPlugin = require('webpack/lib/ResolverPlugin');
// webpack configuration
module.exports = {
entry: {
app: 'app.js'
},
output: {
filename: '[name].js'
},
resolve: {
modulesDirectories: ['node_modules', 'web_modules', 'bower_components', 'static']
},
plugins: [
new ResolverPlugin(
new ResolverPlugin.DirectoryDescriptionFilePlugin('bower.json', ['main'])
)
]
};
I'm trying to use jquery.selectBoxIt as a bower component. Another issue might be that its lacking a main field in its .bower.json file. For what it's worth, I've included that file below:
// .bower.json
{
"name": "jquery.selectBoxIt",
"homepage": "https://github.com/gfranko/jquery.selectBoxIt.js",
"version": "3.8.1",
"_release": "3.8.1",
"_resolution": {
"type": "version",
"tag": "v3.8.1",
"commit": "ffa615b25ebf4fac392726b17c857d429acf244c"
},
"_source": "git://github.com/gfranko/jquery.selectBoxIt.js.git",
"_target": "~3.8.1",
"_originalSource": "jquery.selectBoxIt",
"_direct": true
}

.bower.json is a file generated by Bower during dependency resolution. It is not equivalent to bower.json and generally should not be used as it is an internal file which may change.
In cases where you see only a .bower.json file it means that the package does not have a bower.json (Bower can actually work without it). In such cases it means that you will not be able to find the "main" property.
For example the jquery.selectBoxIt.js package has bower.json file only in their master branch but not in their release tags (it was probably not released yet). When you resolve it, Bower will use the 3.8.1 git tag as you can see in the .bower.json file. In this tag there is no bower.json file.
For such packages you may want to consider another option such as CommonsJS.

Related

Bundle NPM Package so it has different import paths with Vite and Typescript

How can I bundle my NPM package in a way that I can have different import paths for different parts of the package? I have found webpack approaches, but I am using Vite and TS.
My package looks like this:
- src
- atoms
- molecules
- organism
- index.ts (currently simply imports and exports everything)
Now I can use this currently like this
import { Button } from '#mypackage/library'
How can I do it, so I get this outcome:
import { Button } from '#mypackage/library/atom'
Here is the relevant part of my package.json
{
"entry": "src/index.ts",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.cjs.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json",
"./atoms": "./src/atoms/index.ts",
"./molecules": "./src/molecules/index.ts",
"./organisms": "./src/organisms/index.ts",
"./theme": "./src/theme/index.ts"
},
}
Here is my vite.config.ts
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
name: '#workdigtital/component-library-react',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM'
},
exports: 'named'
}
}
},
plugins: [react(), dts({ insertTypesEntry: true })],
resolve: {
alias: {
'#': path.resolve(__dirname, './src')
}
}
});
If I currently try an import like this, inside another project (Laravel+React), in which installed the library.
import { ThemeProvider } from '#workdigital/component-library-react/theme';
I get the following run time error (But no Typescript errors, even IntelliSense is working):
Failed to load url /resources/js/theme/ThemeProvider (resolved id: /resources/js/theme/ThemeProvider). Does the file exist?
My resulting Dist folder looks like this:
You can't have TypeScript exports, this simply won't work. An npm package should have only JS exports.
If you want to be able to selectively import different parts of your package, you must transpile them to different files.
rollup can do it, but it is lots of work, as you will have to set up a separate target for each exported file. Normally you use rollup to create a single bundle, this what this tool is made for.
tsc with a tsconfig.json will be a much better choice in your case. It does this by default, you only need to specify the output directory and it will produce a separate file for each source.
There is an excellent guide on the TypeScript site about packaging TypeScript libraries, you should probably start there.

How to replace sass variable values using grunt-sass-replace?

I want to replace few sass variable values inside a sass config file.
For example, I want to replace the value of variable "$file_global" = "new";
I want to use "grunt-sass-replace" package to do the work, i tried alot but its giving me various errors.
My Project Directory Structure:
grep/
/node_modules/
package.json
Gruntfile.js
src/
my-styles.scss
my-styles.scss Code:
$file_global: "old";
Gruntfile.js Code:
module.exports = function(grunt){
pkg: grunt.file.readJSON('package.json'),
grunt.initConfig({
'sass-replace': {
files: { // File Options
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
},
options: {
variables: [
{
name: 'file_global',
to: 'new'
}
]
}
}
});
grunt.loadNpmTasks('grunt-sass-replace');
grunt.registerTask('default', ['sass-replace']);
};
package.json Code:
{
"name": "grep",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "KJ",
"license": "ISC",
"devDependencies": {
"grunt": "^1.0.4",
"grunt-sass-replace": "^0.1.18",
"npm-check-updates": "^3.1.9"
}
}
I updated the "files" but its still giving me various errors.
Below are the options that i tried and the errors generated.
First Try
// Option First :
files: {
'dest/my-styles.scss': 'src/my-styles.scss'
},
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
Warning: no files passed. Use --force to continue..
Aborted due to warnings.
Second Try:
// Option Second :
files: [
{
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
}
],
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
Warning: pattern.indexOf is not a function Use --force to continue.
Aborted due to warnings.
Last Try:
// Option Third :
files: {
src: 'src/my-styles.scss',
dest: 'dest/my-styles.scss'
},
ERROR :
C:\wamp64\www\GREP>grunt
>> Tasks directory "C:\wamp64\www\GREP\node_modules\grunt-sass-replace\node_modules\grunt-string-replace\tasks" not found.
Running "sass-replace:files" (sass-replace) task
>> [1] scss files found in [1] passed files.
>> replacements resolved successfully.
running string-replace task.
Warning: Task "string-replace:sass" not found. Use --force to continue.
Aborted due to warnings.
Anyone know how to solve this error, or any other grunt package which can do this kind of work.
This package was last updated 3 years ago, also it uses grunt ~0.4.5. I can't help you with this, However checkout "grunt-sass-replace-values" from https://www.npmjs.com/package/grunt-sass-replace-values. This package is updated a year ago and patched.
npm install grunt-sass-replace-values --save-dev
Check out following issue on Github:
https://github.com/eliranmal/grunt-sass-replace/issues/1
Explanation :
Cause of errors :
You defined sass variable incorrectly. Variables should be defined as "$variable: value;" and not like "$variable = value;"
As of the Github issue with this package, you need to update the path to your "grunt-string-replace" dependency.
Solution :
Under your project root folder, Go to below directory:
node_modules/grunt-sass-replace/tasks
Once you're in the above directory, look for a file name "sass-replace.js"
Just open the file with any Text Editor, and Edit the path to dependency.
grunt.task.loadTasks(path.resolve(__dirname, '../node_modules/grunt-string-replace/tasks'));
In your case edit this like as below :
grunt.task.loadTasks(path.resolve(__dirname, '../../../node_modules/grunt-string-replace/tasks'));
I hope this solves your problem. If not use another package, or use older node and grunt(0.4.5) versions.

require cdn libraries in browserify without bundling it in the final js file

If I have a library that is being pulled down from cdn and wouldn't like it to be part of the final js file but be able to require it using browserify, how would I solve it?
Here is how I currently solve it using alias and a shim file.
browserify: {
options: {
debug: true,
transform: [ 'reactify' ],
alias: [
'client/shims/jquery.js:jquery'
]
},
app: {
src: 'client/app.js',
dest: 'public/app.js'
}
}
here is the shim file client/shims/jquery.js which I alias to jquery so I can use require('jquery') instead of the full path.
module.exports = $;
Is there a shortcut in grunt-browserify to support this scenario? I would like to know if it is possible to define it in Gruntfile.js without creating the shim file.
Adding external: [ 'jquery' ] seems to totally ignore it and doesn't work.
With browserify-shim you can add this in your package.json file:
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"jquery": "global:$"
}
Then jquery will be available in your modules via require('jquery')
If you load jQuery before the Browserify bundle on the page, $ will be available as a global.

Durandal.js optimizer generating empty main-built.js

I am trying to optimize my Durandal app but the main-built.js is blank.
I have tried running node r.js -o app.build.js and this threw an error saying that it could not find a file. I added these paths in my main.js file and each individual error went away. However, now the command above just exits with "Tracing dependencies for: durnadal/amd/almond.custom" and the file is still blank.
Question: Which libraries need to go into the paths below? It seems to the external libraries that I use in my index.html and it needs the exact file name?
require.config({
paths: {
"text": "durandal/amd/text",
"breeze": "lib/breeze/breeze.min",
"knockout": "lib/knockout/knockout.mapping-latest",
}
});
When I run Optimizer.exe in the Durandal AMD folder main-built.js is blank. This is the app.build.js file that is generated - any help appreciated on how to get more verbose logging with Almond. I have tried optimizer -verbose true with no luck.
{
"name": "durandal/amd/almond-custom",
"inlineText": true,
"stubModules": [
"durandal/amd/text"
],
"paths": {
"text": "durandal/amd/text"
},
"baseUrl": "C:\\DNNDev.me\\DesktopModules\\Framework.App\\App",
"mainConfigFile": "C:\\DNNDev.me\\DesktopModules\\Framework.App\\App\\main.js",
"include": [
"text!about.html",
"about",
"appNavigation",
"config",
"text!dareAdd.html",
"dareAdd",
"text!dareDetail.html",
"dareDetail",
"text!dareList.html",
"dareList",
"text!dareListItem.html",
"dataContext",
"dataService",
"dataServiceHelper",
"enums",
"errorWatcher",
"text!home.html",
"home",
"text!index.html",
"text!indextopcoat.html",
"indextopcoat",
"text!kendoIndex.html",
"text!loader.html",
"logger",
"text!login.html",
"login",
"main-built",
"main",
"text!menu.html",
"model",
"text!navbar.html",
"text!notifyOfError.html",
"notifyOfError",
"text!privacy.html",
"privacy",
"text!profile.html",
"profile",
"text!shell.html",
"shell",
"text!signup.html",
"signup",
"text!testpage.html",
"testpage",
"uiutilities",
"userState",
"viewModelHelper",
"text!walkthrough.html",
"walkthrough",
"widgetService",
"css/telerik/js/kendo.dataviz.min",
"css/topcoat/js/hello",
"css/topcoat/js/hello.min",
"css/topcoat/js/index",
"css/topcoat/lib/hello",
"css/topcoat/lib/vendor/ender.min",
"css/topcoat/lib/vendor/fastclick",
"durandal/app",
"durandal/composition",
"durandal/events",
"durandal/http",
"text!durandal/messageBox.html",
"durandal/messageBox",
"durandal/modalDialog",
"durandal/system",
"durandal/viewEngine",
"durandal/viewLocator",
"durandal/viewModel",
"durandal/viewModelBinder",
"durandal/widget",
"durandal/plugins/router",
"durandal/transitions/entrance",
"js/cordova",
"js/facebookscript",
"lib/bootstrap/bootstrap",
"lib/bootstrap/bootstrap.min",
"lib/breeze/breeze.debug",
"lib/breeze/breeze.intellisense",
"lib/breeze/breeze.min",
"lib/breeze/q",
"lib/breeze/q.min",
"lib/jquery/jquery-2.0.3.intellisense",
"lib/jquery/jquery-2.0.3",
"lib/jquery/jquery-2.0.3.min",
"lib/knockout/knockout-2.3.0.debug",
"lib/knockout/knockout-2.3.0",
"lib/knockout/knockout.mapping-latest.debug",
"lib/knockout/knockout.mapping-latest",
"lib/knockout/knockout.validation.debug",
"lib/knockout/knockout.validation",
"lib/moment/moment",
"lib/moment/moment.min",
"lib/ratchet/ratchet",
"lib/sammy/sammy-0.7.4",
"lib/sammy/sammy-0.7.4.min",
"lib/toastr/toastr",
"lib/toastr/toastr.min"
],
"exclude": [],
"keepBuildDir": true,
"optimize": "uglify2",
"out": "C:\\DNNDev.me\\DesktopModules\\Framework.App\\App\\main-built.js",
"pragmas": {
"build": true
},
"wrap": true,
"insertRequire": [
"main"
]
}
In your path you are setting your reference to knockout equal to the mapping plugin, which is no bueno.
As shown in this answer, Durandal.js optimizer not working (empty main-built.js) you can run it like Rainer shows and you should see a more specific error.
One thing that I found - if you remove a view model or use a folder or directory as a purgatory (about to be deleted) those files may not be used in your app but if they are in the file structure they will still be evaluated by the optimizer.
EDIT
Check here for more info on the optimizer - Tracking down optimizer issues in durandal.js
Also, are you building debug or release? Are you targeting the correct one? durandal optimizer references wrong path when building it as a post build process in Visual Studio
Also, if you are referencing Knockout.js, I think you mean to reference "lib/knockout/knockout-2.3.0" not the knockout mapping plugin.
Unless I am missing something you shouldn't have to add those paths to your main.js file. Breeze and Knockout should be referenced already. Depending on your project type, your editor, etc... it is probably bundled in your App.Start folder under DurandalBundleConfig. If it is not then are you just referencing the libraries from your index.html?
Move them into the bundle config if that is the case (something like this) -
bundles.Add(
new ScriptBundle("~/scripts/vendor")
.Include("~/Scripts/jquery-{version}.js")
.Include("~/Scripts/jquery-ui-{version}.min.js")
.Include("~/Scripts/knockout-{version}.js")
.Include("~/Scripts/sammy-{version}.js")
.Include("~/Scripts/bootstrap.min.js")
.Include("~/Scripts/knockout-bootstrap.min.js")
.Include("~/Scripts/Q.js")
.Include("~/Scripts/breeze.debug.js")
);
Note that you need to load Q prior to Breeze, as Breeze depends on Q.

Grunt warning: No source files found

I am trying to use Grunt for the first time. I think that I'm properly following the directions to install and use Grunt with a plugin (grunt-text-replace). (See, for instance, Grunt's page and the plugin's.) But I can't successfully run anything -- instead, I keep getting the same error. I've been checking my code against the instructions from both Grunt and the plugin, but I can't see anything I did wrong.
Here is my package.json file:
{
"name": "brink-prototype",
"version": "0.0.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.1.1",
"grunt-contrib-nodeunit": "~0.1.2",
"grunt-text-replace": "~0.3.2"
}
}
And here is my Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
replace: {
src: ['components/bootstrap/less/navbar.less'],
dest: 'build/',
replacements: [{
from: /\.box-shadow.*$/g,
to: ''
}]
}
});
grunt.loadNpmTasks('grunt-text-replace');
grunt.registerTask('default', ['replace']);
};
When I run "grunt" in the command line, I get the following error:
Running "replace:src" (replace) task
Warning: No source files found Use --force to continue.
Aborted due to warnings.
I also tried this process with another plugin (grunt-regex-replace) and had exactly the same error message.
Where have I gone wrong?
UPDATE:
Here are the relevant parts of the file structure:
project/
Gruntfile.js
package.json
components/
bootstrap/
less/
navbar.less
node_modules/
grunt/
grunt-text-replace/
I have been trying to run the command from the project/ directory, where the Gruntfile.js is.
Maybe the path in my src should be relative to something else? I don't know.
The grunt-text-replace plugin requires you to specify a subtask.
replace: {
aSubtaskName: {
src: ['components/bootstrap/less/navbar.less'],
dest: 'build/',
replacements: [{
from: /\.box-shadow.*$/g,
to: ''
}]
}
}

Resources