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進行開發已經不存在很大的問題了。只是咱們應該一氣呵成|●´∀`|σ,繼續探索一下更加深刻的內容。