I've created a simple webpack 4 demo-project which doesn't have any configuration. I added a simple index.js that just prints out a simple line and all works well. A 900 byte main.js is generated as expected.
However, when i require the 24kb library 'sjcl' (has 0 dependencies) and then execute the build, a 400kb file is generated. I've used an analyzer to Any ideas onto what is going on?
It's like webpack is importing a ton of dependencies to handle this library. How can i mitigate this?
index.js
require("sjcl");
console.log("hello world");
package.json
{
"name": "js-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"sjcl": "1.0.7"
},
"devDependencies": {
"webpack": "4.16.5",
"webpack-cli": "3.1.0"
}
}
WARNING in asset size limit: The following asset(s) exceed the
recommended size limit (244 KiB). This can impact web performance.
Assets: main.js (323 KiB)
Below is my analyzer:
https://pastebin.com/iguWmmaS
Looks like webpack adds a browser compatible version of the node crypto module to the bundle, thus significantly increasing the size. To prevent Webpack from doing this, you can use the below option for webpack to ignore the library.
module: {
noParse: [
/sjcl\.js$/,
]
}
Related
I'm currently having a weird issue:
Uncaught (in promise) ReferenceError: Cannot access 'Agile' before initialization,
which is probably caused by webpack trying to correctly transform the ESM part of my library into CommonJs. Unfortunately, it doesn't do a good job and I end up with the error mentioned above.
My library supports both: CommonJs and ESM. So I'm wondering why webpack uses the ESM part and transforms it into CommonJs, instead of directly using the CommonJs part of my library?!
Why am I so sure that it has something to do with the ESM to CommonJs transformation?
Well, I once forced webpack to use the CommonJs part of my library by removing the ESM support. By doing so, I simply deleted the path to the ESM module in the package.json of my library.
"module": "dist/esm/index.js"
After unsupporting ESM, webpack was forced to use the CommonJs part
and it works as expected, since webpack doesn't have to transform anything anymore. (see image)
ESM transformed to CommonJS [not working]
Untransformed CommonJS [working]
Since my library should support both: ESM and CommonJS,
simply unsupporting ESM is no solution.
Here is the package.json of my library:
{
"name": "#agile-ts/core",
"version": "0.2.0+17b078aa",
"author": "BennoDev",
"license": "MIT",
"homepage": "https://agile-ts.org/",
"description": "Spacy, Simple, Scalable State Management Framework",
"keywords": [
// ..
],
"main": "dist/index.js", // <!-- CommonJs
"module": "dist/esm/index.js", // <!-- ESM
"types": "dist/index.d.ts",
"scripts": {
// ..
},
"dependencies": {
"#agile-ts/utils": "^0.0.8"
},
"peerDependencies": {
"#agile-ts/logger": "^0.0.8"
},
"peerDependenciesMeta": {
"#agile-ts/logger": {
"optional": true
}
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/agile-ts/agile.git"
},
"bugs": {
"url": "https://github.com/agile-ts/agile/issues"
},
"files": [
"dist",
"LICENSE",
"README.md",
"CHANGELOG.md"
],
"sideEffects": false
}
Maybe I've misconfigured something in the package.json
and thus webpack uses ESM although it requires CommonJs?
Node Version: v16.3.0
Github Repo: https://github.com/agile-ts/agile/tree/master/packages/core
Ok, I fixed this issue by resolving all circular dependencies ^^
See: https://github.com/agile-ts/agile/issues/193
I have a library in folder common with package.json:
{
"name": "common",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
I have another project that uses this library, in folder article with package.json:
{
"name": "article",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"webpack": "^5.1.3",
"webpack-cli": "^4.0.0"
}
}
Locally I did:
cd common
yarn link
cd ../article
yarn link common
This works fine I locally publish library and use it.
Now I want to deploy this project to CI, and I don't know how to make it work in another computer. Do I have to run this as a script, or is there a better way to use a local library.
If you don't want to create a module, you would want to get the code out to someplace like a repository so other env can access it. Perhaps try using it from git hub using the method from this article:
https://medium.com/pravin-lolage/how-to-use-your-own-package-from-git-repository-as-a-node-module-8b543c13957e
There is something called Yarn Workspaces: https://classic.yarnpkg.com/en/docs/workspaces/.
Basically in the root of your project you create a package.json file and add these properties in:
{
"workspaces": [
"common",
"article"
]
}
and run yarn install and now you can use these local libraries within your other projects.
I’m creating a Javascript library. Inside my project there’s a folder that contains examples of how to use the library. Inside each of the examples is a webpack config file with the entire purpose of bundling that example and serving it over webpack-dev-server with hot reloading. Each of these examples also has the library (at the root of the project) listed as a local NPM dependency. I have hot reloading working for each example and I have babel compiling the library at the root on a watch command.
Primary question: Is there a way that I can have the hot reloader of webpack-dev-server respond to changes in that local NPM dependency?
Secondary question: Is this intended to be the default behavior of webpack? If so, what is could be wrong with my machine/config file?
General/vague question: Am I doing this wrong? I feel like it should be a lot easier to serve local examples (I’m not interested in using Storybook either as the examples I’m writing aren’t in React, Vue, Angular, etc... it's all straight-up vanilla Javascript).
Here's my webpack.config.js file:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = (env, argv) => ({
mode: argv.mode,
entry: './index.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'index.bundle.js'
},
devtool: argv.mode === 'development' ? '#eval-source-map' : 'source-map',
devServer: {
port: 8080,
hot: true,
open: true,
stats: {
children: false, // Hide children information
maxModules: 0 // Set the maximum number of modules to be shown
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
plugins: [new HtmlWebpackPlugin({ template: './index.html' })]
});
And my package.json file (note that syft.js is the local dependency I want to watch for changes):
{
"name": "with-grid",
"version": "1.0.0",
"private": true,
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development",
"build": "rm -rf dist && webpack --mode production",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "",
"devDependencies": {
"babel-loader": "^8.0.6",
"html-webpack-plugin": "^3.2.0",
"path": "^0.12.7",
"webpack": "^4.39.1",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"syft.js": "file:../.."
}
}
Folder structure is like such:
dist
index.js (Babel-generated file, what package.json points to, and the file that I want to be watched)
examples
with-grid
webpack.config.js (referenced above)
package.json (referenced above)
src
index.js (main src file)
Operating System: MacOS 10.14.6
Browser: Chrome 76
Node: 12.8.0
NPM: 6.10.3
Yarn: 1.17.3
I opted for a different strategy that now seems very obvious in retrospect. Rather than treating my library like a local node dependency that needs to be resolved, I can just simply import it locally.
When importing from my example folder, I do:
import syft from '../../src'; // Like a relative file
Instead of:
import syft from 'syft.js'; // Like an NPM package
After this small change, everything reloads as expected.
You can use npm link to create symbolic links between your React app and your local dependencies. Just make sure you build your local dependency to trigger reload in your React app.
Your local dependency should have a "main" and a "name" attributes in the package.json. webpack-dev-server will reload based on changes in your "main"
{
"name": "my-dep",
"main": "lib/index.js",
}
Run npm link next to the dependency package.json.
Run npm link my-dep in your React project - it will create a symbolic link between the two projects.
import myDep from 'my-dep in your React project. Reload will be triggered when you change lib/index.js
You can read more here https://medium.com/dailyjs/how-to-use-npm-link-7375b6219557
npm link: https://docs.npmjs.com/cli/link
I have a PHP project where I am using babeljs to convert all my javascript files to EcmaScript5. However, the files are so many and every time I edit a piece of code it takes too much time since it compiles whole folder files.
I tried to search but cannot find a proper solution.
I would like the BabelJs to compile only files which were modified after the last run.
p.s I have two folders for javascript files, es6 and js. A compiled file goes to js folder which is visible from the web and es6 is only for local use.
Here is my package.json
{
"name": "webplatform",
"version": "1.0.0",
"description": "Web Platform",
"scripts": {
"r8build": "babel htdocs/es6 -d htdocs/js"
},
"author": "harry",
"license": "MIT",
"devDependencies": {
"#babel/cli": "^7.4.3",
"#babel/core": "^7.4.3",
"#babel/preset-env": "^7.4.3",
"babel-preset-minify": "^0.5.0"
},
"dependencies": {}
}
And .babelrc
{
"presets": [
["#babel/preset-env"],
["minify", {
"builtIns": false
}]
],
"sourceType": "script"
}
I built an npm module named emeraldfw and published it. My package.json file is
{
"name": "emeraldfw",
"version": "0.6.0",
"bin": "./emeraldfw.js",
"description": "Emerald Framework is a language-agnostig web development framework, designed to make developer's lives easier and fun while coding.",
"main": "emeraldfw.js",
"directories": {
"example": "examples",
"test": "test"
},
"scripts": {
"test": "mocha"
},
"repository": {
"type": "git",
"url": "git+https://github.com/EdDeAlmeidaJr/emeraldfw.git"
},
"keywords": [
"web",
"development",
"framework",
"language",
"agnostic",
"react"
],
"author": "Ed de Almeida",
"license": "MIT",
"bugs": {
"url": "https://github.com/EdDeAlmeidaJr/emeraldfw/issues"
},
"homepage": "https://github.com/EdDeAlmeidaJr/emeraldfw#readme",
"devDependencies": {
"jshint": "^2.9.4",
"mocha": "^3.3.0"
},
"dependencies": {
"jsonfile": "^3.0.0",
"react": "^15.5.4",
"vorpal": "^1.12.0"
}
}
As you may see, I declared a "bin": "./emeraldfw.js" binary, which corresponds to the application itself. The package.json documentations says this is going to create a link to the application executable at node.js bin/ directory. This worked fine, but when I install it globally (npm install emeraldfw -g) and then run it from the command line I receive an error messsage
All other node modules are working fine and my application is passing in all tests and when I run it directly inside the development directory (with node emeraldfw.js) it works really fine.
I'm not a node.js expert and after having fought this error for two days, here I am to ask for help.
Any ideas?
EDIT:
I checked the permissions for my node binary (emeraldfw.js) and it belongs to edvaldo:edvaldo, my user and group. And it is with executable permissions set. I should have no permission issues inside my own area with these settings, don't you think?
Well, shebang issue here.
Before creating npm modules, you need read every single line of it's documentation.
As it stated here you need to use shebang to let your operating system know that it should run with node instead of operating system's own script execution hosts.
Please make sure that your file(s) referenced in bin starts with
#!/usr/bin/env node, otherwise the scripts are started without the node executable!
So, by using shebang on an npm module, you tell the os to create platform specific executables which let it use node to run the script. A .cmd file on Windows for example.
Have you try to install as su?