针对js文件减少工夫戳,防止文件缓存未更新

01 webpack.config.ts

import * as path from 'path';import * as webpack from 'webpack';import HelloWorld from './src/plugins/HelloWorld'; const HtmlWebpackPlugin = require('html-webpack-plugin');const config: webpack.Configuration = {    entry: './src/index.ts',    mode: 'development',    module: {        rules: [            {                test: /\.(ts|tsx)$/,                use: 'ts-loader',                exclude: /node_modules/,            }        ]    },    resolve: {        extensions: ['ts', 'js', 'tsx'],        modules: ['node_modules'],    },    output: {        filename: 'bundle.js',        path: path.resolve(__dirname, 'dist'),    },    plugins: [        new HelloWorld(),        new HtmlWebpackPlugin(),    ]}export default config;

02 tsconfig.json

{    "compilerOptions": {        "outDir": "./dist/",        "noImplicitAny": true,         "target": "es5",        "jsx": "react",        "allowJs": true,    }}

03 src/plugins/HelloWorld.ts

  • 应用插件的自定义钩子的形式产生了变动:
    compilation.plugin['xxx'] -> HtmlWebpackPlugin.getHooks(compilation)
  • alterAssetTagGroups 将行将插入html的脚本进行分组后触发的钩子
  • 寻找特定的文件:(i.attributes?.src as string)?.indexOf('bundle.js') > -1
  • 从新批改文件src:i.attributes.src = ${i.attributes.src}?${(new Date().valueOf())};
import { Compiler } from "webpack";import * as HtmlWebpackPlugin from 'html-webpack-plugin';export default class HelloWorld {    static defaultOptions = {        outputFile: 'assets.md',    }    name = "HelloWorld";    options: any;    constructor(options: any = {}) {        this.options = {            ...HelloWorld.defaultOptions,            ...options,        }    }    apply(compiler: Compiler) {        const pluginName = HelloWorld.name;        const { webpack } = compiler;        const { Compilation } = webpack;        const { RawSource } = webpack.sources;        compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {            compilation.hooks.processAssets.tap({                name: pluginName,                stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,            }, (assets) => {                const content = "# In this build: \n \n" +                    Object.keys(assets)                        .map(filename => `- ${filename}`)                        .join('\n');                compilation.emitAsset(                    this.options.outputFile,                    new RawSource(content)                )            });        })        compiler.hooks.compilation.tap(pluginName, (compilation) => {            HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tap(HelloWorld.name, (config) => {                // console.log(config.headTags.forEach(i => console.log(i)));                config.headTags.forEach(i => {                    console.log((i.attributes?.src as string)?.indexOf('bundle.js') > -1);                    if (i.tagName === 'script' && (i.attributes?.src as string)?.indexOf('bundle.js') > -1) {                        i.attributes.src = `${i.attributes.src}?${(new Date().valueOf())}`;                    }                })                return config;            })        })    }}