深入理解 webpack 文件打包机制(小结)(3)

  • pageB 中 utilC 不是页面一开始加载时候就需要的内容,假如 utilC 很大,我们不希望页面加载时就直接加载 utilC,而是当用户达到某种条件(如:点击按钮)才去异步加载 utilC,这时候我们需要将 utilC 抽离成单独文件,当用户需要的时候再去加载该文件。
  • 那么 webpack 需要怎么配置呢?

    // 通过 config/webpack.config.multiple.js 打包
    const webpack = require('webpack');
    const path = require('path')
    
    module.exports = {
     entry: {
     pageA: [path.resolve(__dirname, '../src/multiple/pageA.js')],
     pageB: path.resolve(__dirname, '../src/multiple/pageB.js'),
     },
     output: {
     path: path.resolve(__dirname, '../dist'),
     filename: '[name].[chunkhash:8].js',
     },
     plugins: [
     new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: 2,
     }),
     new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
     })
     ]
    }
    
    

    单单配置多 entry 是不够的,这样只会生成两个 bundle 文件,将 pageA 和 pageB 所需要的内容全部放入,跟单入口文件并没有区别,要做到代码切割,我们需要借助 webpack 内置的插件 CommonsChunkPlugin。

    首先 webpack 执行存在一部分运行时代码,即一部分初始化的工作,就像之前单文件中的 __webpack_require__ ,这部分代码需要加载于所有文件之前,相当于初始化工作,少了这部分初始化代码,后面加载过来的代码就无法识别并工作了。

    new webpack.optimize.CommonsChunkPlugin({
     name: 'vendor',
     minChunks: 2,
    })
    

    这段代码的含义是,在这些入口文件中,找到那些引用两次的模块(如:utilB),帮我抽离成一个叫 vendor 文件,此时那部分初始化工作的代码会被抽离到 vendor 文件中。

    new webpack.optimize.CommonsChunkPlugin({
     name: 'manifest',
     chunks: ['vendor'],
     // minChunks: Infinity // 可写可不写
    })

    这段代码的含义是在 vendor 文件中帮我把初始化代码抽离到 mainifest 文件中,此时 vendor 文件中就只剩下 utilB 这个模块了。你可能会好奇为什么要这么做?

    因为这样可以给 vendor 生成稳定的 hash 值,每次修改业务代码(pageA),这段初始化时代码就会发生变化,那么如果将这段初始化代码放在 vendor 文件中的话,每次都会生成新的 vendor.xxxx.js,这样不利于持久化缓存,如果不理解也没关系,下次我会另外写一篇文章来讲述这部分内容。

    另外 webpack 默认会抽离异步加载的代码,这个不需要你做额外的配置,pageB 中异步加载的 utilC 文件会直接抽离为 chunk.xxxx.js 文件。

    所以这时候我们页面加载文件的顺序就会变成:

    mainifest.xxxx.js // 初始化代码
    vendor.xxxx.js // pageA 和 pageB 共同用到的模块,抽离
    pageX.xxxx.js  // 业务代码 
    当 pageB 需要 utilC 时候则异步加载 utilC
          

    内容版权声明:除非注明,否则皆为本站原创文章。

    转载注明出处:http://www.heiqu.com/424.html