likes
comments
collection
share

webpack 学习指南(上)

作者站长头像
站长
· 阅读数 15

构建流程

Webpack 的构建流程可以分为以下几个步骤:

  1. 解析配置文件:Webpack 会读取项目中的 webpack.config.js 文件,并解析其中的配置项。

  2. 解析入口文件:Webpack 通过配置文件中设置的 entry 入口,递归地解析出所有依赖的模块和文件,并生成一个依赖图谱(dependency graph)。

  3. 加载模块:Webpack 根据依赖图谱中的每一个模块,按照配置文件中的 loader 规则进行处理,将其转换成 JavaScript 代码或者其他格式的文件。

  4. 模块编译:Webpack 会将各个模块转换后的代码进行编译,使得它们能够在浏览器环境中运行。这一过程通常使用 Babel 等工具来完成。

  5. 模块打包:Webpack 将所有经过处理的模块打包成一个或多个 bundle 文件。根据配置文件中设置的 output 输出路径及文件名,生成相应的文件。

  6. 输出结果:Webpack 将打包结果返回给调用者,或者直接将结果输出到指定的目录中。

  7. 插件执行:Webpack 支持插件机制,用户可以自定义插件对打包过程进行扩展和优化。在打包完成后,Webpack 会按照配置文件中指定的顺序依次执行所有的插件。

总的来说,Webpack 的构建流程是一个输入、转换、输出的过程,通过加载模块、编译、打包和输出等一系列步骤,将多个模块的代码转换为一个或多个可在浏览器中运行的 bundle 文件。同时,Webpack 还提供了丰富的 loader 和 plugin 机制,使得用户可以根据自己的需要进行定制化开发和优化。

webpack 和 rollup 有什么相同和不同点

Webpack 和 Rollup 都是 JavaScript 模块打包工具,它们的相同点和不同点如下:

相同点:

  1. 都支持通过配置文件来定义打包规则和插件;
  2. 都支持 ES6、CommonJS 等多种模块化规范;
  3. 都支持生成代码分割和懒加载;
  4. 都能转换、压缩和优化代码。

不同点:

  1. Webpack 更适用于构建复杂的应用程序,它可以处理各种类型的资源(如 CSS、图片、字体等),并支持热更新和开发服务器等特性。Rollup 更适合于构建类库或组件等简单的项目,它专注于 JavaScript 模块的打包和优化,输出的代码更加简洁高效。
  2. Rollup 采用 Tree-shaking 技术,可以将不使用的代码从最终的 bundle 中删除,从而减少打包后的文件大小。Webpack 也支持 Tree-shaking,但实现方式不同,更依赖于静态分析和模块依赖的可追踪性。
  3. 在代码拆分和动态导入方面,Webpack 采用 import()语法,Rollup 推荐使用动态导入(import())或者静态导入(require())语法。
  4. 在输出模块格式方面,Webpack 支持各种模块化规范的输出(CommonJS、AMD、UMD 等),Rollup 则默认只生成 ES 模块,可以通过插件来支持其他格式的输出。

webpack 热更新是如何实现的

Webpack 的热更新(Hot Module Replacement,简称 HMR)是一种实时更新应用程序代码的技术。在开发过程中,它可以帮助开发人员快速地看到他们所做的更改的效果,而无需手动刷新浏览器。

Webpack 的热更新实现主要依靠以下两个机制:

  1. Webpack Dev Server

Webpack Dev Server 是一个小型 Node.js Express 服务器,它运行在内存中,并且能够提供 Webpack 编译后的文件。Dev Server 会监听文件的变化,如果文件发生了变化,它会重新编译并刷新页面。这个机制保证了在开发过程中自动刷新页面的功能。

  1. Hot Module Replacement 插件

Hot Module Replacement (HMR) 插件是 Webpack 内置的插件之一,它允许在不刷新整个页面的情况下替换模块。当一个模块发生变化时,HMR 插件会通知 Webpack,Webpack 会重新打包该模块及其依赖的模块,并将新的模块发送给浏览器,然后浏览器通过 HMR 接口将新的模块插入到应用程序中。这个机制保证了在开发过程中只更新改变的模块,而不需要重新加载整个页面。

综上所述,Webpack 的热更新实现主要依靠 Webpack Dev Server 和 Hot Module Replacement 插件这两个机制。Dev Server 负责监听文件的变化并刷新页面,HMR 插件负责在模块发生变化时将新的模块更新到应用程序中。这使得开发人员可以快速看到他们所做的更改的效果,并且无需手动刷新浏览器。

webpack 层面如何实现性能优化

以下是几种实现 webpack 性能优化的方法:

  1. 减少编译时间
  • 使用缓存:使用 babel-loader 和 ts-loader 时可以开启缓存,减少重新编译的时间。
  • 减少 loader 数量:尽可能减少使用 loader 的数量,因为每个 loader 都会增加编译时间。
  • 使用多进程并发构建:通过 happyPack 或 thread-loader 等插件来实现。
  1. 减少打包体积
  • 按需加载:将代码分割成更小的块,并在需要时按需加载。可以使用动态导入语法、SplitChunksPlugin 插件等来实现。
  • 压缩代码:使用 UglifyJSPlugin 或 TerserPlugin 对代码进行压缩和混淆。
  • 移除未使用的代码:使用 tree shaking 可以检测和移除未使用的代码。
  1. 加快构建速度
  • 减少扫描范围:使用 resolve.alias 和 resolve.extensions 等选项来减少模块的扫描范围。
  • 提取公共代码:通过 SplitChunksPlugin 插件提取公共代码,减少重复打包的代码。
  • 使用 DllPlugin:使用该插件可以将不变的库代码打包成一个单独的文件,不需要每次都重新构建。
  1. 优化开发体验
  • 使用 DevServer:使用 webpack-dev-server 可以在本地启动一个服务器预览代码,同时支持自动刷新和热更新。
  • 使用 SourceMap:开启 SourceMap 可以将编译后的代码映射回原始代码,方便调试。
  • 优化日志输出:通过 stats 和 friendly-errors-webpack-plugin 等插件可以优化 webpack 的日志输出。

webpack 的 tree-shaking

Tree-shaking 是 webpack 中一个用于优化 JavaScript 代码的技术,它可以通过静态分析代码,识别并移除未被使用的代码,从而降低最终打包后的文件大小。

具体来说,webpack 会对代码进行静态分析,找出所有引用的模块及其依赖关系,形成一棵依赖树。然后,对于每个模块,webpack 会标记其中被实际使用的部分,并将其打包进最终的输出文件中,同时将未被使用的部分从输出文件中移除。这个过程就是 tree-shaking。

在实现上,webpack 使用 ES6 模块语法中的静态导入(import)和动态导入(import())来区分哪些代码是被使用的。对于静态导入的模块,webpack 可以在编译时就确定其依赖关系和引用情况;而对于动态导入的模块,则需要在运行时才能确定它们是否被使用。

需要注意的是,为了确保 tree-shaking 的有效性,代码必须满足一定的条件。其中最重要的条件是代码必须是“纯净”的,即不会产生副作用(比如修改全局变量、读写文件等)。只有满足这个条件,webpack 才能安全地移除未被使用的代码,不会影响到其他部分的代码逻辑。

webpack 的 scop hosting

Webpack 的 Scope Hosting 是一项优化技术,旨在减少 JavaScript 包的大小和运行时的开销。它通过静态分析模块依赖关系,将具有相同作用域的模块合并成一个模块,并移除不必要的变量声明和闭包。这样可以减少 JavaScript 文件的体积和加载时间,并提高应用程序的性能。

具体来说,Scope Hosting 的工作原理是,在打包过程中,Webpack 根据模块之间的依赖关系,将具有相同作用域的模块合并成一个单独的模块。这种方式可以消除重复的变量声明和函数定义,并且可以防止代码膨胀产生额外的闭包。这样会减少 JavaScript 文件的大小,加快应用程序的加载速度,并且在运行时执行更快。

需要注意的是,为了让 Scope Hosting 生效,需要将所有模块都采用 ES6 模块语法进行导入和导出。只有这样,Webpack 才能正确地识别模块之间的依赖关系,从而实现 Scope Hosting 优化。

webpack 的 dll

WebPack 的 DLL(Dynamic Link Library)是一种优化技术,它可以将经常使用的代码打包成单独的库文件,以便在构建时快速引用,从而提高应用程序的性能和构建速度。

具体来说,通过 DLL 技术,我们可以将公共的第三方库或者自己编写的代码打包为一个动态链接库(DLL),然后在应用程序的构建过程中,只需要引用此库文件,而不需要重新打包这些公共代码,从而避免了重复打包的时间和资源浪费。

使用 WebPack 的 DLL 技术,我们需要先创建一个 DLL 配置文件,其中包括要打包的模块和输出文件的路径等信息。然后,在应用程序的 Webpack 配置文件中,我们可以利用 DllReferencePlugin 插件引用这个 DLL 文件,从而实现对公共库代码的快速引用。

总之,通过 WebPack 的 DLL 技术,我们可以充分利用缓存机制,使得构建过程更加高效,并且在多个应用程序之间共享公共代码也更加方便。