内容简介:Webpack 是一个模块打包工具。Webpack 可以与不同的 task runner 一起处理依赖包。然而,由于 Webpack 社区开发的插件越来越全备,使得两者之间的界限变得模糊了。有时,这些插件也会用于执行 Webpack 之外的任务,例如清理构建目录或部署构建。React,如果您想更详细地了解构建工具及其历史,请查看。
Webpack 是一个模块打包工具。Webpack 可以与不同的 task runner 一起处理依赖包。然而,由于 Webpack 社区开发的插件越来越全备,使得两者之间的界限变得模糊了。有时,这些插件也会用于执行 Webpack 之外的任务,例如清理构建目录或部署构建。
React, Hot Module Replacement (HMR) 等技术的发展将 Webpack 逐步带入开发者的视野中,并使得它能够使用在其他技术栈中,例如 Ruby on Rails 。尽管它的名字中带有一个 Web,但是 Webpack 的应用却不局限于 Web 中,其它应用场景Build Targets 。
如果您想更详细地了解构建 工具 及其历史,请查看。
Webpack 依赖模块
你可以利用 Webpack 对一个包含入口、出口的项目进行打包。其中,入口是打包过程的起始,由你自定义。并且入口本身也是模块,可以导入其他的模块。
当你使用 Webpack 打包一个项目时,它会遍历所有导入的模块,并构建整个面项目对应的依赖关系图( dependency graph ),然后依据配置生成输出文件。此外,还可以定义拆分界限,以在项目内创建单独的包。
Webpack 本身就支持 ESES2015,CommonJS,以及 AMD,三种文件格式。这种加载器机制同样也适用于 CSS,利用 css-loader 对 @import 、url() 两种语法进行支持。你还可以找到完成特定任务的插件,例如较小包体积,国际化,HMR等。
依赖图指定是描述节点如何相互关联的有向图。 在这种情况下,图形定义是通过文件之间的引用(require,import)关系。 Webpack 在不执行源的情况下静态遍历这些源,以生成创建打包所需的图。
Webpack 的执行过程
Webpack 从图中 Entry 处开始工作,也就是之前提到的入口。通常 Webpack 会从这几个 JavaScript 模块开始遍历。在这个过程中,Webpack 会依据图中 Loaders 的配置中 test、loader 项来处理某一个模块,例如图中利用 test: /\.js$/
来匹配对应的 .js 文件,同时选用 babel-loader 来处理。
解析过程
由于入口也是模块的一部分,当 Webpack 遇到时,就会尝试依据入口的解析配置进行匹配。除了 node_modules 之外,你还可以利用 Webpack 对特定目录执行查找。也可以调整 Webpack 与文件扩展名匹配的方式,并且设计具体的目录。具体可以查看Consuming Packages。
如果解析失败,Webpack 会报一个 runtime 的异常。如果 Webpack 想要正确地解析一个文件,则必须根据加载器的定义对匹配的文件进行执行处理。每个加载器都是对特定模块内容进行转换。
一个 Loader 可以通过多种方式来匹配对应文件,包括文件类型和文件系统中的位置。 Webpack 甚至灵活性到允许根据文件在项目中的导入位置来进行特定的转换。
Webpack 的 Loaders 也会执行相同的解析过程。Webpack 允许你应用类似的逻辑来决定应用那个 loader。由于这个原因,相应的加载程序已经解析了自己的配置。 如果Webpack 无法执行加载程序查找,则会报一个运行时错误。
为了解析,webpack 底层依赖了enhanced-resolve 。
Webpack 解析任何类型的文件
Webpack 会在构建依赖图的过程中,解析每一个它遇到的模块。如果入口中包含了一些依赖项,则会针对每个依赖项完成递归操作,直到遍历完成为止。与 Babel 或者 Sass 等这类编译工具不同的是,Webpack 可以针对任何文件执行此过程。
Webpack 还允许你控制如何处理遇到的资源。 例如,你可以决定将资源内联到JavaScript 包以避免请求。 Webpack 还允许你使用 CSS Modules 等技术将样式与组件结合,从而并避免标准 CSS 样式问题。 这种灵活性使 Webpack 非常有价值。
尽管 Webpack 主要用于打包 JavaScript,但是它还能用于捕获图像或者字体等资源,并将生成单独的文件。入口只是打包过程的起点,最终的内容完全取决于你的配置方式。
执行过程
假设所有文件都找到了对应的 Loader,Webpack 则以从下到上,从右到左的方向来执行所匹配到的 Loader(例如``styleLoader(cssLoader('./main.css'))`),并依次通过每个 Loader 运行模块。最终你会得到 Webpack 处理后的包,具体见Loader Definitions。
如果所有的 Loaders 执行过程都在没有运行时错误的情况下完成,则 Webpack 将所以资源打包到一个包中。 插件( Plugins )允许你在打包过程不同阶段拦截运行时事件。
尽管 Loaders 能够做很多事情,但是它们却无法胜任一些高级任务。插件可以拦截 Webpack 提供的打包时的运行事件。例如,MiniCssExtractPlugin 与 Loader 一起使用的时候,可以将 CSS 提取到单独的文件中。如果没有这个插件,CSS 则将内联在生成的 JavaScript 文件中,因为 Webpack 默认将所有代码视为 JavaScript。具体见Separating CSS 。
完成
执行完每一个模块之后,Webpack 会输出最终的包。其中包含着一个引导脚本,用于描述如何在游览器中执行。具体的输出是依据你的构建目标(不一定非要是 Web)。
以上仅仅是一个简易的打包过程,你还可以添加更高级的功能。例如,可以定义特殊的分割点,这样 Webpack 能够基于应用程序生成单独包。具体请见Code Splitting。
Webpack 是配置驱动
Webpack 的核心就是所依赖的配置。这里有一个依据官方 webpack 教程改编的示例配置,其中包含以下要点:
webpack.config.js
const webpack = require("webpack"); module.exports = { // 打包的入口 entry: { app: "./entry.js", }, // 最终输出的文件 output: { // 输出文件所在目录 path: __dirname, // 输出名所用模板 filename: "[name].js", }, // 解析引入的模块 module: { rules: [ { test: /\.css$/, use: ["style-loader", "css-loader"], }, { test: /\.js$/, use: "babel-loader", exclude: /node_modules/, }, ], }, // 要执行的额外处理 plugins: [ new webpack.DefinePlugin({ ... }), ], // 配置 Webpack 如何寻找模块所对应的文件 resolve: { alias: { ... }, }, }; 复制代码
有时候 Webpack 的配置模型有种黑盒的感觉,因为它看起来是庞大而又单一的。在你了解其背后思想之前,很难理解 Webpack 究竟做了什么。
独一无二的资源
使用 Webpack时,你可以为每个包名称注入一个哈希值(例如,app.d587bbd6.js),以便资源更改之后客户端上的缓存的包无效。 Bundle-splitting 使得在理想情况下客户端仅用重新加载一小部分数据。
模块热替换
可能你已经熟悉了 LiveReload、BrowserSync 等工具。这些工具会在你更改时自动刷新游览器。而 HMR 更进一步,它允许应用程序在不强制刷新的情况下更新。虽然这听起来不那么特别,但它可以在实践中产生很大的不同。
在 livereactload、Browserify 中也可以使用HMR,因此它不是 Webpack 独有的功能。
代码分割
除 HMR 外,Webpack 的打包功能也非常强大。 Webpack 允许你以各种方式分割代码。 甚至可以在应用程序执行时动态加载代码。 这种延迟加载特别适用于规模较大的应用程序,因为可以根据需要动态加载依赖项。
即使是小型应用程序也可以从代码分割中受益,因为它允许用户更快地获得可用的东西。 毕竟,性能是一项功能。 了解这项基本技术是值得的。
结论
Webpack 虽然学习成本比较高。然而,考虑到长期可以节省多少时间和精力,这是一个值得学习的工具。 为了更好地了解它与其他工具的比较,请查看官方比较。
Webpack 并不是一把万能钥匙,但是却能解开打包的锁。减少开发过程中的顾虑。package.json 和 Webpack 一起使用,会起到 1 + 1 > 2 的效果。
总结:
- Webpack 是一个模块打包工具,但是你也可以使用它来完成一些任务;
- Webpack 底层基于依赖图,当 Webpack 遍历资源构建图,并使用此信息和配置生成包;
- Webpack 依赖于加载器和插件。加载器主要是模块级别上运行,而插件依赖于 Webpack 提供的钩子,并且可以访问其执行过程;
- Webpack 的配置描述了如何转换图形的资源以及它应该生成哪种输出。 如果使用代码分割等功能,则可以将部分信息包含在本身中;
- 模块热更换(HMR)有助于推广 Webpack。 这是一项特性,无需刷新整页就可以更新游览器中的代码来增强开发体验;
- Webpack 可以生成包含哈希值的文件名,会使得之前的包无效。
如果你还不能确定是否要使用 Webpack,请看这篇安利软文 Why would I use a Webpack?
PS:翻译what is webpack。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深度探索Linux操作系统
王柏生 / 机械工业出版社 / 2013-10-15 / 89.00
《深度探索linux操作系统:系统构建和原理解析》是探索linux操作系统原理的里程碑之作,在众多的同类书中独树一帜。它颠覆和摒弃了传统的从阅读linux内核源代码着手学习linux操作系统原理的方式,而是基于实践,以从零开始构建一个完整的linux操作系统的过程为依托,指引读者在实践中去探索操作系统的本质。这种方式的妙处在于,让读者先从宏观上全面认清一个完整的操作系统中都包含哪些组件,各个组件的......一起来看看 《深度探索Linux操作系统》 这本书的介绍吧!