webpack-demo 主要演示 Webpack 的基础构建方法,最终会生成一个基础的开发框架,本 demo 是根据 Webpack 中文网的 指南 构建的,并且会将指南中的每一小节的内容作为一个单独的 commit 便于查看。
安装之前你需要先安装 Node.js 最新的长期支持的版本。
中国大陆的朋友请不要使用
cnpm
,会有很多奇怪的问题。
安装前请先初始化你的项目
npm install --save-dev webpack # 安装最新版
npm install --save-dev webpack@<version> # 安装特定版本 (<version> 为版本号)
webpack 4+ 版本,还需要安装 CLI。
npm install --save-dev webpack-cli
全局安装的方式不便于项目的维护与升级,不推荐进行全局安装
npm install --global webpack
最新版本可能存在 bug,请勿用于生产环境
npm install webpack@beta
npm install webpack/webpack#<tagname/branchname>
mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
创建相关文件
在 index.js
中打包 lodash
依赖
npm install --save lodash
在安装一个要打包到生产环境的安装包时,你应该使用
npm install --save
,如果你在安装一个用于开发环境的安装包(例如,linter, 测试库等),你应该使用npm install --save-dev
。请在 npm 文档 中查找更多信息。
尝试打包并在浏览器中打开 index.html
npx webpack
打包时会有警告,这个不会影响打包,此问题后续会解决
使用配置文件打包
npx webpack --config webpack.config.js
如果 webpack.config.js
存在,则 webpack
命令将默认选择使用它。我们在这里使用 --config
选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用。
我们可以通过配置方式指定 loader 规则(loader rules)、插件(plugins)、解析选项(resolve options),以及许多其他增强功能。了解更多详细信息,请查看配置文档。
如果你配置了 npm 脚本(npm script) "build": "webpack"
也可以运行 npm run build
打包
为了从 JavaScript 模块中 import
一个 CSS 文件,你需要在 module 配置中 安装并添加 style-loader 和 css-loader:
npm install --save-dev style-loader css-loader
可以进行 CSS 分离,
可以支持任何你可以想到的 CSS 处理器风格 - postcss, sass 和 less 等。
webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。
使用 file-loader,我们可以轻松地将图片混合到 CSS 中:
npm install --save-dev file-loader
合乎逻辑下一步是,压缩和优化你的图像。查看 image-webpack-loader 和 url-loader,以了解更多关于如果增强加载处理图片功能。
file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体。
如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说 import Data from './data.json'
默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loader 和 xml-loader。
npm install --save-dev csv-loader xml-loader papaparse
如果我们更改了我们的一个入口起点的名称,甚至添加了一个新的名称,会发生什么?生成的包将被重命名在一个构建中,但是我们的 index.html
文件仍然会引用旧的名字。我们用 HtmlWebpackPlugin 来解决这个问题。
npm install --save-dev html-webpack-plugin
在我们构建之前,你应该了解,虽然在 dist/
文件夹我们已经有 index.html
这个文件,然而 HtmlWebpackPlugin
还是会默认生成 index.html
文件。这就是说,它会用新生成的 index.html
文件,把我们的原来的替换。
如果你在代码编辑器中将 index.html
打开,你就会看到 HtmlWebpackPlugin
创建了一个全新的文件,所有的 bundle
会自动添加到 html
中。
如果你想要了解更多 HtmlWebpackPlugin 插件提供的全部功能和选项,那么你就应该多多熟悉 HtmlWebpackPlugin 仓库。
html-webpack-template,除了默认模板之外,还提供了一些额外的功能。
由于过去的指南和代码示例遗留下来,导致我们的 /dist
文件夹相当杂乱。webpack 会生成文件,然后将这些文件放置在 /dist
文件夹中,但是 webpack 无法追踪到哪些文件是实际在项目中用到的。
通常,在每次构建前清理 /dist
文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。
clean-webpack-plugin 是一个比较普及的管理插件。
npm install clean-webpack-plugin --save-dev
配置完成后运行 npm run build
旧的文件已经消失,输出目录中只会看到�刚��构建的文件
通过 manifest,webpack 能够对「你的模块映射到输出 bundle 的过程」保持追踪。如果你对通过其他方式来管理 webpack 的输出更感兴趣,那么首先了解 manifest 是个好的开始。
通过使用 WebpackManifestPlugin,可以直接将数据提取到一个 json 文件,以供使用。
你可以仔细深入阅读 manifest 的概念页面,以及通过缓存指南来弄清如何与长期缓存相关联。
由于获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 缓存 的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快,然而,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。
此指南的重点在于通过必要的配置,以确保 webpack 编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。
通过使用 output.filename
进行文件名替换,可以确保浏览器获取到修改后的文件。[hash
] 替换可以用于在文件名中包含一个构建相关(build-specific)的 hash,但是更好的方式是使用 [chunkhash
] 替换,在文件名中包含一个 chunk 相关(chunk-specific)的哈希。
bundle 的名称是它内容(通过 hash)的映射。如果我们不做修改,然后再次运行构建,我们以为文件名会保持不变。然而,如果我们真的运行,可能会发现情况并非如此:(如果不做修改,文件名可能会变,也可能不会。)
就像我们之前从代码分离了解到的,SplitChunksPlugin 可以用于将模块分离到单独的文件中。webpack提供了一个优化功能,它根据提供的选项将运行时代码拆分为单独的块,使用 optimization.runtimeChunk
此插件会自动将我们需要的内容提取到单独的包中
将第三方库(例如lodash或)提取react到单独的vendor块中也是一种很好的做法,因为它们比我们的本地源代码更不可能更改。此步骤将允许客户端从服务器请求更少,以保持最新。这可以通过使用 SplitChunksPlugin的示例 中演示的 cacheGroups
选项来完成。
因为每个 module.id
会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变。因此,简要概括:
main bundle
会随着自身的新增内容的修改,而发生变化。vendor bundle
会随着自身的module.id
的修改,而发生变化。manifest bundle
会因为当前包含一个新模块的引用,而发生变化。
第一个和最后一个都是符合预期的行为 -- 而 vendor 的 hash 发生变化是我们要修复的。幸运的是,可以使用两个插件来解决这个问题。第一个插件是 NamedModulesPlugin
,将使用模块的路径,而不是数字标识符。虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。第二个选择是使用 HashedModuleIdsPlugin
,推荐用于生产环境构建