Open tomoya06 opened 3 years ago
完整过程参考博客
首次加载时:
热更新时:
概述:tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。webpack的tree-shaking依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。
Dead Code 一般具有以下几个特征
ES6 module特点:
ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础。
进一步分析:
"side effect(副作用)" 的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个 export 或多个 export。举例说明,例如 polyfill,它影响全局作用域,并且通常不提供 export。
具有副作用的文件不应该做TS。默认webpack认为所有的代码都有副作用,这可以保护你免于删除必要的文件,但这意味着 Webpack 的默认行为实际上是不进行 tree-shaking。不过可以通过配置告诉webpack当前项目是没有副作用的,可以进行TS。
代码参考掘金博客
package.json 有一个特殊的属性 sideEffects。它有三个可能的值:
另外,也可以在loader的配置中设置sideEffects
属性,告诉webpack这类文件都会有副作用。
在编写支持 tree-shaking 的代码时,导入方式非常重要。你应该避免将整个库导入到单个 JavaScript 对象中。当你这样做时,你是在告诉 Webpack 你需要整个库, Webpack 就不会摇它。
以流行的库 Lodash 为例。一次导入整个库是一个很大的错误,但是导入单个的模块要好得多。当然,Lodash 还需要其他的步骤来做 tree-shaking,但这是个很好的起点:
// 全部导入 (不支持 tree-shaking)
import _ from 'lodash';
// 具名导入(支持 tree-shaking)
import { debounce } from 'lodash';
// 直接导入具体的模块 (支持 tree-shaking)
import debounce from 'lodash/lib/debounce';
Webpack
概述
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个 依赖图(dependency graph),此依赖图会映射项目所需的每个模块,并生成一个或多个 bundle。
核心概念
webpack 的核心有四个
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。
loader
webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
在更高层面,在 webpack 的配置中,loader 有两个属性:
插件(plugin)
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
构建流程
webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
在以上过程中,webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 webpack 提供的 API 改变 webpack 的运行结果。