美文网首页
如何获取Webpack打包出的文件Hash

如何获取Webpack打包出的文件Hash

作者: bysir | 来源:发表于2020-08-04 14:13 被阅读0次

需求

如果你使用 Vue/React脚手架搭建的项目, 你可能永远不需要这个步骤.

不过如果你需要手写webpack配置, 或者对webpack感兴趣, 也许你会疑惑: 添加了hash后的文件名每次打包都会变动, 如何将最新文件名写入到页面上?

答案是通过html-webpack-plugin插件将打包之后的文件名Inject到index.html中.

此逻辑仅仅需要配置几行代码

new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true,
    })

很简单, 所以我们一般不用花时间研究它.

不过我在一个项目中, index.html不再由前端定义, 而是由服务端渲染输出, 所以HtmlWebpackPlugin这套逻辑不再走得通.

现在 后端就需要知晓打包后的文件名, 才能正确输出文件名到index.html中.

方案

读取output文件夹中的文件名

这个方案最显而易见与简单, 不过它却有一些缺点:

output中文件有很多, 包括Entry和异步Chunk, 由于我们无法区分Entry和其他文件, 只能手动指定要引入的Entry文件, 代码会像这样:

<script :src="files[entry-a.js]"></script>
<script :src="files[entry-b.js]"></script>
<script :src="files[entry-c.js]"></script>

并不优雅, 我想要一个循环搞定

编写Webpack插件导出文件名

如果我们要区分Entry和其他文件, 那么就只能从Webpack入手, 由于Webpack太强大(复杂), 我们需要在网上找找资料, 搜索关键字: get webpack hash.

他们提到一个方案: 在插件中获取需要的文件名, 输入为一个清单文件.

有了这个清单文件, 后端就能读取它并注入到index.html中了.

不过它们提供的代码太简陋, 不能用于生产, 故继续查找资料来编写我所需要的插件:

同时在html-webpack-plugin插件有相同功能: 将打包好的文件inject到index.html中. 所以也去翻了翻它的源码.

最后搬运过来的代码就是这样:

class DumpAssetsPlugin {
  /*
  options: {
    filename: 'dist/access.json', // default: outputPath + "/assets.json"
  }
  */
  constructor(options) {
    options = options || {}
    this.options = {
      filename: options.filename || null,
    };
  }

  apply(compiler) {
    compiler.hooks.afterEmit.tap("ExportAssets", (compilation) => {
      // see https://webpack.js.org/api/stats/
      let stats = compilation.getStats().toJson();

      let entrypoints = compilation.entrypoints;
      let entryNames = Array.from(entrypoints.keys());

      let files = []
      for (let i = 0; i < entryNames.length; i++) {
        const entryName = entryNames[i];
        const entryFiles = entrypoints.get(entryName).getFiles();
        files.push(...entryFiles)
      }

      function unique(arr) {
        return arr.filter(function (item, index, arr) {
          return arr.indexOf(item, 0) === index;
        });
      }

      files = unique(files)

      let assets = {
        js: [],
        css: [],
        uncase: [] // 意料之外的文件
      }

      files.forEach(f => {
        const sp = f.split('.')
        const ext = sp[sp.length - 1]
        if (assets[ext]) {
          assets[ext].push(f)
        } else {
          console.warn('uncased file ext:', f)
          assets.uncase.push(f)
        }
      })

      let filename = this.options.filename
      if (!filename) {
        filename = stats.outputPath + "/assets.json"
      }

      require("fs").writeFileSync(
        filename,
        JSON.stringify(assets)
      );
    });
  }
}

或者, 你也可以使用我上传到NPM的包: dump-assets-webpack-plugin

使用方法如下:

module.exports = {
  entry: {
    index: ['./src/index.js'],
  },
  output: {
    path: __dirname + '/dist',
    filename: 'js/[name].[chunkHash:8].js'
  }
  ...

  plugins: [
    ...
    new DumpAssetsPlugin()
  ]
}

相关文章

  • 如何获取Webpack打包出的文件Hash

    需求 如果你使用 Vue/React脚手架搭建的项目, 你可能永远不需要这个步骤. 不过如果你需要手写webpac...

  • 清除缓存

    【微信浏览器缓存】 参考文档 【webpack打包文件添加hash】 参考文档

  • webpack的配置

    一、webpack(简化打包代码) 之前打包的命令需要指打包的文件和导报后的文件 如何简化命令,让webpack自...

  • webpack(七) 动态打包多入口文件

    webpack如何打包多入口文件webpack打包文件主要是靠entry中配置对象,对象的key有几个,那么对象的...

  • 处理index.html缓存问题

    前端使用webpack打包后 文件名是可以配置加入hash值,来保证每次打包后的文件名不一样,有效的应对部署新版...

  • webpack优化提升构建速度

    Webpack 的最简单的配置如下: 这样的配置会将我们的文件打包成为一个 app.[hash].js 文件。这样...

  • [插件1] html-webpack-plugin

    这个插件用于简化HTML文件的创建,服务于webpack bundles.这对文件名使用hash的打包特别有用。可...

  • 缓存

    webpack中可采用hash值打包阻止缓存策略

  • vue-cli3配置webpack-bundle-analyze

    webpack-bundle-analyzer的作用是可以直观分析打包出的文件包含哪些,大小占比如何,模块包含关系...

  • webpack打包Js文件

    1.如何通过webpack打包js文件 1.安装webpack 2.在终端输入打包命令 a .注意点:index....

网友评论

      本文标题:如何获取Webpack打包出的文件Hash

      本文链接:https://www.haomeiwen.com/subject/uighrktx.html