webpack概念(依赖图、target、manifest)

发布时间 2023-12-27 23:36:52作者: 心意12

依赖图(dependency graph)

依赖的东西可以是代码,也可以是非代码(images和web字体)

 从 入口 开始,webpack 会递归的构建一个 依赖关系图,这个依赖图包含着应用程序中所需的每个模块,然后将所有模块打包为少量的 bundle —— 通常只有一个 —— 可由浏览器加载。

对于 HTTP/2 来说,你还可以使用代码分离进行进一步优化。

target

由于 JavaScript 既可以编写服务端代码也可以编写浏览器代码,所以 webpack 提供了多种部署 target,你可以在 webpack 的配置选项中进行设置

用法

 webpack.config.js
module.exports = {
  target: 'node',
};

在上述示例中,target 设置为 node,webpack 将在类 Node.js 环境编译代码。(使用 Node.js 的 require 加载 chunk,而不加载任何内置模块,如 fs 或 path)。(???为什么要写不加载任何内置模块)

每个 target 都包含各种 deployment(部署)/environment(环境)特定的附加项,以满足其需求。具体请参阅 target 可用值

多 target

 虽然 webpack 不支持 向 target 属性传入多个字符串,但是可以通过设置两个独立配置,来构建对 library 进行同构:

webpack.config.js

 
const path = require('path');
const serverConfig = {
  target: 'node',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.node.js',
  },
  //
};

const clientConfig = {
  target: 'web', // <=== 默认为 'web',可省略
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.js',
  },
  //
};

module.exports = [serverConfig, clientConfig];

上述示例中,将会在 dist 文件夹下创建 lib.js 和 lib.node.js 文件。

manifest

在使用 webpack 构建的典型应用程序或站点中,有三种主要的代码类型:

  1. 你或你的团队编写的源码。
  2. 你的源码会依赖的任何第三方的 library 或 "vendor" 代码。
  3. webpack 的 runtime 和 manifest,管理所有模块的交互。

本文将重点介绍这三个部分中的最后部分:runtime 和 manifest,特别是 manifest。

runtime

runtime,以及伴随的 manifest 数据,主要是指:在浏览器运行过程中,webpack 用来连接模块化应用程序所需的所有代码。它包含:在模块交互时,连接模块所需的加载和解析逻辑。包括:已经加载到浏览器中的连接模块逻辑,以及尚未加载模块的延迟加载逻辑。

manifest

一旦你的应用在浏览器中以 index.html 文件的形式被打开,一些 bundle 和应用需要的各种资源都需要用某种方式被加载与链接起来。在经过打包、压缩、为延迟加载而拆分为细小的 chunk 这些 webpack 优化 之后,你精心安排的 /src 目录的文件结构都已经不再存在。所以 webpack 如何管理所有所需模块之间的交互呢?这就是 manifest 数据用途的由来……

当 compiler 开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 "manifest",当完成打包并发送到浏览器时,runtime 会通过 manifest 来解析和加载模块。无论你选择哪种 模块语法,那些 import 或 require 语句现在都已经转换为 __webpack_require__ 方法,此方法指向模块标识符(module identifier)。通过使用 manifest 中的数据,runtime 将能够检索这些标识符,找出每个标识符背后对应的模块。

 

如果你决定通过使用浏览器缓存来改善项目的性能,理解runtime和manifest就极为重要

通过使用内容散列(content hash)作为 bundle 文件的名称,这样在文件内容修改时,会计算出新的 hash,浏览器会使用新的名称加载文件,从而使缓存无效。一旦你开始这样做,你会立即注意到一些有趣的行为。即使某些内容明显没有修改,某些 hash 还是会改变。这是因为,注入的 runtime 和 manifest 在每次构建后都会发生变化。

查看 管理输出 指南的 manifest 部分,了解如何提取 manifest,并阅读下面的指南,以了解更多长效缓存错综复杂之处。