webpack-code split代码分割

  • Post author:
  • Post category:其他


在前面的学习中,可以发现,js代码都打包成了一个文件。

这样使得js文件很大,影响加载速度,我们希望能将文件进行分割,这样可以实现多个文件并行加载,速度更快,另外代码分割之后还可以实现按需加载等功能。

代码分割方法一:通过入口文件进行代码分割

项目里面有两个js文件(index.js,test.js),可以通过设置entry实现多个入口,从而打包生成多个js文件。

    // 单入口
    // entry:'./src/js/index.js',
    // 多入口
    entry:{
        main:'./src/js/index.js',
        test:'./src/js/test.js'
    },

output修改输出文件名filename:’js/[name].[contenthash:10].js’,

    output: {
        // 输出文件名
        // filename: 'built.js',
        // [name]:取entry中的文件名,如果entry中是main,则输出就是main,如果是test输出就是test
        filename:'js/[name].[contenthash:10].js',
        // 输出文件路径-写路径是要写绝对路径
        // __dirname是nodejs的变量,代表当前文件的目录绝对路径,在这里当前文件指的就是webpack.config.js
        // 第二个参数,当前路径下的哪个文件中,这里指的就是打包后的资源输出到当前路径下的build文件夹中
        //连上上面的filename,就是打包资源输出到当前文件路径下的build文件夹中的built.js文件中
        path: resolve(__dirname, 'build')
    },

执行webpakc命令

可以看到打包生成了两个js文件。

但是这种方法有一点缺点:如果js文件名修改,或者js文件增加或者减少时,都需要修改配置很不方便。

代码分割方法二:通过splitChunks属性进行代码分割

单入口分析

不配置splitChunks

将入口文件还原为单入口,然后在index.js中引入jquery,

import '../css/style1.css'
import '../css/style2.less'
// import { test, test2, test3 } from './test.js'
import $ from 'jquery'

console.log('index.js执行了')

// test()
// test2([1, 2, 3])

function add(a, b) {
    return a + b;
}

console.log(add(1, 3))

console.log($)

执行webpack命令:

在webpack.config.js中配置splitChunks

    optimization:{
        splitChunks:{
            chunks:'all'
        }
    },

重新执行webpack

可以看到代码进行了分割。

splitChunks可以将node_modules中的代码单独打包成一个chunk输出

多入口分析

代码设置成多入口,并且在test中也引入jquery

import $ from 'jquery'

console.log($)

console.log('test.js执行了')

export function test() {
    const value = 'hello world'
    console.log('test value: ', value)
}

export function test2(arr) {
    if (!arr || arr.length <= 0) {
        console.log('test2 传参错误')
        return
    }
    const result = arr.reduce((sum, current) => sum += current, 0)
    console.log('test2  result: ', result)
}
export function test3(a, b) {
    console.log('test3 执行力')
    return a + b
}

不配置splitChunks

执行webpack命令

从打包后的文件大小可以看出,当多个入口都引入同一个库文件时,每个入口都会将库文件打包进去,这很不友好,如果整个项目只打包一次才是我们想要的。

在webpack.config.js中配置splitChunks

设置了splitChunks之后,再重新运行webpack命令

从打包输出文件可以明显看出jquery文件只打包了一次,并且输出了3个文件(一个node_modules库文件,两个入口文件)。这样项目的输出文件就减小了很多。

所以,splitChunks 会自动分析多个入口chunk中,有没有公共的文件,如果有则会打包成单独的一个chunk,而不会重复加载

代码分割方法三:通过js代码进行代码分割

将配置修改为单入口,这样虽然设置了splitChunks,但是也只会将node_modules中文件单独打包。

在index.js中引入test.js文件

import '../css/style1.css'
import '../css/style2.less'
import { test, test2, test3 } from './test.js'
import $ from 'jquery'

console.log('index.js执行了')

test()
test2([1, 2, 3])

function add(a, b) {
    return a + b;
}

console.log(add(1, 3))

console.log($)

执行webpack:

可以看到只打包了jquery库文件和index.js文件,test.js并没有单独打包。我们希望能将test文件也单独打包,该怎么处理呢?可以通过js代码,让某个文件单独打包成一个chunk

修改test.js的引入方式

// import { test, test2, test3 } from './test.js'

import('./test').then((result) => {
    console.log('test.js加载成功')
    console.log('result:', result)
}).catch(() => {
    console.log('test.js加载失败')
})

输出result中是es6的module,在module中有test.js中的方法,如果需要使用test.js中的方法,就需要直接传入方法

// import { test, test2, test3 } from './test.js'

import('./test').then(({ test, test2 }) => {
    console.log('test.js加载成功')
    // console.log('result:', result)
    test()
    test2([1, 2, 3])
}).catch(() => {
    console.log('test.js加载失败')
})

这种方法就是通过import动态倒入语法,能将某个文件单独打包

但是,从打包的输出文件可以看出输出的名字不是我们想要的。我们希望能够指定文件名。

可以通过webpackChunkName来设置打包输出的文件名

// import { test, test2, test3 } from './test.js'

import(/*webpackChunkName:'test'*/'./test').then(({ test, test2 }) => {
    console.log('test.js加载成功')
    // console.log('result:', result)
    test()
    test2([1, 2, 3])
}).catch(() => {
    console.log('test.js加载失败')
})

可以看到重新运行后的test.js的输出文件名已经是我们指定的路。



版权声明:本文为Celester_best原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。