简要说明:我遇到了意外的输出/问题时,在使用MiniCssExtractPlugin和一些加载器提供给HtmlWebpackPlugin沿着的.html模板中的<link>
标记内引用的.css文件。
目录结构:
| package.json
| webpack.prod.js
| src
| css
| main.css
| another.css
| ...
| images
| image1.png
...
| scripts
| script1.js
| script2.js
| templates
| file1.html
| file2.html
...
| ...
字符串
上面显示的目录结构的文件内容:script1.js
包含对script2.js
的引用,但没有对css文件的引用。.css文件仅使用./src/template
s文件夹中包含的.html文件中的<link>
标记引用。
webpack.prod.js内容:
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const htmlTemplates = fs.readdirSync(path.resolve(__dirname, 'src/templates')).filter(file => /\.html$/i.test(file));
module.exports = {
mode: "production",
entry: {
index: "./src/scripts/script1.js",
},
output: {
filename: 'static/[name]-[contenthash].bundle.js',
path: path.resolve(__dirname, 'build'),
publicPath: '/',
assetModuleFilename: "static/[name]-markedByAssetModuleFilename-[contenthash].bundle[ext]",
clean: true,
},
optimization: {
minimizer: [
new CssMinimizerPlugin(),
new TerserPlugin({
extractComments: false, //omit the creation of a separate LICENSE file
terserOptions: {
format: {
comments: false, //remove the comments from the bundled output
},
}
}),
],
},
plugins: [
...htmlTemplates.map((file) => {
return new HtmlWebpackPlugin({
template: `./src/templates/${file}`,
filename: `htmlFiles/${file.replace(/\.html$/, '.bundle.html')}`,
inject: 'head',
scriptLoading: 'module',
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
minifyJS: true,
minifyCSS: true
}
});
}),
new MiniCssExtractPlugin({
filename: 'static/[name]-[contenthash].bundle.css',
}),
],
module: {
rules: [
{
test: /\.js$/i,
exclude: [/node_modules/],
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
{
test: /\.html$/i,
use: ["html-loader"]
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: "asset/resource",
},
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
],
}
],
},
};
型
package.json
"devDependencies": {
"@babel/preset-env": "^7.23.6",
"babel-loader": "^9.1.3",
"css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1",
"html-loader": "^4.2.0",
"html-webpack-plugin": "^5.6.0",
"mini-css-extract-plugin": "^2.7.6",
"terser-webpack-plugin": "^5.3.10",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
...
...
}
型
我期望的输出:
当我运行webpack --config webpack.prod.js
我应该得到./build/htmlFiles
文件夹包含所有“处理”的html文件.这些html文件应该有脚本标签捆绑script1.js和应该有链接标签指向被处理的css文件.处理的css文件应该根据指定的文件名为MiniCssExtractPlugin而不是每output.assetModuleFilename
命名. css文件不应该为空.
我得到的输出:./build/htmlFiles
文件夹中的.html文件有指向./build
文件夹中输出的css文件和脚本的链接标签和脚本标签。到目前为止一切顺利。
我发现在./build/static
文件夹中.css文件都是根据ouput.assetModuleFilename
下指定的名称命名的。所有.css文件也是空的,看起来像这样:
// extracted by mini-css-extract-plugin
export {};
型
我发现,如果我修改module.rules
,使其具有include
属性,如下图所示,并指向一个不存在的文件,那么./build/static
中的所有.css文件都有css内容,但不再说// extracted by mini-css-extract-plugin
。它们仍然根据output.assetModuleFilename
命名。如果include
确实指向存在的实际文件,则./build/static
中的文件将不包含css内容,并且将为空。.build/static
将有内容然后.我不明白这是怎么回事.
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader, //2. Extract css into files
'css-loader' //1. Turns css into commonjs
],
include: path.resolve(__dirname, './src/css/nonExistentFile.css'),
}
型
如何获得预期的输出?我想使用html模板中的所有css,使用指向build目录中已处理的.css文件的<link>
标记。我不想在共享的script1.js文件中使用css导入语句。每个.html模板文件使用<link>
标记指向自己的.css文件。
我已经试着阅读文档的最后2天,但不能弄清楚webpack刚刚。这是我第一次使用webpack。
1条答案
按热度按时间mo49yndu1#
可以使用html-bundler-webpack-plugin。
这个插件允许在HTML标签中直接使用JS和CSS/SCSS源文件。
模板中的所有源文件路径都将被解析,并在捆绑输出中自动替换为正确的URL。解析后的资源将通过Webpack插件/加载器进行处理,并放置到输出目录中。
例如,有HTML模板包含对SCSS,JS和图像的引用:
字符串
生成的HTML包含输出文件名:
型
简单的Webpack配置:
型
备注
使用HTML模板器插件,HTML模板是入口点,而不是JS。您不再需要在Webpack入口中定义SCSS和JS文件。
HTML插件取代了html-webpack-plugin和mini-css-extract-plugin的功能。