17.webpack优化配置-code split 代码分割

303 阅读2分钟

webpack会将所有依赖的文件打包到一个文件中,即bundle.js文件,当一个项目慢慢变得复杂的时候会导致这个bundle.js文件越来越大,浏览器加载的速度也会越来越慢,可以使用代码分割来将不同代码单独打包成不同文件。

方式一:通过多入口实现代码分割

配置webpack, 将单入口,改为多入口
注意:index.js文件不要引入base.js文件

const path = require('path');


module.exports = {
mode: 'production',
entry: {
index: './src/js/index.js',
base: './src/js/base.js'
},
output: {
filename: 'js/[name][contenthash:8].js',
path: path.resolve(__dirname, 'bulid'),
}
}


方式二:通过optimization将公共代码单独打包

  • 该方式可以将node_modules中代码单独打包一个chunk最终输出

  • 会自动分析多入口chunk中,有没有公共的文件,如果有会将公共文件打包成一个单独的chunk

  • 该方式可以对单入口文件使用,也可以对多入口文件使用。

  • 注意: 被动态导入的文件如base.js文件内容被修改后,hash值会更改,但是index.js打包生成的main156g2sa.js文件中会记录base.js的hash值,导致index.js的打包文件的的hash值也更改。

    解决方法:可以使用runtimeChunk选项使index.js打包生成的main.js不记录base.js生成的hash值,而是将hash值单独放入到一个文件中。

  1. 安装jquery

    npm i jquery --save
    
  2. 入口文件index.js

    import $ from 'jquery';
    function fn(x, y){
        return x * y;
    }
    
  3. base.js文件

    import $ from 'jquery';
    const add = (x, y) => x + y;
    add(2, 5);
    
  4. webpack配置文件

    const path = require('path');
    
    
    module.exports = {
    mode: 'production',
    entry: {
    index: './src/js/index.js',
    base: './src/js/base.js'
    },
    output: {
    filename: 'js/[name][contenthash:8].js',
    path: path.resolve(__dirname, 'bulid'),
    },
    optimization:{
    //被注释的代码不是必须的,可以根据自己需求开启
    splitChunks:{
    chunks: 'all',
    },
    //将当前模块记录其他模块的hash单独打包为一个文件runtime
    runtimeChunk:{
    name: entrypoint => runtime-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${<!-- --></span>entrypoint<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">
    },
    }
    }
    
    
    
  5. 进行打包

    webpack
    
  6. 最终会打包出三个文件,base.js生成的文件,index.js生成的文件,和jquery生成的文件

方式三:import动态导入

  • 通过import动态导入语法,将某个文件单独打包。
  • 可以实现单入口
  1. webpack.config.js文件

    const path = require('path');
    
    
    module.exports = {
    mode: 'production',
    entry: './src/js/index.js',
    output: {
    //[name]默认是chunks
    filename: 'js/[name][contenthash:8].js',
    path: path.resolve(__dirname, 'bulid'),
    },
    optimization:{
    splitChunks:{
    chunks: 'all'
    },
    //将当前模块记录其他模块的hash单独打包为一个文件runtime
    runtimeChunk:{
    name: entrypoint => runtime-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${<!-- --></span>entrypoint<span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">
    },
    }
    }
    
    
    
    
    
  2. 入口文件index.js

    import $ from 'jquery';
    
    
    //加载base.js文件,返回promise
    //webpackChunkName是将打包后的文件名以base开头,相同的webpackChunkName将被打包到一个文件中
    //base.js文件一定要进行导出(export)
    import( /* webpackChunkName: 'base' */ './base').then((result) => {
    console.log(result);
    }).catch(() => {
    console.log('base.js加载失败!');
    });
    
    
    
    
    function fn(x, y) {
    return x * y;
    }
    
    
    
  3. 打包

    webpack
    
  4. 打包信息
    在这里插入图片描述