开发

如果您一直在关注这些指南,您应该对一些 webpack 基础知识有深入的了解。在我们继续之前,让我们看看如何设置一个开发环境,让我们的生活更轻松。

让我们从将 mode 设置为 'development' 以及将 title 设置为 'Development' 开始。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
+  mode: 'development',
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   plugins: [
     new HtmlWebpackPlugin({
-      title: 'Output Management',
+      title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
 };

使用源映射

当 webpack 打包您的源代码时,追踪错误和警告到其原始位置可能会变得很困难。例如,如果您将三个源文件(a.jsb.jsc.js)打包成一个捆绑包(bundle.js),并且其中一个源文件包含错误,则堆栈跟踪将指向 bundle.js。这并不总是很有帮助,因为您可能想知道错误来自哪个确切的源文件。

为了更轻松地追踪错误和警告,JavaScript 提供了 源映射,它将您的编译代码映射回您的原始源代码。如果错误源自 b.js,源映射将准确地告诉您这一点。

在源映射方面,有很多 不同的选项 可供选择。请务必查看它们,以便您可以根据需要进行配置。

对于本指南,让我们使用 inline-source-map 选项,它非常适合说明目的(尽管不适合生产环境)。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   mode: 'development',
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
+  devtool: 'inline-source-map',
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
 };

现在让我们确保我们有一些东西可以调试,所以让我们在 print.js 文件中创建一个错误。

src/print.js

 export default function printMe() {
-  console.log('I get called from print.js!');
+  cosnole.log('I get called from print.js!');
 }

运行 npm run build,它应该编译成类似这样的内容

...
[webpack-cli] Compilation finished
asset index.bundle.js 1.38 MiB [emitted] (name: index)
asset print.bundle.js 6.25 KiB [emitted] (name: print)
asset index.html 272 bytes [emitted]
runtime modules 1.9 KiB 9 modules
cacheable modules 530 KiB
  ./src/index.js 406 bytes [built] [code generated]
  ./src/print.js 83 bytes [built] [code generated]
  ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
webpack 5.4.0 compiled successfully in 706 ms

现在在浏览器中打开生成的 index.html 文件。点击按钮,查看控制台,错误信息应该显示在那里。错误信息应该类似于以下内容

Uncaught ReferenceError: cosnole is not defined
   at HTMLButtonElement.printMe (print.js:2)

我们可以看到,错误信息还包含对文件 (print.js) 和错误发生的行号 (2) 的引用。这很棒,因为现在我们确切地知道在哪里查找以解决问题。

选择开发工具

每次想要编译代码时手动运行 npm run build 会变得很麻烦。

Webpack 中提供了一些不同的选项,可以帮助您在代码发生更改时自动编译代码

  1. Webpack 的 观察模式
  2. Webpack-dev-server
  3. Webpack-dev-middleware

在大多数情况下,您可能希望使用 webpack-dev-server,但让我们探索以上所有选项。

使用观察模式

您可以指示 Webpack “观察”依赖关系图中所有文件的更改。如果其中一个文件更新,代码将重新编译,因此您无需手动运行完整的构建。

让我们添加一个 npm 脚本,它将启动 Webpack 的观察模式

package.json

 {
   "name": "webpack-demo",
   "version": "1.0.0",
   "description": "",
   "private": true,
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
+    "watch": "webpack --watch",
     "build": "webpack"
   },
   "keywords": [],
   "author": "",
   "license": "ISC",
   "devDependencies": {
     "html-webpack-plugin": "^4.5.0",
     "webpack": "^5.4.0",
     "webpack-cli": "^4.2.0"
   },
   "dependencies": {
     "lodash": "^4.17.20"
   }
 }

现在从命令行运行 npm run watch,看看 Webpack 如何编译您的代码。您可以看到它没有退出命令行,因为脚本目前正在观察您的文件。

现在,在 Webpack 观察您的文件时,让我们删除之前引入的错误

src/print.js

 export default function printMe() {
-  cosnole.log('I get called from print.js!');
+  console.log('I get called from print.js!');
 }

现在保存您的文件并检查终端窗口。您应该看到 Webpack 自动重新编译了更改的模块!

唯一的缺点是您必须刷新浏览器才能看到更改。如果可以自动发生,那就太好了,所以让我们尝试一下 `webpack-dev-server`,它会做到这一点。

使用 webpack-dev-server

webpack-dev-server 为您提供了一个基本的 Web 服务器和使用实时重新加载的功能。让我们开始设置它。

npm install --save-dev webpack-dev-server

更改您的配置文件以告诉开发服务器在哪里查找文件。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   mode: 'development',
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   devtool: 'inline-source-map',
+  devServer: {
+    static: './dist',
+  },
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
+  optimization: {
+    runtimeChunk: 'single',
+  },
 };

这告诉 `webpack-dev-server` 从 `dist` 目录中的 `localhost:8080` 上提供文件。

让我们添加一个脚本以轻松运行开发服务器。

package.json

 {
   "name": "webpack-demo",
   "version": "1.0.0",
   "description": "",
   "private": true,
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
     "watch": "webpack --watch",
+    "start": "webpack serve --open",
     "build": "webpack"
   },
   "keywords": [],
   "author": "",
   "license": "ISC",
   "devDependencies": {
     "html-webpack-plugin": "^4.5.0",
     "webpack": "^5.4.0",
     "webpack-cli": "^4.2.0",
     "webpack-dev-server": "^3.11.0"
   },
   "dependencies": {
     "lodash": "^4.17.20"
   }
 }

现在,我们可以从命令行运行 `npm start`,然后我们会看到我们的浏览器自动加载我们的页面。如果您现在更改任何源文件并保存它们,Web 服务器将在代码编译后自动重新加载。试试看!

webpack-dev-server 带有许多可配置选项。请前往 文档 了解更多信息。

使用 webpack-dev-middleware

webpack-dev-middleware 是一个包装器,它将由 webpack 处理的文件发出到服务器。这在 `webpack-dev-server` 内部使用,但它作为一个单独的包可用,以便在需要时允许更自定义的设置。我们将看一下将 `webpack-dev-middleware` 与 express 服务器结合使用的示例。

让我们安装 `express` 和 `webpack-dev-middleware`,以便开始。

npm install --save-dev express webpack-dev-middleware

现在我们需要对我们的 webpack 配置文件进行一些调整,以确保中间件能够正常工作。

webpack.config.js

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
   mode: 'development',
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   devtool: 'inline-source-map',
   devServer: {
     static: './dist',
   },
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
+    publicPath: '/',
   },
 };

publicPath 将在我们的服务器脚本中使用,以确保文件在 `http://localhost:3000` 上正确提供服务。我们稍后将指定端口号。下一步是设置我们的自定义 `express` 服务器。

项目

  webpack-demo
  |- package.json
  |- package-lock.json
  |- webpack.config.js
+ |- server.js
  |- /dist
  |- /src
    |- index.js
    |- print.js
  |- /node_modules

server.js

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
  webpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});

现在添加一个 npm 脚本,使运行服务器更加容易。

package.json

 {
   "name": "webpack-demo",
   "version": "1.0.0",
   "description": "",
   "private": true,
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
     "watch": "webpack --watch",
     "start": "webpack serve --open",
+    "server": "node server.js",
     "build": "webpack"
   },
   "keywords": [],
   "author": "",
   "license": "ISC",
   "devDependencies": {
     "express": "^4.17.1",
     "html-webpack-plugin": "^4.5.0",
     "webpack": "^5.4.0",
     "webpack-cli": "^4.2.0",
     "webpack-dev-middleware": "^4.0.2",
     "webpack-dev-server": "^3.11.0"
   },
   "dependencies": {
     "lodash": "^4.17.20"
   }
 }

现在在您的终端中运行 `npm run server`,它应该给您类似于此的输出。

Example app listening on port 3000!
...
<i> [webpack-dev-middleware] asset index.bundle.js 1.38 MiB [emitted] (name: index)
<i> asset print.bundle.js 6.25 KiB [emitted] (name: print)
<i> asset index.html 274 bytes [emitted]
<i> runtime modules 1.9 KiB 9 modules
<i> cacheable modules 530 KiB
<i>   ./src/index.js 406 bytes [built] [code generated]
<i>   ./src/print.js 83 bytes [built] [code generated]
<i>   ./node_modules/lodash/lodash.js 530 KiB [built] [code generated]
<i> webpack 5.4.0 compiled successfully in 709 ms
<i> [webpack-dev-middleware] Compiled successfully.
<i> [webpack-dev-middleware] Compiling...
<i> [webpack-dev-middleware] assets by status 1.38 MiB [cached] 2 assets
<i> cached modules 530 KiB (javascript) 1.9 KiB (runtime) [cached] 12 modules
<i> webpack 5.4.0 compiled successfully in 19 ms
<i> [webpack-dev-middleware] Compiled successfully.

现在启动您的浏览器并访问 `http://localhost:3000`。您应该看到您的 webpack 应用程序正在运行并正常工作!

调整您的文本编辑器

当使用自动编译您的代码时,您可能会在保存文件时遇到问题。一些编辑器具有“安全写入”功能,这可能会干扰重新编译。

要禁用一些常用编辑器中的此功能,请参阅以下列表。

  • Sublime Text 3:将 `atomic_save: 'false'` 添加到您的用户首选项中。
  • JetBrains IDEs(例如 WebStorm):在 `Preferences > Appearance & Behavior > System Settings` 中取消选中“使用安全写入”。
  • Vim:将 `:set backupcopy=yes` 添加到您的设置中。

结论

现在您已经了解了如何自动编译您的代码并运行开发服务器,您可以查看下一份指南,其中将介绍 代码拆分

15 位贡献者

SpaceK33zrafdefvgsTheDutchCoderWojciechKoCalinouGAumalaEugeneHlushkobyzyktrivikraholznerchenxsansnitin315f3ndot