Tip:splitChunks.chunks,表明将选择哪些 chunk 进行优化。当提供一个字符串,有效值为 all,async 和 initial。设置为 all 可能特别强大,因为这意味着 chunk 可以在异步和非异步 chunk 之间共享。
> npm i lodash@4 // index.js import _ from 'lodash'; console.log(_);打包只生成一个 js:
> npm run build Asset Size Chunks Chunk Names index.html 303 bytes [emitted] main.js 72.7 KiB 0 [emitted] main配置splitChunks.chunks:
// webapck.config.js module.exports = { optimization: { splitChunks: { chunks: 'all', }, }, };再次打包,这次生成两个 js,其中Chunk Names 是 vendors~main 对应的就是 loadsh:
> npm run build Asset Size Chunks Chunk Names 1.main.js 71.5 KiB 1 [emitted] vendors~main index.html 336 bytes [emitted] main.js 1.9 KiB 0 [emitted] main同一个 chunk 中,如果 index.js 和 a.js 都引入 loadash,会如何打包?请看示例:
// index.js import {a} from './a.js' import _ from 'lodash'; console.log(a) console.log(_); // a.js export let a = 'hello' export let b = 'jack' > npm run build Asset Size Chunks Chunk Names 1.main.js 71.5 KiB 1 [emitted] vendors~main index.html 336 bytes [emitted] main.js 1.92 KiB 0 [emitted] main同样是两个 js,而且 loadash 应该是公用了,因为 main.js 较上次只增加了 0.02 kb。
动态导入使用动态导入可以分离出 chunk。
请看示例:
上文我们知道,这段代码打包会生成两个 js,其中 main.js 包含了 a.js。
// index.js import {a} from './a.js' import _ from 'lodash'; console.log(a) console.log(_);将其中的 a.js 改为动态导入的方式:
// index.js import _ from 'lodash'; // 动态导入 import(/* webpackChunkName: 'a' */'./a').then((aModule) => { console.log(aModule.a); }); console.log(_);打包:
> npm run build Asset Size Chunks Chunk Names 0.main.js 192 bytes 0 [emitted] a 2.main.js 94.6 KiB 2 [emitted] vendors~main index.html 336 bytes [emitted] main.js 2.75 KiB 1 [emitted] main其中 a.js 被单独打包成一个js(从 Chunk Names 为 a 可以得知)
懒加载懒加载就是用到的时候在加载。
请看示例:
我们在入口文件注册一个点击事件,只有点击时才加载 a.js。
// index.js document.body.onclick = function () { // 动态导入 import(/* webpackChunkName: 'a' */'./a').then((aModule) => { console.log(aModule.a); }); }; // a.js console.log('moduleA'); export let a = 'hello' export let b = 'jack'启动服务,测试:
> npm run dev 第一次点击:moduleA hello 第二次点击:hello只有第一次点击,才会请求 a.js 模块。
Tip:懒加载其实用到的就是上文介绍的动态导入
预获取思路可能是这样:
首先使用普通模式
普通模式下,一次性加载太多,而 a.js 这个文件又有点大,于是就使用懒加载,需要使用的时候在加载 a.js
触发点击事件,懒加载 a.js,但 a.js 很大,需要等待好几秒中才触发,于是我想预获取来减少等待的时间
将懒加载改为预获取:
// index.js document.body.onclick = function () { // 动态导入 import(/* webpackChunkName: 'a', webpackPrefetch: true*/'./a').then((aModule) => { console.log(aModule.a); }); };刷新浏览器,发现 a.js 被加载了;触发点击事件,输出 moduleA hello,再次点击,输出 hello。
Tip:浏览器中有如下一段代码:
// 指示着浏览器在闲置时间预取 0.main.a3f7d94cb1.js <link as="script" href="http://www.likecs.com/0.main.a3f7d94cb1.js">预获取和懒加载的不同是,预获取会在空闲的时候先加载。
渐进式网络应用程序渐进式网络应用程序(progressive web application - PWA),是一种可以提供类似于 native app(原生应用程序) 体验的 web app(网络应用程序)。PWA 可以用来做很多事。其中最重要的是,在离线(offline)时应用程序能够继续运行功能。这是通过使用名为 Service Workers 的 web 技术来实现的。
我们首先通过一个包来启动服务:
> npm i -D http-server@0 // package.json { "scripts": { "start": "http-server dist" }, } > npm run build启动服务:
> npm run start > webpack-example3@1.0.0 start > http-server dist Starting up http-server, serving dist Available on: :8080 :8080 :8080 :8080 Hit CTRL-C to stop the server