3

如何获取 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>每次更新/重新生成代码时我都必须更改它

我可以使用filename: '[name].bundle.js'chunkhash但它不适合缓存 porpouses。

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

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

4

1 回答 1

1

好的,我找到了方法。

我使用了下面的插件,因为它让我可以使用我的 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的被解析,所有的 csslink标签和 script 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>

希望它可以帮助别人!

于 2019-08-25T03:21:47.153 回答