webpack中文网(四)懒加载、缓存(main、vendor、manifest bundle)、创建library(lodash _.reduce、外部化lodash、externals、暴露lib

webpack中文网(四)懒加载、缓存(main、vendor、manifest bundle)、创建library(lodash _.reduce、外部化lodash、externals、暴露library)

总结:

  • 懒加载
    • 懒加载或者按需加载,是一种很好的优化网页或应用的方式。
    • 这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。
    • 这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。
  • 缓存
    • main bundle 会随着自身的新增内容的修改,而发生变化。
    • vendor bundle 会随着自身的 module.id 的修改,而发生变化。
    • manifest bundle 会因为当前包含一个新模块的引用,而发生变化。
  • 创建library
    • lodash _.reduce:lodash.reduce | Lodash 中文文档 | Lodash 中文网 (lodashjs.com)
    • 外部化lodash:
      • 现在,如果执行 webpack,你会发现创建了一个非常巨大的文件。如果你查看这个文件,会看到 lodash 也被打包到代码中。在这种场景中,我们更倾向于把 lodash 当作 peerDependency
      • 也就是说,用户应该已经将 lodash 安装好。因此,你可以放弃对外部 library 的控制,而是将控制权让给使用 library 的用户。
      • 这可以使用 externals 配置来完成
    • 暴露library
      • 变量:作为一个全局变量,通过 script 标签来访问(libraryTarget:'var')。
      • this:通过 this 对象访问(libraryTarget:'this')。
      • window:通过 window 对象访问,在浏览器中(libraryTarget:'window')。
      • UMD:在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:'umd')。

1. 懒加载

本指南的继承自代码分离。如果你尚未阅读该指南,请先行阅读。

懒加载或者按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。

示例

我们在代码分离中的例子基础上,进一步做些调整来说明这个概念。那里的代码确实会在脚本运行的时候产生一个分离的代码块 lodash.bundle.js ,在技术概念上“懒加载”它。问题是加载这个包并不需要用户的交互 – 意思是每次加载页面的时候都会请求它。这样做并没有对我们有很多帮助,还会对性能产生负面影响。

我们试试不同的做法。我们增加一个交互,当用户点击按钮的时候用 console 打印一些文字。但是会等到第一次交互的时候再加载那个代码块(print.js)。为此,我们返回到代码分离的例子中,把 lodash 放到主代码块中,重新运行代码分离中的代码 final Dynamic Imports example

project

webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- /src
  |- index.js
+ |- print.js
|- /node_modules

src/print.js

console.log('The print.js module has loaded! See the network tab in dev tools...');

export default () => {
   
  console.log('Button Clicked: Here\'s "some text"!');
}

src/index.js

+ import _ from 'lodash';
+
- async function getComponent() {
+ function component() {
    var element = document.createElement('div');
-   const _ = await import(/* webpackChunkName: "lodash" */ 'lodash');
+   var button = document.createElement('button');
+   var br = document.createElement('br');

+   button.innerHTML = 'Click me and look at the console!';
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.appendChild(br);
+   element.appendChild(button);
+
+   // Note that because a network request is involved, some indication
+   // of loading would need to be shown in a production-level site/app.
+   button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
+     var print = module.default;
+
+     print();
+   });

    return element;
  }

- getComponent().then(component => {
-   document.body.appendChild(component);
- });
+ document.body.appendChild(component());

注意当调用 ES6 模块的 import() 方法(引入模块)时,必须指向模块的 .default 值,因为它才是 promise 被处理后返回的实际的 module 对象。

现在运行 webpack 来验证一下我们的懒加载功能:

Hash: e0f95cc0bda81c2a1340
Version: webpack 3.0.0
Time: 1378ms
          Asset       Size  Chunks                    Chunk Names
print.bundle.js  417 bytes       0  [emitted]         print
index.bundle.js     548 kB       1  [emitted]  [big]  index
     index.html  189 bytes          [emitted]
   [0] ./src/index.js 742 bytes {
   1} [built]
   [2] (webpack)/buildin/global.js 509 bytes {
   1} [built]
   [3] (webpack)/buildin/module.js 517 bytes {
   1} [built]
   [4] ./src/print.js 165 bytes {
   0} [built]
    + 1 hidden module
Child html-webpack-plugin for "index.html":
       [2] (webpack)/buildin/global.js 509 bytes {
   0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {
   0} [built]
        + 2 hidden modules

框架

许多框架和类库对于如何用它们自己的方式来实现(懒加载)都有自己的建议。这里有一些例子:


进一步阅读

2. 缓存

本指南继续沿用起步管理输出代码分离中的代码示例。

以上,我们使用 webpack 来打包我们的模块化后的应用程序,webpack 会生成一个可部署的 /dist 目录,然后把打包后的内容放置在此目录中。只要 /dist 目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问网站此服务器的网站及其资源。而最后一步获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 缓存 的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快,然而,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。

此指南的重点在于通过必要的配置,以确保 webpack 编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。

输出文件的文件名(Output Filenames)

通过使用 output.filename 进行文件名替换,可以确保浏览器获取到修改后的文件。[hash] 替换可以用于在文件名中包含一个构建相关(build-specific)的 hash,但是更好的方式是使用 [chunkhash] 替换,在文件名中包含一个 chunk 相关(chunk-specific)的哈希。

让我们使用起步 中的示例,以及管理输出 中的 plugins 来作为项目的基础,所以我们不必手动处理维护 index.html 文件:

project

webpack-demo
|- package.json
|- webpack.config.js
|- /dist
|- /src
  |- index.js
|- /node_modules

webpack.config.js

  const path = require('path');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry: './src/index.js',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
-       title: 'Output Management'
+       title: 'Caching'
      })
    ],
    output: {
-     filename: 'bundle.js',
+     filename: '[name].[chunkhash].js',
      path: path.resolve(__dirname, 'dist')
    }
  };

使用此配置,然后运行我们的构建脚本 npm run build,应该产生以下输出:

Hash: f7a289a94c5e4cd1e566
Version: webpack 3.5.1
Time: 835ms
                       Asset       Size  Chunks                    Chunk Names
main.7e2c49a622975ebd9b7e.js     544 kB       0  [emitted
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChrisP3616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值