开发环境

    如果你一直跟随之前的指南,应该对一些 webpack 基础知识有着很扎实的理解。在我们继续之前,先来看看如何设置一个开发环境,使我们的开发体验变得更轻松一些。

    本指南中的工具仅用于开发环境,请不要在生产环境中使用它们!

    在开始前,我们先将 设置为 'development'

    webpack.config.js

    当 webpack 打包源代码时,可能会很难追踪到 error(错误) 和 warning(警告) 在源代码中的原始位置。例如,如果将三个源文件(a.js, b.jsc.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会直接指向到 bundle.js。你可能需要准确地知道错误来自于哪个源文件,所以这种提示这通常不会提供太多帮助。

    为了更容易地追踪 error 和 warning,JavaScript 提供了 功能,可以将编译后的代码映射回原始源代码。如果一个错误来自于 b.js,source map 就会明确的告诉你。

    source map 有许多 可用选项,请务必仔细阅读它们,以便可以根据需要进行配置。

    对于本指南,我们将使用 inline-source-map 选项,这有助于解释说明示例意图(此配置仅用于示例,不要用于生产环境):

    webpack.config.js

    1. const path = require('path');
    2. const HtmlWebpackPlugin = require('html-webpack-plugin');
    3. const CleanWebpackPlugin = require('clean-webpack-plugin');
    4. module.exports = {
    5. mode: 'development',
    6. entry: {
    7. app: './src/index.js',
    8. print: './src/print.js'
    9. },
    10. + devtool: 'inline-source-map',
    11. plugins: [
    12. new CleanWebpackPlugin(['dist']),
    13. new HtmlWebpackPlugin({
    14. title: 'Development'
    15. })
    16. ],
    17. output: {
    18. filename: '[name].bundle.js',
    19. path: path.resolve(__dirname, 'dist')
    20. }
    21. };

    现在,让我们来做一些调试,在 print.js 文件中生成一个错误:

    src/print.js

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

    运行 npm run build,编译如下:

    1. ...
    2. Asset Size Chunks Chunk Names
    3. app.bundle.js 1.44 MB 0, 1 [emitted] [big] app
    4. print.bundle.js 6.43 kB 1 [emitted] print
    5. index.html 248 bytes [emitted]
    6. ...

    现在,在浏览器中打开生成的 index.html 文件,点击按钮,并且在控制台查看显示的错误。错误应该如下:

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

    我们可以看到,此错误包含有发生错误的文件(print.js)和行号(2)的引用。这是非常有帮助的,因为现在我们可以确切地知道,所要解决问题的位置。

    在每次编译代码时,手动运行 npm run build 会显得很麻烦。

    webpack 提供几种可选方式,帮助你在代码发生变化后自动编译代码:

    多数场景中,你可能需要使用 webpack-dev-server,但是不妨探讨一下以上的所有选项。

    你可以指示 webpack “watch” 依赖图中所有文件的更改。如果其中一个文件被更新,代码将被重新编译,所以你不必再去手动运行整个构建。

    我们添加一个用于启动 webpack watch mode 的 npm scripts:

    package.json

    现在,你可以在命令行中运行 npm run watch,然后就会看到 webpack 是如何编译代码。 然而,你会发现并没有退出命令行。这是因为此 script 当前还在 watch 你的文件。

    现在,webpack 观察文件的同时,先移除我们之前加入的错误:

    src/print.js

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

    现在,保存文件并检查 terminal(终端) 窗口。应该可以看到 webpack 自动地重新编译修改后的模块!

    唯一的缺点是,为了看到修改后的实际效果,你需要刷新浏览器。如果能够自动刷新浏览器就更好了,因此接下来我们会尝试通过 webpack-dev-server 实现此功能。

    webpack-dev-server 为你提供了一个简单的 web server,并且具有 live reloading(实时重新加载) 功能。设置如下:

    1. npm install --save-dev webpack-dev-server

    修改配置文件,告诉 dev server,从什么位置查找文件:

    webpack.config.js

    1. const path = require('path');
    2. const HtmlWebpackPlugin = require('html-webpack-plugin');
    3. const CleanWebpackPlugin = require('clean-webpack-plugin');
    4. module.exports = {
    5. mode: 'development',
    6. entry: {
    7. app: './src/index.js',
    8. print: './src/print.js'
    9. },
    10. devtool: 'inline-source-map',
    11. + },
    12. plugins: [
    13. new CleanWebpackPlugin(['dist']),
    14. new HtmlWebpackPlugin({
    15. title: 'Development'
    16. })
    17. ],
    18. output: {
    19. filename: '[name].bundle.js',
    20. path: path.resolve(__dirname, 'dist')
    21. }
    22. };

    以上配置告知 webpack-dev-server,将 dist 目录下的文件 serve 到 localhost:8080 下。(译注:serve,将资源作为 server 的可访问文件)

    webpack-dev-server 在编译之后不会写入到任何输出文件。而是将 bundle 文件保留在内存中,然后将它们 serve 到 server 中,就好像它们是挂载在 server 根路径上的真实文件一样。如果你的页面希望在其他不同路径中找到 bundle 文件,则可以通过 dev server 配置中的 选项进行修改。

    我们添加一个可以直接运行 dev server 的 script:

    package.json

    1. {
    2. "name": "development",
    3. "version": "1.0.0",
    4. "description": "",
    5. "main": "webpack.config.js",
    6. "scripts": {
    7. "test": "echo \"Error: no test specified\" && exit 1",
    8. "watch": "webpack --watch",
    9. + "start": "webpack-dev-server --open",
    10. "build": "webpack"
    11. },
    12. "keywords": [],
    13. "author": "",
    14. "license": "ISC",
    15. "devDependencies": {
    16. "clean-webpack-plugin": "^0.1.16",
    17. "css-loader": "^0.28.4",
    18. "csv-loader": "^2.1.1",
    19. "file-loader": "^0.11.2",
    20. "html-webpack-plugin": "^2.29.0",
    21. "style-loader": "^0.18.2",
    22. "webpack": "^3.0.0",
    23. "xml-loader": "^1.2.1"
    24. }
    25. }

    现在,在命令行中运行 npm start,我们会看到浏览器自动加载页面。如果你更改任何源文件并保存它们,web server 将在编译代码后自动重新加载。试试看!

    webpack-dev-middleware 是一个封装器(wrapper),它可以把 webpack 处理过的文件发送到一个 server。 webpack-dev-server 在内部使用了它,然而它也可以作为一个单独的 package 来使用,以便根据需求进行更多自定义设置。下面是一个 webpack-dev-middleware 配合 express server 的示例。

    首先,安装 expresswebpack-dev-middleware

    现在,我们需要调整 webpack 配置文件,以确保 middleware(中间件) 功能能够正确启用:

    webpack.config.js

    1. const path = require('path');
    2. const HtmlWebpackPlugin = require('html-webpack-plugin');
    3. const CleanWebpackPlugin = require('clean-webpack-plugin');
    4. module.exports = {
    5. mode: 'development',
    6. entry: {
    7. app: './src/index.js',
    8. print: './src/print.js'
    9. },
    10. devtool: 'inline-source-map',
    11. devServer: {
    12. contentBase: './dist'
    13. },
    14. plugins: [
    15. new CleanWebpackPlugin(['dist']),
    16. new HtmlWebpackPlugin({
    17. title: '管理输出'
    18. })
    19. output: {
    20. filename: '[name].bundle.js',
    21. + publicPath: '/'
    22. }
    23. };

    我们将会在 server 脚本使用 publicPath,以确保文件资源能够正确地 serve 在 http://localhost:3000 下,稍后我们会指定 port number(端口号)。接下来是设置自定义 express server:

    project

    1. webpack-demo
    2. |- package.json
    3. |- webpack.config.js
    4. + |- server.js
    5. |- /dist
    6. |- /src
    7. |- index.js
    8. |- print.js
    9. |- /node_modules

    server.js

    1. const express = require('express');
    2. const webpack = require('webpack');
    3. const webpackDevMiddleware = require('webpack-dev-middleware');
    4. const app = express();
    5. const config = require('./webpack.config.js');
    6. const compiler = webpack(config);
    7. // 告诉 express 使用 webpack-dev-middleware,
    8. // 以及将 webpack.config.js 配置文件作为基础配置
    9. app.use(webpackDevMiddleware(compiler, {
    10. publicPath: config.output.publicPath
    11. }));
    12. // 将文件 serve 到 port 3000。
    13. app.listen(3000, function () {
    14. console.log('Example app listening on port 3000!\n');
    15. });

    现在,添加一个 npm script,以使我们更方便地运行服务:

    package.json

    1. {
    2. "name": "development",
    3. "version": "1.0.0",
    4. "description": "",
    5. "main": "webpack.config.js",
    6. "scripts": {
    7. "test": "echo \"Error: no test specified\" && exit 1",
    8. "watch": "webpack --watch",
    9. "start": "webpack-dev-server --open",
    10. + "server": "node server.js",
    11. "build": "webpack"
    12. },
    13. "keywords": [],
    14. "author": "",
    15. "license": "ISC",
    16. "devDependencies": {
    17. "clean-webpack-plugin": "^0.1.16",
    18. "css-loader": "^0.28.4",
    19. "csv-loader": "^2.1.1",
    20. "express": "^4.15.3",
    21. "file-loader": "^0.11.2",
    22. "html-webpack-plugin": "^2.29.0",
    23. "style-loader": "^0.18.2",
    24. "webpack": "^3.0.0",
    25. "webpack-dev-middleware": "^1.12.0",
    26. "xml-loader": "^1.2.1"
    27. }
    28. }

    现在,在 terminal(终端) 中执行 npm run server,将会有类似如下信息输出:

    现在,打开浏览器,访问 http://localhost:3000。应该看到webpack 应用程序已经运行!

    如果想要了解更多关于模块热替换(hot module replacement)的运行机制,我们推荐你查看 模块热替换(hot module replacement) 指南。

    使用自动编译代码时,可能会在保存文件时遇到一些问题。某些编辑器具有 “safe write(安全写入)” 功能,会影响重新编译。

    在一些常见的编辑器中禁用此功能,查看以下列表:

    • Sublime Text 3:在用户首选项(user preferences)中添加 atomic_save: 'false'
    • Vim:在设置(settings)中增加 :set backupcopy=yes

    现在,你已经学会了如何自动编译代码,并运行一个简单的 development server,查看下一个指南,其中将介绍 。


    Calinou GAumala TheDutchCoder byzyk rafde