This guide extends on code examples found in the Output Management guide.css
本指南的例子是基于上一个指南的。(≖ᴗ≖)✧html
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.node
若是你一直跟着咱们的指南敲敲敲(=´ω`=),你如今应该对于webpack的基础有一个很扎实的理解了。在咱们继续以前,让咱们深刻研究一下搭建开发环境,这可使咱们的生活不那么艰辛!(ノ´▽`)ノ♪webpack
The tools in this guide are only meant for development, please avoid using them in production!!web
下面提到的工具,只能在开发时使用,请避免在产品中还用它们!express
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.npm
当webpack为你的源码打包时,它很难追踪出errors
和warnings
的源头。举个例子,若是你正在给三个源文件打包(a.js
, b.js
, 和 c.js
),将它们打包到bundle.js
,而且,其中一个文件中包含error
,堆栈跟踪会将error
简单指向bundle.js
.这并不老是有用,由于您可能想知道错误来自哪一个源文件(T▽T)。json
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
选项,这对于说明的目的是很好的(尽管不是用于生产环境):
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
。(≖ᴗ≖)✧
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
的引用,并且明确指出错误是出如今第二行的。这太给力了,这样一来,咱们就能确切地知道什么地方出了问题而后修复它。
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中有几个不一样的选项能够帮助您在代码更改时自动编译代码:(❁´◡`❁)✲゚
In most cases, you probably would want to use webpack-dev-server, but let's explore all of the above options.
在大多数状况下,您可能会想要使用webpack-dev-server
,可是咱们来探索以上全部选项。
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的监视模式了:
{ "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
。
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
吧!( ̄︶ ̄)↗
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
须要盯紧了哪些文件。 ̄ω ̄=
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
也可以轻松运行。 (ノ ̄▽ ̄)
{ "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!
如今,你的服务器工做起来了,你也许但愿尝试一下热模块替换
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-middleware
和express
服务器的例子。
Let's install express and webpack-dev-middleware so we can get started:
让咱们先安装一下express
和webpack-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配置文件作一些调整,以确认咱们的中间件功能正常。
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
服务器:
webpack-demo |- package.json |- webpack.config.js + |- server.js |- /dist |- /src |- index.js |- print.js |- /node_modules
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
脚本,让它更便捷地运行在服务器上。
{ "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。
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:
若是想在一些普通的编辑器中关闭这个特性,看看下面这个列表吧:
atomic_save: "false"
到你的用户偏好.safe write
,而后使之失效.backupcopy=yes
.safe write
.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进行开发已经不存在很大的问题了。只是咱们应该一气呵成|●´∀`|σ,继续探索一下更加深刻的内容。