如何自动获取 webpack4 chunkhash 值以在 html 内的脚本 src 中使用?

How to get webpack4 chunkhash value to use in script src inside the html automatically?

如何获取 webpack4 生成的 chunkhash 值,以便我可以在 index.html 中使用它来正确设置脚本 src?

简要背景:希望这不是一个愚蠢的问题,因为我是 webpack 的新手,今天才开始学习。我知道如何配置、提取 js、css、缩小它们,也许还有所有非常基本的操作。

这是我的 webpack.config.js:

const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptmizerCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve('dist'),
        filename: '[chunkhash].bundle.js' // <<<<<<
    },

    mode: 'development',

    optimization: {
        minimizer: [
            new TerserPlugin({}),
            new OptmizerCssAssetsPlugin({})
        ],
        splitChunks: {
            chunks: 'all'
        }
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    'css-loader'
                ]
            }
        ]
    },

    plugins: [
        new webpack.ProvidePlugin({
            cowsay: 'cowsay-browser'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ]
}

相关部分在 filename: '[chunkhash].bundle.js' 中,它将生成类似 6f9e5dd33686783a5ff8.bundle.js 的文件名。

我可以在我的 html 中使用该名称,例如 <script src="dist/6f9e5dd33686783a5ff8.bundle.js"></script>,但是 每次代码为 updated/regenerated 时我都必须更改它。

我可以使用 filename: '[name].bundle.js' 而不是 chunkhash,但它不适合缓存海豚。

那么,有什么方法可以获取 chunkhash 值并在我每次构建项目时使用它自动设置我的 index.html 中的脚本 src 文件名?

任何有效的建议都将受到欢迎!

好的,我找到办法了。

我使用了下面的插件,因为它让我可以使用我的 html 作为模板文件。我只需要删除 linkscript 标签,然后让它将它们插入到它将生成的最终 html 中。

我是这样做的:

1 - 安装 html-webpack-plugin

npm i -D html-webpack-plugin

2 - 将我的 /index.html 移动为 /src/main.html

因为我的配置会生成一个名为 index.html 的文件。将模板重命名为 main.html 避免可能的混淆

3 - 将其添加到 webpack.config.js

的插件部分
// ... other imports here ... //

const HtmlPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve('dist'),
        filename: '[chunkhash].bundle.js' // **** using chunkhash
    },

    mode: 'development',

    optimization: {
        minimizer: [
            new TerserPlugin({}),
            new OptmizerCssAssetsPlugin({})
        ],
        splitChunks: {
            chunks: 'all' // **** config the WebPack SplitChunksPlugin
        }
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    'css-loader'
                ]
            }
        ]
    },

    plugins: [
        new webpack.ProvidePlugin({
            cowsay: 'cowsay-browser'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[contenthash].css' // **** using contenthash
        }),

// **** new config: 
        new HtmlPlugin({
            filename: 'index.html',
            template: path.resolve('src', 'main.html')
        })
    ]
}

4 - 就是这样!

现在,当我构建我的项目时,我的 /src/main.html 被解析,所有 css link 标签和脚本 js 标签被自动插入到一个新的 /dist/index.html 文件中(见下文):

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Vacapack</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- LOOK THIS: //-->
    <link href="css/7358f9abc5c8cea68707.css" rel="stylesheet"></head>
    <body>
        <pre id="caixa"></pre>
    <!-- AND THESE: //-->
    <script type="text/javascript" src="b6183f7997b49195d1f8.bundle.js"></script>
    <script type="text/javascript" src="0e374d6ca9b34e89e18f.bundle.js"></script></body>
</html>

希望对其他人有所帮助!