如何从 html-webpack-plugin 生成中排除 link 标签(或更具体地说,由 mini-css-extract-plugin 提取的 .css 文件)?
How to exclude link tags (or more specifically .css files extracted by the mini-css-extract-plugin) from being generated by html-webpack-plugin?
由于(遗留)项目当前的设置方式,我无法以标准方式从 webpack 的缓存功能中受益,而是必须在空文件中生成脚本(如 main.html5 示例)并将它们包含在项目的头部或正文中。
这与我目前的配置工作得很好,但我发现自己缺乏引用 main.[hash].js 和 main.[hash].css 的能力,由 [=34= 提取]mini-css-extract-plugin
在单独的 ejs 文件中,以便我可以将每个生成的 html5 包含在我的 html5 模板的不同位置(link 标签在头部和脚本中正文)。
webpack.common.js :
module.exports = {
entry: {
main: path.resolve(__dirname, "./react/src/Index.js"),
styles: path.resolve(__dirname, "./react/src/Styles.js"),
vendor: path.resolve(__dirname, "./react/src/Vendor.js"),
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "[name].[contenthash].js",
assetModuleFilename: "images/[hash][ext][query]",
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/main.ejs"),
filename: "main.html5",
inject: false,
publicPath: "/dist/",
chunks: ["main"], // would be great to only reference .js here, then create another instance for .css
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
}),
],
main.ejs 只有 :
<%= htmlWebpackPlugin.tags.headTags %>
生成main.html5文件:
<script defer="" src="/dist/main.534ca9564003f8d93251.js"></script><link href="/dist/main.0864e3dfa0f6edc21e68.css" rel="stylesheet">
然后我将 main.html5 包含到我的项目模板中,如下所示:
<body>
// ---- html code goes here
<?php include_once 'dist/main.html5'; ?>
</body>
问题是这会在 body 标签的末尾加载两个标签,而我想在头部包含 css tags.So 理想情况下,我会有 2 html5 文件生成。一个包含 script 标签,另一个包含 link 标签。我已经阅读了 webpack 的文档,但没有看到任何适用于我的案例的可能解决方案。如果我可以从 ejs 文件中排除可能是解决方案的标签,但我无法在 HtmlWebpackPlugin
文档中找到任何相关信息。
所以,我发现了 html-webpack-exclude-assets-plugin
这正是我想要的,但不幸的是它没有工作并且大约 5 年没有更新。值得庆幸的是,html-webpack-skip-assets-plugin
有一个替代方案。这是我的使用方法:
webpack.common.js :
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackSkipAssetsPlugin =
require("html-webpack-skip-assets-plugin").HtmlWebpackSkipAssetsPlugin;
module.exports = {
entry: {
main: path.resolve(__dirname, "./react/src/Index.js"),
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "[name].[contenthash].js",
assetModuleFilename: "images/[hash][ext][query]",
},
optimization: {
minimizer: [`...`, new CssMinimizerPlugin()],
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/vendor.ejs"),
filename: "vendor.html5",
inject: false,
publicPath: "/dist/",
chunks: ["vendor"],
excludeAssets: [
/\/dist\/styles.*.css/,
(asset) => asset.attributes && asset.attributes["x-skip"],
],
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/styles.ejs"),
filename: "styles.html5",
inject: false,
publicPath: "/dist/",
chunks: ["main"],
// excludeAssets: [/\.css$/i]
excludeAssets: [
/\/dist\/main.*.js/,
(asset) => asset.attributes && asset.attributes["x-skip"],
],
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
}),
new HtmlWebpackSkipAssetsPlugin(),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.css$/i,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: "asset/resource", //* less performance heavy than asset/inline
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg)$/i,
type: "asset/inline", //* only for small assets. if webpack complains about asset size limit, change to asset/ressource type or asset. Had these as inline before (woff(2)?|eot|ttf|otf|svg),
},
],
},
好了,我们现在可以在自己的 html 文件中生成 css link 标签,并将其包含在我们项目的 .html 文件中任何需要的地方5 个模板。
由于(遗留)项目当前的设置方式,我无法以标准方式从 webpack 的缓存功能中受益,而是必须在空文件中生成脚本(如 main.html5 示例)并将它们包含在项目的头部或正文中。
这与我目前的配置工作得很好,但我发现自己缺乏引用 main.[hash].js 和 main.[hash].css 的能力,由 [=34= 提取]mini-css-extract-plugin
在单独的 ejs 文件中,以便我可以将每个生成的 html5 包含在我的 html5 模板的不同位置(link 标签在头部和脚本中正文)。
webpack.common.js :
module.exports = {
entry: {
main: path.resolve(__dirname, "./react/src/Index.js"),
styles: path.resolve(__dirname, "./react/src/Styles.js"),
vendor: path.resolve(__dirname, "./react/src/Vendor.js"),
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "[name].[contenthash].js",
assetModuleFilename: "images/[hash][ext][query]",
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/main.ejs"),
filename: "main.html5",
inject: false,
publicPath: "/dist/",
chunks: ["main"], // would be great to only reference .js here, then create another instance for .css
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
}),
],
main.ejs 只有 :
<%= htmlWebpackPlugin.tags.headTags %>
生成main.html5文件:
<script defer="" src="/dist/main.534ca9564003f8d93251.js"></script><link href="/dist/main.0864e3dfa0f6edc21e68.css" rel="stylesheet">
然后我将 main.html5 包含到我的项目模板中,如下所示:
<body>
// ---- html code goes here
<?php include_once 'dist/main.html5'; ?>
</body>
问题是这会在 body 标签的末尾加载两个标签,而我想在头部包含 css tags.So 理想情况下,我会有 2 html5 文件生成。一个包含 script 标签,另一个包含 link 标签。我已经阅读了 webpack 的文档,但没有看到任何适用于我的案例的可能解决方案。如果我可以从 ejs 文件中排除可能是解决方案的标签,但我无法在 HtmlWebpackPlugin
文档中找到任何相关信息。
所以,我发现了 html-webpack-exclude-assets-plugin
这正是我想要的,但不幸的是它没有工作并且大约 5 年没有更新。值得庆幸的是,html-webpack-skip-assets-plugin
有一个替代方案。这是我的使用方法:
webpack.common.js :
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackSkipAssetsPlugin =
require("html-webpack-skip-assets-plugin").HtmlWebpackSkipAssetsPlugin;
module.exports = {
entry: {
main: path.resolve(__dirname, "./react/src/Index.js"),
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "[name].[contenthash].js",
assetModuleFilename: "images/[hash][ext][query]",
},
optimization: {
minimizer: [`...`, new CssMinimizerPlugin()],
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/vendor.ejs"),
filename: "vendor.html5",
inject: false,
publicPath: "/dist/",
chunks: ["vendor"],
excludeAssets: [
/\/dist\/styles.*.css/,
(asset) => asset.attributes && asset.attributes["x-skip"],
],
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "./react/styles.ejs"),
filename: "styles.html5",
inject: false,
publicPath: "/dist/",
chunks: ["main"],
// excludeAssets: [/\.css$/i]
excludeAssets: [
/\/dist\/main.*.js/,
(asset) => asset.attributes && asset.attributes["x-skip"],
],
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
}),
new HtmlWebpackSkipAssetsPlugin(),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.css$/i,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: "asset/resource", //* less performance heavy than asset/inline
},
{
test: /\.(woff(2)?|eot|ttf|otf|svg)$/i,
type: "asset/inline", //* only for small assets. if webpack complains about asset size limit, change to asset/ressource type or asset. Had these as inline before (woff(2)?|eot|ttf|otf|svg),
},
],
},
好了,我们现在可以在自己的 html 文件中生成 css link 标签,并将其包含在我们项目的 .html 文件中任何需要的地方5 个模板。