webpack splitChunks: how do I merge dependencies into a named chunk? - javascript

Suppose you have a project below:
package.json
{
"name": "webpack-test-repo",
"main": "index.js",
"dependencies": {
"define-properties": "^1.1.3"
},
"devDependencies": {
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2"
}
}
index.js
// dynamically load the 'define-properties' module.
import('define-properties');
webpack.config.js
module.exports = {
mode: 'production',
entry: './index.js',
output: {
chunkFilename: '[name].js',
},
optimization: {
splitChunks: {
minSize: 0, // <- just to demonstrate the situation with small packages
cacheGroups: {
defineProperties: {
test: /node_modules\/define-properties\//,
name: 'define-properties',
},
},
},
},
};
Note that the imported module define-properties has a single dependency object-keys.
I configured splitChunks in webpack.config.js so that contents of define-properties are split into define-properties.js.
The result of running webpack is as follows:
$ npx webpack
Hash: 7d9500fb0e6bfd1e32d1
Version: webpack 4.20.2
Time: 127ms
Built at: 2018-10-08 03:25:47
Asset Size Chunks Chunk Names
main.js 2.05 KiB 0 [emitted] main
define-properties.js 754 bytes 1 [emitted] define-properties
2.js 2.08 KiB 2 [emitted]
Entrypoint main = main.js
[0] ./index.js 81 bytes {0} [built]
+ 3 hidden modules
Here we get three output files: main.js for the content of index.js, define-properties.js for the define-properties module, and 2.js for the object-keys module.
Question:
I want the chunk for object-keys to be merged into define-properties because it is only used by define-properties.
In other words, I want to pack define-properties and its dependencies into one named chunk by only specifying the parent module.
Although test: /node_modules\/(?:define-properties|object-keys)\// works for this example, I don't want to list all (potentially many) dependencies of define-properties.
How do I configure webpack to achieve it?

Related

Webpack 5 doesn't update the bundle.js

I'm trying to create a boilerplate with Webpack 5 and React to understand the details all of the elements. And it seems like everything works properly except the updating bundle.js in memory.
When I run the 'webpack serve' command the server starts, then I modify script, page is reloaded but there are no changes.
I have next statement in config files
package.json:
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack serve",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"#babel/core": "^7.16.0",
"#babel/preset-env": "^7.16.4",
"#babel/preset-react": "^7.16.0",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"dotenv-webpack": "^7.0.3",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.64.1",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.5.0"
}
}
webpack.config.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const DotenvWebpackPlugin = require('dotenv-webpack');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'index.bundle.js',
},
devServer: {
static: {
directory: path.join(__dirname, 'src'),
},
port: 8080,
open: true,
hot: true,
liveReload: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /nodeModules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new DotenvWebpackPlugin({
path: '.env'
})
],
stats: {
errorDetails: true,
},
}
Logs:
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.0.106:8080/
<i> [webpack-dev-server] Content not from webpack is served from 'D:\Projects\boilerplates\react-app\src' directory
<i> [webpack-dev-middleware] wait until bundle finished: /
[BABEL] Note: The code generator has deoptimised the styling of D:\Projects\boilerplates\react-app\node_modules\react-dom\cjs\react-dom.development.js as it exceeds the max of 500KB.
asset index.bundle.js 4.06 MiB [emitted] (name: main)
asset index.html 287 bytes [emitted]
runtime modules 27.1 KiB 13 modules
modules by path ./node_modules/ 1.06 MiB 45 modules
modules by path ./src/ 3.29 KiB
modules by path ./src/*.js 477 bytes
./src/index.js 200 bytes [built] [code generated]
./src/App.js 277 bytes [built] [code generated]
modules by path ./src/*.css 2.83 KiB
./src/app.css 2.24 KiB [built] [code generated]
./node_modules/css-loader/dist/cjs.js!./src/app.css 601 bytes [built] [code generated]
webpack 5.64.1 compiled successfully in 3107 ms
assets by path *.js 4.06 MiB
asset index.bundle.js 4.06 MiB [emitted] (name: main)
asset main.c161a0c51f50fe5a9631.hot-update.js 676 bytes [emitted] [immutable] [hmr] (name: main)
asset index.html 287 bytes [emitted]
asset main.c161a0c51f50fe5a9631.hot-update.json 28 bytes [emitted] [immutable] [hmr]
Entrypoint main 4.06 MiB = index.bundle.js 4.06 MiB main.c161a0c51f50fe5a9631.hot-update.js 676 bytes
cached modules 1.07 MiB [cached] 48 modules
runtime modules 27.1 KiB 13 modules
./src/App.js 277 bytes [built]
webpack 5.64.1 compiled successfully in 118 ms
assets by status 4.06 MiB [cached] 1 asset
asset index.html 287 bytes [emitted]
cached modules 1.07 MiB (javascript) 27.1 KiB (runtime) [cached] 62 modules
webpack 5.64.1 compiled successfully in 15 ms
<i> [webpack-dev-middleware] wait until bundle finished: /
assets by status 4.06 MiB [cached] 1 asset
asset index.html 287 bytes [emitted]
cached modules 1.07 MiB (javascript) 27.1 KiB (runtime) [cached] 62 modules
webpack 5.64.1 compiled successfully in 16 ms
You can check the boilerplate here in repo
So, page is reloaded successfully but there are no changes. What the problem can be there?
UPDATE 1:
I'm updating jsx inside of this script for anything else - src/app.js
import React from "react";
function App() {
return (<div>
<h2>Welcome to React App</h2>
<h3>Date : {new Date().toDateString()}</h3>
</div>)
}
export default App
But the changes are visible only after restarting webpack dev server.
To reproduce the problem you can easily clone the repo and run this script in react-app directory:
npm i
npm start
I found the problem.
index.js had:
import App from "./App"
but correct one is:
import App from "./app"
Strange thing. It's like there should be an error instead of silence.

Webpack 5 multiple javascript files produces 0 bytes bundle in production mode

I just need to minify and bundle all my js files into one file. So prepared a simple configuration as;
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'production',
resolve: {
extensions: ['.js']
},
entry: [
'./src/main/resources/static/js/app/context.js',
'./src/main/resources/static/js/app/pagemanager.js'
],
plugins: [
new CleanWebpackPlugin()
],
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
filename: 'bundle.js'
}
};
but if I execute webpack --mode production it produces 0 bytes and bundle.js is empty
asset bundle.js 0 bytes [emitted] [minimized] (name: main)
./src/main/resources/static/js/app/context.js 9.74 KiB [built] [code generated]
./src/main/resources/static/js/app/pagemanager.js 27.9 KiB [built] [code generated]
webpack 5.20.2 compiled successfully in 299 ms
but with webpack --mode development it creates a file that contains js code.
What may be the reason leading to this? Thank you.
I think that if your file don't have any code to execute, such as
// just define a var
const foo = 1;
// or just a string
"console.log('something');"
and the webpack mode is "production"(if you don't set it, the default value is this),the result will be empty, asset main.js 0 bytes.
The solution is changing the code to this.
console.log('something');
Answering my question for those who is facing the same problem,
There should be "export" syntax, that refers what you export from these js files to solve this problem.

Why does webpack build global.js?

I'm getting started with webpack, and on my first build I noticed that the output included a default file was included (index 1):
build.js 222 kB 0 [emitted] main
[1] (webpack)/buildin/global.js 509 bytes {0} [built]
[2] ./source/scripts/main.js 105 bytes {0} [built]
+ 4 hidden modules
Why is this file being included? I don't have any dependencies that would require anything close to the amount of code that comes out in my build.js file. I was expecting to have maybe 10 lines of code in the output, instead I have 8000.
I've also noticed some other projects out there don't have this file listed in the output. Is this strictly necessary? I can't even find it in the docs.
For reference, my webpack.config.js file:
'use strict';
module.exports = {
entry: './source/scripts/main.js',
output: {
path: __dirname + '/dist',
filename: 'build.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/
}
]
}
}
I had the same issue. It turned out that I was importing something from node_modules accidentally.
In typescript:
import Util from 'Util';
should have been
import Util from './Util';
since the first one loaded a 'Util' from node modules instead of my local file. The 'exclude: /node_modules/' doesn't seem to matter. I had the equivalent in my tsconfig. Maybe webpack should warn if you import something that's excluded.

Module not found: Error: Can't resolve 'webpack'

I am trying to generate bundle.js using all javascript which I have. Here is command which I used.
> C:\Users\aaa\node_modules\.bin>"C:\Users\aaa\node_modules\.bin\webpack.cmd" "D:\www\webpack.config.js" "D:\www\bundle.js"
bundle.js got generate but build failing. Here is error.
C:\Users\aaa\node_modules\.bin>C:\Users\aa\node_modules\.bin\webpack.cmd D:\www\webpack.config.js D:\www\bundle.js
Hash: 44eb203978bf482447b4
Version: webpack 2.2.1
Time: 94ms
Asset Size Chunks Chunk Names
bundle.js 15 kB 0 [emitted] main
[0] ../webpack/~/node-libs-browser/~/path-browserify/index.js 6.18 kB {0} [bu
ilt]
[1] ../webpack/~/node-libs-browser/~/process/browser.js 5.3 kB {0} [built]
[2] D:/www/webpack.config.js 567 bytes {0} [built]
ERROR in D:/www/webpack.config.js
Module not found: Error: Can't resolve 'webpack' in 'D:\www'
# D:/www/webpack.config.js 2:16-34
Here is my webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
context: path.resolve("www", './src'),
entry: {
app: ['js/index.js', './js/require.js', './js/google-protobuf.js', './js/proto/ByteBufferAB.min.js',
'./js/proto/Long.min.js', './js/proto/control_1.js', './js/proto/data_1.js', './js/proto/data_hmi_1.js',
'./js/proto/main_1.js'],
},
output: {
path: path.resolve("www", './dist'),
filename: 'bundle.js',
}
};
Please give any reference or hint.
Try to change your context and output.path:
context: path.resolve(__dirname, './'),
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js',
publicPath: '/'
},
Then __dirname will be replaced by your physical path where your files are.
Please check if you have webpack installed globally.
Command to check : webpack -v
Also you should execute webpack build command : webpack --config webpack.config.js --progress --colors.
Please note command should be executed in the same directory where webpack.config.js is present.
Your using local webpack as per your current command.

Using webpack-dev-server and Hot Module Replacement not updating bundle.js with changes to JS or SCSS files

I am using an npm script npm start to run webpack-dev-server --progress --colors --hot --inline --open in the Terminal. My React app loads up fine on the local server. But when I make any SCSS changes for example I see:
webpack: bundle is now INVALID.
Hash: 619812c0fa6ffc42708e
Version: webpack 1.13.3
Time: 343ms
Asset Size Chunks Chunk Names
bundle.js 1.02 MB 0 [emitted] main
0.065f433e5a1a691720c9.hot-update.js 659 bytes 0 [emitted] main
065f433e5a1a691720c9.hot-update.json 36 bytes [emitted]
chunk {0} bundle.js, 0.065f433e5a1a691720c9.hot-update.js (main) 946 kB [rendered]
[249] ./~/css-loader?sourceMap!./~/sass-loader?sourceMap!./src/styles/main.scss 586 bytes {0} [built]
+ 251 hidden modules
webpack: bundle is now VALID.
However, the page doesn't reflect any SCSS or JS changes I make. My bundle.js is not updated at all. However, if i run webpack in another Terminal window my bundle.js updates and then if I refresh my page I can see my changes.
Here is my webpack.config.js:
var webpack = require("webpack");
module.exports = {
entry: "./src/main.js",
output: {
path: "./build/scripts",
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.jsx?$/,
loader: "babel",
exclude: "./node_modules"
},
{ test: /\.scss$/,
loaders: [ "style", "css?sourceMap", "sass?sourceMap" ]
}
],
}
};
Here is my main.js file:
import React from "react";
import ReactDOM from "react-dom";
// CSS
import "./styles/main.scss"
let docBody = "Webpack is doing its thing, with ES2015!!";
document.write(docBody);
Any idea what I'm doing wrong here?

Categories

Resources