Skip to content

ScriptExtHtmlWebpackPlugin是干啥用的? #97

Open
@dcharlie123

Description

@dcharlie123

今天重新搭建项目时,看到后台系统vue.config.js中有这样一段代码,不知道是干什么用的,于是搜索一下了解

chainWebpack (config) {
    config.when(nodeEnv !== 'development', config => {
      config
        .plugin('ScriptExtHtmlWebpackPlugin')
        .after('html')
        .use('script-ext-html-webpack-plugin', [
          {
            // `runtime` must same as runtimeChunk name. default is `runtime`
            inline: /runtime\..*\.js$/
          }
        ])
        .end()
    })
    config.optimization.runtimeChunk('single')
  }

ScriptExtHtmlWebpackPlugin

ScriptExtHtmlWebpackPlugin是webpack插件,用于在html文件中添加脚本

上面的代码是什么作用呢?

优化持久化缓存的, runtime 指的是 webpack 的运行环境(具体作用就是模块解析, 加载) 和 模块信息清单,

模块信息清单在每次有模块变更(hash 变更)时都会变更, 所以我们想把这部分代码单独打包出来, 配合后端缓存策略, 这样就不会因为某个模块的变更导致包含模块信息的模块(通常会被包含在最后一个 bundle 中)缓存失效.

optimization.runtimeChunk 就是告诉 webpack 是否要把这部分单独打包出来.

何为运行时代码?
形如import('abc').then(res=>{})这种异步加载的代码,在webpack中即为运行时代码。

设置runtimeChunk是将包含chunks 映射关系的 list单独从 app.js里提取出来,因为每一个 chunk 的 id 基本都是基于内容 hash 出来的,所以每次改动都会影响它,如果不将它提取出来的话,等于app.js每次都会改变。缓存就失效了。设置runtimeChunk之后,webpack就会生成一个个runtime~xxx.js的文件。
然后每次更改所谓的运行时代码文件时,打包构建时app.js的hash值是不会改变的。如果每次项目更新都会更改app.js的hash值,那么用户端浏览器每次都需要重新加载变化的app.js,如果项目大切优化分包没做好的话会导致第一次加载很耗时,导致用户体验变差。
现在设置了runtimeChunk,就解决了这样的问题。所以这样做的目的是避免文件的频繁变更导致浏览器缓存失效,所以其是更好的利用缓存。提升用户体验。
runtimeChunk作用是为了线上更新版本时,充分利用浏览器缓存,使用户感知的影响到最低。

runtimeChunk

之所以把 runtimeChunk 单独拿出来说一下,是因为它真的很重要,但是大部分人都会用错。
runtimeChunk 可以理解为 webpack 为运行时提供的一些封装,比如要支持异步按需加载需要引入 webpack_require.e、webpack_require.p 等函数,要支持HMR、WASM、Web Worker等功能也需要引入对应的封装,这些封装就是 runtimeChunk,也可以叫做 webpack 运行时代码,把这些代码单独打包有以下好处:

  • 长期缓存:将运行时代码与业务代码分离,可以确保在业务代码发生变化时,运行时代码的 hash 值不会改变。这意味着浏览器可以缓存运行时代码,而只需下载业务代码的更新部分,从而减少用户加载页面的时间和带宽消耗。
  • 提升构建速度:由于运行时代码相对稳定,将其单独拆分出来后,可以避免在每次构建时都重新生成和打包运行时代码。这样可以提升构建的速度
  • 代码复用:将运行时代码单独拆分出来,可以在多个入口文件中共享同一份运行时代码。这样可以避免在每个入口文件中重复包含运行时代码,减小打包文件的体积。

所以结论就是,运行时代码通常不会经常变化,并且可以被多个模块共享。通过optimization.runtimeChunk将运行时代码从模块中分离出来,可以减小每个模块的体积,并且在浏览器缓存中保持稳定。runtimeChunk:'single'指示webpack将运行时代码提取到一个单独的文件中,但会增加额外的HTTP请求,浏览器每次都需要重新请求它,它的 http 耗时远大于它的执行时间,所以使用ScriptExtHtmlWebpackPlugin将它内联到index.html中

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions