Trying to use Webpack to bundle and minify all the JS files to a bundle.min.js file, and all the CSS files into a bundle.min.css file.
Folder structure:
root
|- assets
|- src
|-- js
|--- *.js
|-- css
|--- *.css
Code:
const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
scripts: glob.sync('./src/js/*.js'),
styles: glob.sync('./src/css/*.css')
},
output: {
path: path.resolve(__dirname, 'assets'),
filename: '[name].bundle.min.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].bundle.min.css'
})
],
optimization: {
minimize: true,
minimizer: [new TerserPlugin()]
}
}
When I try to run npx webpack --config webpack.config.js
, I get the following error(s) for all the JS and CSS files:
ERROR in [...]
Module not found: Error: Can't resolve 'src\css\[...].css' in '[...]'
Did you mean './src\css\[...].css'?
Requests that should resolve in the current directory need to start with './'.
Requests that start with a name are treated as module requests and resolve within module directories (node_modules).
If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.
Kinda stuck at this point. Any suggestions is GREATLY appreciated. Thanks in advance.
The advice in the building errors message is clear.
Requests that should resolve in the current directory need to start with './'.
If the path doesn't start with './'
, it will parse the request as a module
Requests that start with a name are treated as module requests and resolve within module directories (node_modules).
Webpack will try to resolve the module within module directories (node_modules).
Project structure:
$ tree -L 3 -I node_modules
.
├── assets
│ ├── scripts.bundle.min.js
│ ├── styles.bundle.min.css
│ └── styles.bundle.min.js
├── package-lock.json
├── package.json
├── src
│ ├── css
│ │ ├── a.css
│ │ └── b.css
│ └── js
│ ├── a.js
│ └── b.js
└── webpack.config.js
Two solutions:
{ dotRelative: true }
option for glob.sync()
Prepend all relative path strings with ./ (or .\ on Windows).
E.g.
glob.sync('./src/js/*.js', { dotRelative: true })
// [ './src/js/b.js', './src/js/a.js' ]
webpack.config.js
:
const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production',
entry: {
scripts: glob.sync('./src/js/*.js', { dotRelative: true }),
styles: glob.sync('./src/css/*.css', { dotRelative: true }),
},
output: {
path: path.resolve(__dirname, 'assets'),
filename: '[name].bundle.min.js',
clean: true,
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [new MiniCssExtractPlugin({ filename: '[name].bundle.min.css' })],
};
resolve.preferRelative
configurationWhen enabled, webpack would prefer to resolve module requests as relative requests instead of using modules from
node_modules
directories.
This solution is also mentioned in the error:
If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.
webpack.config.js
:
const glob = require('glob');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production',
entry: {
scripts: glob.sync('./src/js/*.js'),
styles: glob.sync('./src/css/*.css'),
},
output: {
path: path.resolve(__dirname, 'assets'),
filename: '[name].bundle.min.js',
clean: true,
},
resolve: {
preferRelative: true,
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [new MiniCssExtractPlugin({ filename: '[name].bundle.min.css' })],
};
Build logs:
> webpack
asset styles.bundle.min.css 76 bytes [compared for emit] (name: styles)
asset scripts.bundle.min.js 34 bytes [compared for emit] [minimized] (name: scripts)
asset styles.bundle.min.js 0 bytes [compared for emit] [minimized] (name: styles)
Entrypoint scripts 34 bytes = scripts.bundle.min.js
Entrypoint styles 76 bytes = styles.bundle.min.css 76 bytes styles.bundle.min.js 0 bytes
orphan modules 3.23 KiB (javascript) 1.83 KiB (runtime) [orphan] 12 modules
cacheable modules 136 bytes (javascript) 74 bytes (css/mini-extract)
javascript modules 136 bytes
modules by path ./src/js/*.js 36 bytes
./src/js/b.js 18 bytes [built] [code generated]
./src/js/a.js 18 bytes [built] [code generated]
modules by path ./src/css/*.css 100 bytes
./src/css/b.css 50 bytes [built] [code generated]
./src/css/a.css 50 bytes [built] [code generated]
css modules 74 bytes
css ./node_modules/css-loader/dist/cjs.js!./src/css/b.css 37 bytes [built] [code generated]
css ./node_modules/css-loader/dist/cjs.js!./src/css/a.css 37 bytes [built] [code generated]
webpack 5.88.1 compiled successfully in 245 ms
package versions:
"css-loader": "^6.8.1",
"glob": "^10.3.1",
"mini-css-extract-plugin": "^2.7.6",
"webpack": "^5.80.0",
"webpack-cli": "^5.0.2"
Note: For better demonstration, I simplified the example, removed some loaders, plugins and configuration. Because they are not the cause of the problem.