入门

Webpack 用于编译 JavaScript 模块。安装完成后,您可以通过其 CLI 或 API 与 webpack 交互。如果您仍然不熟悉 webpack,请阅读核心概念和此比较,了解为什么您可能选择使用它而不是社区中的其他工具。

基本设置

首先,让我们创建一个目录,初始化 npm,在本地安装 webpack,并安装 webpack-cli(用于在命令行上运行 webpack 的工具)

mkdir webpack-demo
cd webpack-demo
npm init -y
npm 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.

现在,我们将创建以下目录结构、文件及其内容

项目

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- index.html
+ |- /src
+   |- index.js

src/index.js

function component() {
  const element = document.createElement('div');

  // Lodash, currently included via a script, is required for this line to work
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Getting Started</title>
    <script src="https://unpkg.com/[email protected]"></script>
  </head>
  <body>
    <script src="./src/index.js"></script>
  </body>
</html>

我们还需要调整我们的 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 来管理这些脚本。

创建捆绑包

首先,我们将稍微调整一下我们的目录结构,将“源”代码 (./src) 与我们的“分发”代码 (./dist) 分开。“源”代码是我们编写和编辑的代码。“分发”代码是我们构建过程的最小化和优化的 output,最终将在浏览器中加载。请按如下方式调整目录结构

项目

  webpack-demo
  |- package.json
  |- package-lock.json
+ |- /dist
+   |- index.html
- |- index.html
  |- /src
    |- index.js

为了将 lodash 依赖项与 index.js 捆绑在一起,我们需要在本地安装该库

npm install --save lodash

现在,让我们在我们的脚本中导入 lodash

src/index.js

+import _ from 'lodash';
+
 function component() {
   const element = document.createElement('div');

-  // Lodash, currently included via a script, is required for this line to work
+  // Lodash, now imported by this script
   element.innerHTML = _.join(['Hello', 'webpack'], ' ');

   return element;
 }

 document.body.appendChild(component());

现在,由于我们将捆绑我们的脚本,我们必须更新我们的 index.html 文件。让我们删除 lodash <script>,因为我们现在 import 它,并修改另一个 <script> 标签以加载捆绑包,而不是原始的 ./src 文件

dist/index.html

 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="utf-8" />
     <title>Getting Started</title>
-    <script src="https://unpkg.com/[email protected]"></script>
   </head>
   <body>
-    <script src="./src/index.js"></script>
+    <script src="main.js"></script>
   </body>
 </html>

在这个设置中,index.js 明确要求 lodash 存在,并将其绑定为 _(不会污染全局作用域)。通过声明模块需要的依赖项,webpack 可以使用这些信息构建依赖关系图。然后,它使用该图生成一个优化的捆绑包,其中脚本将按正确的顺序执行。

话虽如此,让我们运行 npx webpack,它将把我们位于 src/index.js 的脚本作为 入口点,并将生成 dist/main.js 作为 输出npx 命令(随 Node 8.2/npm 5.2.0 或更高版本一起提供)运行我们之前安装的 webpack 包的 webpack 二进制文件 (./node_modules/.bin/webpack)

$ npx webpack
[webpack-cli] Compilation finished
asset main.js 69.3 KiB [emitted] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable 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'

模块

importexport 语句已在 ES2015 中标准化。它们目前在大多数浏览器中都受支持,但是有些浏览器不识别新语法。但不用担心,webpack 默认支持它们。

在幕后,webpack 实际上会“转译”代码,以便旧版浏览器也可以运行它。如果您检查 dist/main.js,您可能会看到 webpack 是如何做到的,这非常巧妙!除了 importexport 之外,webpack 还支持各种其他模块语法,有关更多信息,请参阅 模块 API

请注意,webpack 不会更改除importexport 语句之外的任何代码。如果您使用其他ES2015 功能,请确保使用转译器,例如通过 webpack 的加载器系统 使用Babel

使用配置

从版本 4 开始,webpack 不需要任何配置,但大多数项目都需要更复杂的设置,这就是 webpack 支持配置文件 的原因。这比在终端中手动输入大量命令要高效得多,所以让我们创建一个。

项目

  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 finished
asset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable 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

配置文件比 CLI 使用提供了更大的灵活性。我们可以通过这种方式指定加载器规则、插件、解析选项以及许多其他增强功能。请参阅配置文档 以了解更多信息。

NPM 脚本

鉴于从 CLI 运行 webpack 的本地副本并不特别有趣,我们可以设置一个简短的快捷方式。让我们通过添加一个npm 脚本 来调整我们的 package.json

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 命令。请注意,在 scripts 中,我们可以通过名称引用本地安装的 npm 包,就像我们使用 npx 一样。这种约定是大多数基于 npm 的项目的标准,因为它允许所有贡献者使用同一组通用脚本。

现在运行以下命令,看看您的脚本别名是否有效。

$ npm run build

...

[webpack-cli] Compilation finished
asset main.js 69.3 KiB [compared for emit] [minimized] (name: main) 1 related asset
runtime modules 1000 bytes 5 modules
cacheable 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

结论

现在您已经有了基本的构建,您应该继续下一个指南 资产管理 来学习如何使用 webpack 管理图像和字体等资产。此时,您的项目应该看起来像这样

项目

webpack-demo
|- package.json
|- package-lock.json
|- webpack.config.js
|- /dist
  |- main.js
  |- index.html
|- /src
  |- index.js
|- /node_modules

如果您想了解更多关于 webpack 设计的信息,您可以查看 基本概念配置 页面。此外,API 部分深入探讨了 webpack 提供的各种接口。

24 位贡献者

bebrawcntanglijunchrisVillanuevajohnstewsimon04aaronangTheDutchCodersudarsangpVanguard90chenxsanEugeneHlushkoATGardnerayvarotbjarkiztomaszeSpiral90210byzykwizardofhogwartsmyshovanshumanvd3lmsnitin315Etheryen