webpack 用于编译 JavaScript 模块。一旦完成安装,你就可以通过 webpackCLI或API与其配合交互。如果你还不熟悉 webpack,请阅读核心概念和对比,了解为什么要使用 webpack,而不是社区中的其他工具。
运行 webpack 5 的 Node.js 最低版本是 10.13.0 (LTS)。
(相关资料图)
基本安装首先我们创建一个目录,初始化 npm,然后在本地安装 webpack,接着安装webpack-cli
(此工具用于在命令行中运行 webpack):
mkdir webpack-democd webpack-demonpm init -ynpm install webpack webpack-cli --save-dev
在整个指南中,我们将使用diff
块,来展示对目录、文件和代码所做的修改。例如:
this is a new line you shall copy into your code and this is a line to be removed from your code and this is a line not to touch.
现在,我们将创建以下目录结构、文件和内容:
project
webpack-demo |- package.json |- package-lock.json |- index.html |- /src |- index.js
src/index.js
function component() { const element = document.createElement("div"); // lodash(目前通过一个 script 引入)对于执行这一行是必需的 element.innerHTML = _.join(["Hello", "webpack"], " "); return element;}document.body.appendChild(component());
index.html
起步 <script src="https://unpkg.com/lodash@4.17.20"></script> <script src="./src/index.js"></script>
我们还需要调整package.json
文件,以便确保我们安装包是private(私有的)
,并且移除main
入口。这可以防止意外发布你的代码。
package.json
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "MIT", "devDependencies": { "webpack": "^5.38.1", "webpack-cli": "^4.7.2" } }
在此示例中,<script>
标签之间存在隐式依赖关系。在index.js
文件执行之前,还需要在页面中先引入lodash
。这是因为index.js
并未显式声明它需要lodash
,假定推测已经存在一个全局变量_
。
使用这种方式去管理 JavaScript 项目会有一些问题:
无法直接体现,脚本的执行依赖于外部库。如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。让我们使用 webpack 来管理这些脚本。
创建一个 bundle首先,我们稍微调整下目录结构,创建分发代码(./dist
)文件夹用于存放分发代码,源代码(./src
)文件夹仍存放源代码。源代码是指用于书写和编辑的代码。分发代码是指在构建过程中,经过最小化和优化后产生的输出结果,最终将在浏览器中加载。调整后目录结构如下:
project
webpack-demo |- package.json |- package-lock.json |- /dist |- index.html |- index.html |- /src |- index.js
要在index.js
中打包lodash
依赖,我们需要在本地安装 library:
现在,在我们的 script 中 importlodash
:
src/index.js
import _ from "lodash"; function component() { const element = document.createElement("div"); // lodash(目前通过一个 script 引入)对于执行这一行是必需的 // lodash 在当前 script 中使用 import 引入 element.innerHTML = _.join(["Hello", "webpack"], " "); return element; } document.body.appendChild(component());
现在,我们将会打包所有脚本,我们必须更新index.html
文件。由于现在是通过import
引入 lodash,所以要将 lodash<script>
删除,然后修改另一个<script>
标签来加载 bundle,而不是原始的./src
文件:
dist/index.html
起步 <script src="https://unpkg.com/lodash@4.17.20"></script> <script src="./src/index.js"></script> <script src="main.js"></script>
在这个设置中,index.js
显式要求引入的lodash
必须存在,然后将它绑定为_
(没有全局作用域污染)。通过声明模块所需的依赖,webpack 能够利用这些信息去构建依赖图,然后使用图生成一个优化过的 bundle,并且会以正确顺序执行。
可以这样说,执行npx webpack
,会将我们的脚本src/index.js
作为入口起点,也会生成dist/main.js
作为输出。Node 8.2/npm 5.2.0 以上版本提供的npx
命令,可以运行在初次安装的 webpack package 中的 webpack 二进制文件(即./node_modules/.bin/webpack
):
$ npx webpack[webpack-cli] Compilation finishedasset main.js 69.3 KiB [emitted] [minimized] (name: main) 1 related assetruntime modules 1000 bytes 5 modulescacheable modules 530 KiB ./src/index.js 257 bytes [built] [code generated] ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]webpack 5.4.0 compiled successfully in 1851 ms
在浏览器中打开dist
目录下的index.html
,如果一切正常,你应该能看到以下文本:"Hello webpack"
。
ES2015中的import
和export
语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。
事实上,webpack 在幕后会将代码 “转译”,以便旧版本浏览器可以执行。如果你检查dist/main.js
,你可以看到 webpack 具体如何实现,这是独创精巧的设计!除了import
和export
,webpack 还能够很好地支持多种其他模块语法,更多信息请查看模块 API。
注意,webpack 不会更改代码中除import
和export
语句以外的部分。如果你在使用其它ES2015 特性,请确保你在 webpackloader 系统中使用了一个像是Babel的transpiler(转译器)。
在 webpack v4 中,可以无须任何配置,然而大多数项目会需要很复杂的设置,这就是为什么 webpack 仍然要支持配置文件。这比在 terminal(终端) 中手动输入大量命令要高效的多,所以让我们创建一个配置文件:
project
webpack-demo |- package.json |- package-lock.json |- webpack.config.js |- /dist |- index.html |- /src |- index.js
webpack.config.js
const path = require("path");module.exports = { entry: "./src/index.js", output: { filename: "main.js", path: path.resolve(__dirname, "dist"), },};
现在,让我们通过新的配置文件再次执行构建:
$ npx webpack --config webpack.config.js[webpack-cli] Compilation finishedasset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related assetruntime modules 1000 bytes 5 modulescacheable modules 530 KiB ./src/index.js 257 bytes [built] [code generated] ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]webpack 5.4.0 compiled successfully in 1934 ms
如果webpack.config.js
存在,则webpack
命令将默认选择使用它。我们在这里使用--config
选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用的。
比起 CLI 这种简单直接的使用方式,配置文件具有更多的灵活性。我们可以通过配置方式指定 loader 规则(loader rule)、plugin(插件)、resolve 选项,以及许多其他增强功能。更多详细信息请查看配置文档。
npm scripts考虑到用 CLI 这种方式来运行本地的 webpack 副本并不是特别方便,我们可以设置一个快捷方式。调整package.json文件,添加一个npm script:
package.json
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.4.0", "webpack-cli": "^4.2.0" }, "dependencies": { "lodash": "^4.17.20" } }
现在,可以使用npm run build
命令,来替代我们之前使用的npx
命令。注意,使用 npmscripts
,我们可以像使用npx
那样通过模块名引用本地安装的 npm packages。这是大多数基于 npm 的项目遵循的标准,因为它允许所有贡献者使用同一组通用脚本。
现在运行以下命令,然后看看你的脚本别名是否正常运行:
$ npm run build...[webpack-cli] Compilation finishedasset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related assetruntime modules 1000 bytes 5 modulescacheable modules 530 KiB ./src/index.js 257 bytes [built] [code generated] ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]webpack 5.4.0 compiled successfully in 1940 ms
可以通过在npm run build
命令与参数之间添加两个连接符的方式向 webpack 传递自定义参数,例如:npm run build -- --color
。
现在,你已经有了一个基础构建配置,你应该移至下一章节资源管理
指南,以了解如何通过 webpack 来管理资源,例如 images、fonts。此刻你的项目看起来应该如下:
project
webpack-demo|- package.json|- package-lock.json|- webpack.config.js|- /dist |- main.js |- index.html|- /src |- index.js|- /node_modules
不要使用 webpack 编译不可信的代码。它可能会在你的计算机,远程服务器或者在你 web 应用程序使用者的浏览器中执行恶意代码。
标签: