博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
demo09 使用 SplitChunksPlugin 分离第三方依赖包以及异步包
阅读量:6574 次
发布时间:2019-06-24

本文共 4285 字,大约阅读时间需要 14 分钟。

1.为什么要代码分离

在单页面或多页面应用中,通过代码分离的方式,能够优化性能。

比如把异步加载的代码分离成一个单独的chunk,等到需要调用的时候再按需加载(比如click时),这样可以减少首屏的代码体积,从而提高首屏的加载速度。

另外,在我们的项目中,可能会用到很多的第三方库(比如 lodash 、rxjs 等),而往往这些第三方依赖库的代码一般很少变化,因此,很适合把第三方依赖库单独分离成一个包,并且包名包含 hash( webpack 可以轻松做到),这样的好处在于,可以配合浏览器http的缓存机制 (比如 max-age ),实现对相关资源包的长缓存,从而优化性能。

一般需要代码分割的场景有:

  • 分离业务代码和第三方依赖
  • 分离首次加载和异步加载的代码
  • 分离业务代码和业务的公用代码

2.安装相关依赖

通过 html-webpack-plugin 自动生成 index.html

npm install -D html-webpack-pluginnpm install -D webpack // html-webpack-plugin 依赖于 webpacknpm install --save axios lodash复制代码

3.目录结构

// `--` 代表目录, `-` 代表文件  --demo09    --src      -app.js      -async-module1.js      -async-module2.js      -module.js    -index.html    -webpack.config.js复制代码

src/async-module1.js

export const data = 'this is async module1';复制代码

src/async-module2.js

export const data = 'this is async module2';复制代码

src/module.js

export const sayHello1 = () => {  console.log('Hi I want to say hello1');}export const sayHello2 = () => {  console.log('Hi I want to say hello2');}export const sayHello3 = () => {  console.log('Hi I want to say hello3');}复制代码

src/app.js

import { sayHello1, sayHello2, sayHello3 } from './module';sayHello1();sayHello2();sayHello3();// 异步加载 async-module1setTimeout(() => {  require.ensure(    [],    function () {      const asyncModule = require("./async-module1");      console.log(asyncModule.data);    },    "module1"  );}, 3000);// 异步加载 async-module2setTimeout(() => {  require.ensure(    [],    function () {      const asyncModule2 = require("./async-module2");      console.log(asyncModule2.data);    },    "module2"  );}, 3000);// 引用第三方库// https://github.com/lodash/lodashimport * as _ from "lodash";// https://github.com/axios/axiosimport * as axios from "axios";console.log(_);console.log(axios);复制代码

3.配置打包第三方库的规则

使用 webpack4 的 splitChunks 可以很容易的做到。

关于splitChunks 的各个参数的用法,可以看我的这篇文章

splitChunks: {      cacheGroups: {        vendors: {          chunks: "all", // 使用 all 模式          test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 下的模块          name: "vendors", // 包命名,最终的命名要结合 output 的 chunkFilename          minChunks: 1,          minSize: 30000,          priority: 10 // 设置优先级        }      }    }复制代码

4.配置打包异步加载包的规则

打包异步加载包

splitChunks: {      cacheGroups: {        async: {          chunks: "async",          minChunks: 1, // 代码块至少被引用的次数          maxInitialRequests: 3, // 设置最大的请求数          minSize: 0, // 设置每个 chunk 最小的大小 (默认30000),这里设置为 0,以方便测试          automaticNameDelimiter: '~',          priority: 9        },      }    }复制代码

5.完整的 webpack 配置文件

const path = require("path");module.exports = {  mode: 'development', // 使用development模式,方便看到各个包名中的 [name],以区分各个包,在production模式下,[name]会被转化为0 1 2...  entry: {    app: "./src/app.js",  },  output: {    publicPath: __dirname + "/dist/", // 打包后资源文件的引用会基于此路径    path: path.resolve(__dirname, "dist"), // 打包后的输出目录    filename: "[name].[chunkhash].bundle.js", // 每个包包含 chunkhash    chunkFilename: "[id].[chunkhash].chunk.js"  },  optimization: {    runtimeChunk: "single",    splitChunks: {      cacheGroups: {        async: {          chunks: "async",          minChunks: 1, // 代码块至少被引用的次数          maxInitialRequests: 3, // 设置最大的请求数          minSize: 0, // 设置每个 chunk 最小的大小 (默认30000),这里设置为 0,以方便测试          automaticNameDelimiter: '~',          priority: 9        },        vendors: {          chunks: "all", // 使用 all 模式          test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 下的模块          name: "vendors", // 包命名,最终的命名要结合 output 的 chunkFilename          minChunks: 1,          minSize: 30000,          priority: 10 // 设置优先级        }      }    }  }};复制代码

5.执行打包命令

(默认你已经安装了全局 webpack 以及 webpack-cli )

webpack复制代码

打包成功后,结果输出在 demo09 的 dist 目录下

(注意这里设置 "mode""development" )

app.226a343cb53e0a689358.chunk.js (app主模块)async~module1.87d116fd41640c30a6b2.chunk.js (async-module1模块)async~module2.65866f4d15253512c981.chunk (async-module2模块)runtime.4e6de616bd3030f8bff8.bundle.js (webpack运行时模块)vendors.a83c085b3a7ac03b1b47.chunk.js (第三方依赖模块)复制代码

6.修改程序代码,验证打包结果

可以通过修改 app.js 等代码,再次运行 webpack 命令,你会发现,第三方依赖模块的包名没有被改变: vendors.a83c085b3a7ac03b1b47.chunk.js

在浏览器运行 dist/index.html,打开控制台可以观察异步加载模块的效果。

(备注:runtime.xxxxxxxx.bundle.js模块包含了对异步加载模块的引用逻辑,此外,异步加载引用的相对路径受 output -> publicPath 配置的影响)

7.源码地址

demo 代码地址:

仓库代码地址(及目录):

转载于:https://juejin.im/post/5ce8eeb1e51d4510926a7ac3

你可能感兴趣的文章
java 面试题解惑二 到底创建了几个String对象?
查看>>
面试总结之 oop desing 之 The Strategy Pattern
查看>>
必 备 习 题 集 (一)
查看>>
第 三 十 四 天:二 阶 段 复 习(五)
查看>>
windows下批量部署简易脚本
查看>>
python爬虫入门—统计豆瓣电影评论词频
查看>>
mysql由于server-id相同而造成同步失败
查看>>
【LoadRunner技术讲座4】利用sitescope监测监控mysql
查看>>
IEnumerable中运用yield
查看>>
python 时间转换(day,hous,minute,second)
查看>>
网络布线线材用量计算公式
查看>>
查询当前数据库用户会话信息
查看>>
创建触发器的基本语法
查看>>
2015.1.15 利用Oracle函数返回表结果 重大技术进步!
查看>>
2015.3.2 VC++6制作非MFC dll以及VS2005、VS2010调用
查看>>
转:模态对话框的支持 (IE,Firefox,Chrome)
查看>>
让您的电脑在任意目录可以支持图片的粘贴,试试看呗~
查看>>
Jenkins+QTP自动化测试框架
查看>>
《Node.js In Action》笔记之流程控制
查看>>
C++类和对象
查看>>