Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Webpack】Code Spliting 代码分割 #46

Open
Tracked by #6
swiftwind0405 opened this issue Apr 17, 2020 · 2 comments
Open
Tracked by #6

【Webpack】Code Spliting 代码分割 #46

swiftwind0405 opened this issue Apr 17, 2020 · 2 comments
Labels

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Apr 17, 2020

Code Splitting 的核心是把很大的文件,分离成更小的块,让浏览器进行并行加载。

常见的代码分割有三种形式:

  • 手动进行分割:例如项目如果用到 lodash,则把 lodash 单独打包成一个文件。
  • 同步导入的代码:使用 Webpack 配置进行代码分割。
  • 异步导入的代码:通过模块中的内联函数调用来分割代码。

手动进行分割的意思是在 entry 上配置多个入口。
比如配置两个 entry,它就会输出两个模块,也能在一定程度上进行代码分割,不过这种分割是十分脆弱的,如果两个模块共同引用了第三个模块,那么第三个模块会被同时打包进这两个入口文件中,而不是分离出来。
所以我们常见的做法是关心最后两种代码分割方法,无论是同步代码还是异步代码,都需要在 webpack.common.js 中配置 splitChunks 属性,像下面这样子:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all'
	  // async:此值为默认值,只有异步导入的代码才会进行代码分割
	  // initial:与async相对,只有同步引入的代码才会进行代码分割。
	  // all:表示无论是同步代码还是异步代码都会进行代码分割。
    }
  }
}
@swiftwind0405
Copy link
Owner Author

webpack和code Splitting:

  • 代码分割是webpack相当重要的一个特性,可以让代码分割到不同的文件中,一边按需加载或者并行加载这些文件,这样可以优化加载性能,以及用户体验会更好。
  • 代码分割其实只是在webpack中去实现代码分割,两种方式,同步代码分割只需optimization中配置即可,异步代码分割,webpack代码分割默认配置就是对异步代码进行代码分割,但是需要babel插件来做翻译,浏览器对异步的这种语法规则不支持。
//异步代码分割,安装babel插件,babel-plugin-dynamic-import-webpack
npm install babel-plugin-dynamic-import-webpack -D
//同步代码分割的话需要在optimization中配置splitChunks
//---在.babelrc中去配置一个plugins,
presets: [], 
plugins: ["dynamic-import-webpack"]
//webpack.common.js
optimization: {
    splitChunks: {
        chunks: 'all'//对同步代码和异步代码同时做代码分割
        chunks:'aysnc'//对异步代码做分割
    }
}
//test-code--index.js
function getComponent() { 
    return import('lodash').then(({default:_}) => {
        var element = document.createElement('div');
        element.innerHTML = _.join(['dell','lee'],'_');
        return element
    })
}
getComponent().then(element => {
    document.body.appendChild(element);
})
  • splitChunksPlugin的底层配置中,异步代码会自动打包成一个文件0.js,这里需要指定引入异步代码文件的名字可以使用魔法注释,这里就需要这个插件@babel/plugin-syntax-dynamic-import来做异步代码的转化,不能使用上面那个插件babel-plugin-dynamic-import-webpack,/webpackChuunkName:‘lodash’/,
  • chunks:aysnc这种异步代码可以解决打包文件过大,加载时间过长,分出第三方库和插件,需要的时候在进行按需加载和并行加载,提供加载性能。
npm install @babel/plugin-syntax-dynamic-import --save-dev
splitChunks: {
    chunks: async //--如果是async的话,只是对异步代码做代码分割,all是对异步和同步分都做代码分割
    minSize: 30000===30kb //大于30kb就会做代码分割,小于的话就做代码分割
    maxSize:0,//可配可不配 --如果是50000===50kb, 会做二次分割 lodash 打包成1mb ,会拆成20个50kb代码分割
    minChunks: 1,//当这个模块使用几次的话在做代码分割,小于的设置的次数就不做代码分割
    maxAsyncRequests: 5,//同时加载的模块是5个,在打包前五个会帮你打包做代码分割,超过五个的话就不做代码分割
    maxInitialRequests: 3,//指整个网站首页进行加载的时候或者是入口文件进行加载的时候,入口文件会引入其他库,也只能最多三个,超过三个就不会做代码分割了
    automaticNameDelimiter: '~',//文件生成的时候,文件的中间会有一些连接符,
    name: true, ---//起什么名字,让cacheGroups中的名字有效
    cacheGroups: {//如果是同步的话会走完chunks之后会走这个配置,缓存组
        vendors: {
            test: /[\\/]node_modules[\\/]/,//--是同步代码发现是从node_modules引入的话,那么符合这个组会被打包成单独文件
            priority: -10
            filename: 'vendors.js'//是打包文件的名字
        }
        default: {
            priority: -20,//假设同时符合两个组,通过这个配置来设置优先级,值越大,优先级越高
            reuseExistingChunk: true,如果一个模块a,b,如果a使用了b,符合代码分割的要求,然后又符合default这个组,就不打包之前打包过的内容
            filename: 'common.js'
        }
    }
}
  • lazy loading—就是支持esmodule这种语法,按需加载。
  • css代码分割: filename与chunkFilename区别:官网的代码分割插件:做的事情就是把css文件单独打包,不直接打包到js文件里面,这个插件不支持HMR,所以css代码分割插件一般应用到生产环境.
//安装插件
npm install mini-css-extract-plugin --save-dev
//线上环境单独生成的css文件需要做代码压缩合并
npm install optimize-css-assets-webpack-plugin -D
//optimization
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require(' optimize-css-assets-webpack-plugin')
//配置做更改
//开发环境使用规则默认
//线上环境
module: {
    rules: [
            use: ['MiniCssExtractPlugin.loader'] //所有使用style-loader全部替换,不使用style-loader   
        ]
},
optimization: {minimizer: [new OptimizeCssAssetsWebpackPlugin({})]},
plugins: [new MiniCssExtractPlugin({
    filename: '[name].css',//被文件直接引用走这个配置
    chunkFilename: '[name].chunk.css'//被间接引用的话是走这个配置项
})]
output: {
    filename: '[name].js',
    chunkFilename: '[name].chunk.js'//就是被js间接引用的打包文件就会走这个配置内容,
    path: path.resolve(__dirname,'../dist')
}

参考文档

@swiftwind0405 swiftwind0405 changed the title webpack之代码分割 【webpack】Code Spliting 代码分割 Apr 17, 2020
@swiftwind0405 swiftwind0405 changed the title 【webpack】Code Spliting 代码分割 【Webpack】【进阶】Code Spliting 代码分割 Apr 17, 2020
@swiftwind0405
Copy link
Owner Author

@swiftwind0405 swiftwind0405 changed the title 【Webpack】【进阶】Code Spliting 代码分割 【Webpack】Code Spliting 代码分割 Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant