Bundle and minify multiple JS and CSS files with webpack – ERROR Module not found

huangapple go评论81阅读模式
英文:

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 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' })],
};

> 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.

huangapple
  • 本文由 发表于 2023年6月30日 02:26:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定