1

Development

This guide extends on code examples found in the Output Management guide.

       本指南的例子是基于上一个指南的。(≖ᴗ≖)✧

If you've been following the guides, you should have a solid understanding of some of the webpack basics. Before we continue, let's look into setting up a development environment to make our lives a little easier.

       如果你一直跟着我们的指南敲敲敲(=´ω`=),你现在应该对于webpack的基础有一个很扎实的理解了。在我们继续之前,让我们深入研究一下搭建开发环境,这可以使我们的生活不那么艰辛!(ノ´▽`)ノ♪

The tools in this guide are only meant for development, please avoid using them in production!!

       下面提到的工具,只能在开发时使用,请避免在产品中还用它们!

Using source maps (使用源地图)

When webpack bundles your source code, it can become difficult to track down errors and warnings to their original location. For example, if you bundle three source files (a.js, b.js, and c.js) into one bundle (bundle.js) and one of the source files contains an error, the stack trace will simply point to bundle.js. This isn't always helpful as you probably want to know exactly which source file the error came from.

       当webpack为你的源码打包时,它很难追踪出errorswarnings的源头。举个例子,如果你正在给三个源文件打包(a.js, b.js, 和 c.js),将它们打包到bundle.js,并且,其中一个文件中包含error,堆栈跟踪会将error简单指向bundle.js.这并不总是有用,因为您可能想知道错误来自哪个源文件(T▽T)

In order to make it easier to track down errors and warnings, JavaScript offers source maps, which maps your compiled code back to your original source code. If an error originates from b.js, the source map will tell you exactly that.

       为了更容易追踪错误和警告,JavaScript提供了源代码映射,将您编译的代码映射回原始源代码。如果一个错误源于b.js,源地图会告诉你这个事 。(o゚▽゚)o

There are a lot of different options available when it comes to source maps, be sure to check them out so you can configure them to your needs.

       源地图有很多不同的选项可供选择,一定要检查一下,以便将它们配置为您的需要。

For this guide, let's use the inline-source-map option, which is good for illustrative purposes (though not for production):

       对于本指南,让我们使用这个inline-source-map选项,这对于说明的目的是很好的(尽管不是用于生产环境):

webpack.config.js

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

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

Now let's make sure we have something to debug, so let's create an error in our print.js file:

       现在,让我们确定一下我们有一些需要debug的东西,来吧,我们给print.js整一个error(≖ᴗ≖)✧

src/print.js

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

Run an npm run build, it should compile to something like this:

       让我们运行npm run build,它应当会编译一些像这样的东西出来:

Hash: 7bf68ca15f1f2690e2d1
Version: webpack 3.1.0
Time: 1224ms
          Asset       Size  Chunks                    Chunk Names
  app.bundle.js    1.44 MB    0, 1  [emitted]  [big]  app
print.bundle.js    6.43 kB       1  [emitted]         print
     index.html  248 bytes          [emitted]
   [0] ./src/print.js 84 bytes {0} {1} [built]
   [1] ./src/index.js 403 bytes {0} [built]
   [3] (webpack)/buildin/global.js 509 bytes {0} [built]
   [4] (webpack)/buildin/module.js 517 bytes {0} [built]
    + 1 hidden module
Child html-webpack-plugin for "index.html":
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 2 hidden modules

Now open the resulting index.html file in your browser. Click the button and look in your console where the error is displayed. The error should say something like this:

       现在,我们在浏览器中打开最终生成的index.html。单击按钮,然后你就可以看到控制台上报了一个error,这个error应当是说了大概这样的内容:

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

We can see that the error also contains a reference to the file (print.js) and line number (2) where the error occurred. This is great, because now we know exactly where to look in order to fix the issue.

       我们能看到这个error也包含了对于print.js的引用,而且明确指出错误是出现在第二行的。这太给力了,这样一来,我们就能确切地知道什么地方出了问题然后修复它。

Choosing a Development Tool (选一件开发工具)

Some text editors have a "safe write" function that might interfere with some of the following tools. Read Adjusting Your text Editor for a solution to these issues.

       某些文本编辑器具有“安全写入”功能,可能会干扰以下某些工具。阅读调整您的文本编辑器以解决这些问题。(๑´ㅂ`๑)

It quickly becomes a hassle to manually run npm run build every time you want to compile your code.

       相信我,很快你就会感觉每次手动运行npm run build非常麻烦。ヽ(`Д´)ノ

There are a couple of different options available in webpack that help you automatically compile your code whenever it changes:

       webpack中有几个不同的选项可以帮助您在代码更改时自动编译代码:(❁´◡`❁)✲゚

  • webpack's Watch Mode (webpack监视模式)
  • webpack-dev-server (webpack开发服务)
  • webpack-dev-middleware (webpack开发中间件)

In most cases, you probably would want to use webpack-dev-server, but let's explore all of the above options.

       在大多数情况下,您可能会想要使用webpack-dev-server,但是我们来探索以上所有选项。

Using Watch Mode (使用webpack监视模式)

You can instruct webpack to "watch" all files within your dependency graph for changes. If one of these files is updated, the code will be recompiled so you don't have to run the full build manually.

       您可以指示webpack“监视”依赖关系图中的所有文件是否发生了更改。如果其中一个文件更新了,代码会自动重新编译,你不必再手动重新编译了。

Let's add an npm script that will start webpack's Watch Mode:

       让我们添加一个npm脚本,这样我们就可以开启webpack的监视模式了:

package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
+     "watch": "webpack --watch",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }

You can now run npm run watch from the command line to see that webpack compiles your code, but doesn't exit to the command line. This is because the script is still watching your files.

       现在,你可以在命令提示符下执行npm run watch来观察webpack编译你的代码的过程,但是请不要退出命令行。因为脚本还在运行着,它正在监视着你的文件。

Now, with webpack watching your files, let's remove the error we introduced earlier:

       现在,就让webpack一直监视着你的文件,让我们移除我们前面介绍到的error

src/print.js

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

Now save your file and check the terminal window. You should see that webpack automatically recompiles the changed module!

       现在,保存你的文件,查看你的命令行窗口,你应该会发现webpack正在自动重新编译发生改变的模块!((^∀^*))

The only downside is that you have to refresh your browser in order to see the changes. It would be much nicer if that would happen automatically as well, so let's try webpack-dev-server which will do exactly that.

       唯一会让你感到消极的是,你需要刷新一下浏览器才能看到改变。要是浏览器也能跟着自动刷新那就棒呆了,所以,让我们尝试一下能实现这个的webpack-dev-server吧!( ̄︶ ̄)↗

Using webpack-dev-server (使用webpack开发服务)

The webpack-dev-server provides you with a simple web server and the ability to use live reloading. Let's set it up:

       webpack-dev-server可以为你提供一个简单的web服务器,而且还可以使你的项目自动重加载,让我们来设置一下:

P.S.:live reloading我这里想翻译成自动重载,虽然在JavaWeb中已经有了热部署和热加载的概念。这里的自动重载有点像热加载,但是两个概念还是有区别的,所以我加以区分,望后端同学谅解。

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

Change your config file to tell the dev server where to look for files:

       修改你的配置文件以告诉dev server需要盯紧了哪些文件。 ̄ω ̄=

webpack.config.js

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

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

This tells webpack-dev-server to serve the files from the dist directory on localhost:8080.

       这个配置告诉webpack-dev-server部署dist目录下的文件到localhost:8080

Let's add a script to easily run the dev server as well:

       让我们添加一个脚本,使得dev server也能够轻松运行。 (ノ ̄▽ ̄)

package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --progress --watch",
+     "start": "webpack-dev-server --open",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }

Now we can run npm start from the command line and we will see our browser automatically loading up our page. If you now change any of the source files and save them, the web server will automatically reload after the code has been compiled. Give it a try!

       现在,我们可以在命令行中执行npm start,然后我们就可以看到我们的浏览器自动加载我们的页面。如果你修改了任何一个源文件并且保存了,web服务器都将自动地重加载编译后的代码。赶紧试试吧!

The webpack-dev-server comes with many configurable options. Head over to the documentation to learn more.

       webpack-dev-server带有许多配置选项。转到文档了解更多。

Now that your server is working, you might want to give Hot Module Replacement a try!

       现在,你的服务器工作起来了,你也许希望尝试一下热模块替换

Using webpack-dev-middleware (使用webpack开发中间件)

webpack-dev-middleware is a wrapper that will emit files processed by webpack to a server. This is used in webpack-dev-server internally, however it's available as a separate package to allow more custom setups if desired. We'll take a look at an example that combines webpack-dev-middleware with an express server.

       webpack-dev-middleware是一个将webpack处理后的文件发送到服务器的包装器。它在webpack-dev-server的内部被使用,然而,当你有更多需要自定义的设置的时,它也能被单独使用。让我们来看一个包含webpack-dev-middlewareexpress服务器的例子。

Let's install express and webpack-dev-middleware so we can get started:

让我们先安装一下expresswebpack-dev-middleware,让我们能够开始下面的例子。

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

Now we need to make some adjustments to our webpack configuration file in order to make sure the middleware will function correctly:

       现在我们需要对我们的webpack配置文件做一些调整,以确认我们的中间件功能正常。

webpack.config.js

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

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    devtool: 'inline-source-map',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Output Management'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
+     publicPath: '/'
    }
  };

The publicPath will be used within our server script as well in order to make sure files are served correctly on http://localhost:3000, the port number we'll specify later. The next step is setting up our custom express server:

       为了确认有哪些文件将被正确部署到http://localhost:3000,publicPath也会被我们的服务脚本所使用。端口号我们会稍后定义。下一步,我们定制化一下我们的express服务器:

project

  webpack-demo
  |- package.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');
});

Now add an npm script to make it a little easier to run the server:

       现在,让我们添加一个npm脚本,让它更便捷地运行在服务器上。

package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --progress --watch",
      "start": "webpack-dev-server --open",
+     "server": "node server.js",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "webpack-dev-middleware": "^1.12.0",
      "xml-loader": "^1.2.1"
    }
  }

Now in your terminal run npm run server, it should give you an output similar to this:

       现在,在你的终端执行npm run server,它应当给你一个类似于这样的输出:

Example app listening on port 3000!
webpack built 27b137af6d9d8668c373 in 1198ms
Hash: 27b137af6d9d8668c373
Version: webpack 3.0.0
Time: 1198ms
          Asset       Size  Chunks                    Chunk Names
  app.bundle.js    1.44 MB    0, 1  [emitted]  [big]  app
print.bundle.js    6.57 kB       1  [emitted]         print
     index.html  306 bytes          [emitted]
   [0] ./src/print.js 116 bytes {0} {1} [built]
   [1] ./src/index.js 403 bytes {0} [built]
   [2] ./node_modules/lodash/lodash.js 540 kB {0} [built]
   [3] (webpack)/buildin/global.js 509 bytes {0} [built]
   [4] (webpack)/buildin/module.js 517 bytes {0} [built]
Child html-webpack-plugin for "index.html":
         Asset    Size  Chunks  Chunk Names
    index.html  544 kB       0
       [0] ./node_modules/html-webpack-plugin/lib/loader.js!./node_modules/html-webpack-plugin/default_index.ejs 538 bytes {0} [built]
       [1] ./node_modules/lodash/lodash.js 540 kB {0} [built]
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
webpack: Compiled successfully.

Now fire up your browser and go to http://localhost:3000, you should see your webpack app running and functioning!

       现在,打开浏览器,访问http://localhost:3000,你应当看到你的wepback应用正在运行和发挥作用!ヽ(゚∀゚)メ(゚∀゚)ノ

If you would like to know more about how Hot Module Replacement works, we recommend you read the Hot Module Replacement guide.

       如果你对于模块热重置如何工作很感兴趣,我们推荐你阅读Hot Module Replacement guide

Adjusting Your Text Editor

When using automatic compilation of your code, you could run into issues when saving your files. Some editors have a "safe write" feature that can potentially interfere with recompilation.

       当你正在使用代码自动补全的时候,你可能会在保存文件时陷入麻烦。有一些编辑器有“安全写入”的特性,啥意思呢?它会潜在地扰乱重新编译。

To disable this feature in some common editors, see the list below:

       如果想在一些普通的编辑器中关闭这个特性,看看下面这个列表吧:

  • Sublime Text 3 - 添加 atomic_save: "false" 到你的用户偏好.
  • IntelliJ - 在偏好中找到 safe write ,然后使之失效.
  • Vim - 在设置中添加backupcopy=yes.
  • WebStorm - 在 Preferences > Appearance & Behavior > System Settings取消选中safe write.

Conclusion (总结)

Now that you've learned how to automatically compile your code and run a simple development server, you can check out the next guide, which will cover Hot Module Replacement.

现在,你已经学到了如歌自动编译你的代码,运行在一个简单的开发服务器上了。捏可以看看下个指南,它会讲一下模块热重置

P.S.:到了这里,我们使用webpack进行开发已经不存在很大的问题了。只是我们应该一鼓作气|●´∀`|σ,继续探索一下更加深入的内容。


hengbao
22 声望2 粉丝

消极的心态限制潜能发挥