英文:
Bundle and minify multiple JS and CSS files with webpack - ERROR Module not found
问题
尝试使用Webpack将所有JS文件捆绑和缩小为bundle.min.js文件,将所有CSS文件捆绑为bundle.min.css文件。
文件夹结构:
root
|- assets
|- src
|-- js
|--- *.js
|-- css
|--- *.css
代码:
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()]
}
}
尝试运行npx webpack --config webpack.config.js
时,我得到了以下错误信息,适用于所有JS和CSS文件:
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.
目前有点困惑。非常感谢您提前的任何建议。
英文:
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.
答案1
得分: 1
建筑错误消息中的建议很明确。
> 应该在当前目录中解析的请求需要以'./'开头。
如果路径不以'./'开头,它将解析请求为模块
> 以名称开头的请求被视为模块请求,并在模块目录(node_modules)中解析。
Webpack将尝试在模块目录(node_modules)中解析模块。
项目结构:
$ 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
两种解决方案:
- 对于
glob.sync()
使用{ dotRelative: true }
选项
> 在所有相对路径字符串之前添加'./'(或在Windows上添加' .')。
例如:
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' })],
};
> 当启用时,Webpack会更愿意将模块请求解析为相对请求,而不是使用node_modules
目录中的模块。
此解决方案也在错误中提到:
> 如果更改源代码不是一个选项,还有一个名为'preferRelative'的解析选项,它也会尝试在当前目录中解析这种类型的请求。
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' })],
};
构建日志:
> 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
软件包版本:
"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"
注意:为了更好地演示,我简化了示例,删除了一些加载器、插件和配置。因为它们不是问题的原因。
英文:
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:
- Use
{ dotRelative: true }
option forglob.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' })],
};
- Use
resolve.preferRelative
configuration
> When 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论