Skip to content

ChanMenglin/webpack-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Webpack

webpack-demo 主要演示 Webpack 的基础构建方法,最终会生成一个基础的开发框架,本 demo 是根据 Webpack 中文网的 指南 构建的,并且会将指南中的每一小节的内容作为一个单独的 commit 便于查看。

1. 安装

安装之前你需要先安装 Node.js 最新的长期支持的版本。

1. �本地安装

中国大陆的朋友请不要使用 cnpm,会有很多奇怪的问题。
安装前请先初始化你的项目

npm install --save-dev webpack # 安装最新版
npm install --save-dev webpack@<version> # 安装特定版本 (<version> 为版本号)

webpack 4+ 版本,还需要安装 CLI。

npm install --save-dev webpack-cli

2. 全局安装(不推荐)

全局安装的方式不便于项目的维护与升级,不推荐进行全局安装

npm install --global webpack

3. 最新体验版本

最新版本可能存在 bug,请勿用于生产环境

npm install webpack@beta
npm install webpack/webpack#<tagname/branchname>

2. 起步

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 打包

3. 资源管理

1. 加载�css

为了从 JavaScript 模块中 import 一个 CSS 文件,你需要在 module 配置中 安装并添加 style-loadercss-loader

npm install --save-dev style-loader css-loader

可以进行 CSS 分离
可以支持任何你可以想到的 CSS 处理器风格 - postcss, sassless 等。

webpack 根据正则表达式,来确定应该查找哪些文件,并将其提供给指定的 loader。

2. 加载图片

使用 file-loader,我们可以轻松地将图片混合到 CSS 中:

npm install --save-dev file-loader

合乎逻辑下一步是,压缩和优化你的图像。查看 image-webpack-loaderurl-loader,以了解更多关于如果增强加载处理图片功能。

3. 加载字体

file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体。

4. 加载数据

如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说 import Data from './data.json' 默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loaderxml-loader

npm install --save-dev csv-loader xml-loader papaparse

5. 管理输出

如果我们更改了我们的一个入口起点的名称,甚至添加了一个新的名称,会发生什么?生成的包将被重命名在一个构建中,但是我们的 index.html 文件仍然会引用旧的名字。我们用 HtmlWebpackPlugin 来解决这个问题。

设定 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 文件夹

由于过去的指南和代码示例遗留下来,导致我们的 /dist 文件夹相当杂乱。webpack 会生成文件,然后将这些文件放置在 /dist 文件夹中,但是 webpack 无法追踪到哪些文件是实际在项目中用到的。
通常,在每次构建前清理 /dist 文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。

clean-webpack-plugin 是一个比较普及的管理插件。

npm install clean-webpack-plugin --save-dev

配置完成后运行 npm run build 旧的文件已经消失,输出目录中只会看到�刚��构建的文件

Manifest

通过 manifest,webpack 能够对「你的模块映射到输出 bundle 的过程」保持追踪。如果你对通过其他方式来管理 webpack 的输出更感兴趣,那么首先了解 manifest 是个好的开始。
通过使用 WebpackManifestPlugin,可以直接将数据提取到一个 json 文件,以供使用。
你可以仔细深入阅读 manifest 的概念页面,以及通过缓存指南来弄清如何与长期缓存相关联。

推荐阅读:开发指南 | 代码分离指南

6-3. 缓存

由于获取资源是比较耗费时间的,这就是为什么浏览器使用一种名为 缓存 的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快,然而,如果我们在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。由于缓存的存在,当你需要获取新的代码时,就会显得很棘手。

此指南的重点在于通过必要的配置,以确保 webpack 编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。

1. 输出文件的文件名(Output Filenames)

通过使用 output.filename 进行文件名替换,可以确保浏览器获取到修改后的文件。[hash] 替换可以用于在文件名中包含一个构建相关(build-specific)的 hash,但是更好的方式是使用 [chunkhash] 替换,在文件名中包含一个 chunk 相关(chunk-specific)的哈希。
bundle 的名称是它内容(通过 hash)的映射。如果我们不做修改,然后再次运行构建,我们以为文件名会保持不变。然而,如果我们真的运行,可能会发现情况并非如此:(如果不做修改,文件名可能会变,也可能不会。)

2. 提取模板(Extracting Boilerplate)

就像我们之前从代码分离了解到的,SplitChunksPlugin 可以用于将模块分离到单独的文件中。webpack提供了一个优化功能,它根据提供的选项将运行时代码拆分为单独的块,使用 optimization.runtimeChunk 此插件会自动将我们需要的内容提取到单独的包中

将第三方库(例如lodash或)提取react到单独的vendor块中也是一种很好的做法,因为它们比我们的本地源代码更不可能更改。此步骤将允许客户端从服务器请求更少,以保持最新。这可以通过使用 SplitChunksPlugin的示例 中演示的 cacheGroups 选项来完成。

3. 模块标识符(Module Identifiers)

因为每个 module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变。因此,简要概括:

  • main bundle 会随着自身的新增内容的修改,而发生变化。
  • vendor bundle 会随着自身的 module.id 的修改,而发生变化。
  • manifest bundle 会因为当前包含一个新模块的引用,而发生变化。

第一个和最后一个都是符合预期的行为 -- 而 vendor 的 hash 发生变化是我们要修复的。幸运的是,可以使用两个插件来解决这个问题。第一个插件是 NamedModulesPlugin,将使用模块的路径,而不是数字标识符。虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。第二个选择是使用 HashedModuleIdsPlugin,推荐用于生产环境构建

参考链接
webpack | 指南-起步