开发:
ps:本指南中的工具仅用于开发环境,请不要在生产环境中使用。
先设置一下模式:
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = {+ mode: 'development', 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') } };
使用source-map:
使用webpack打包资源后,追踪到错误和警告在源代码中的位置有时候会变得比较困难。比如你把a.js、b.js、c.js打包成了bundle.js,如果某个源文件报错了,那堆栈跟踪只会指向bundle.js。为了更好地追踪错误和警告,js提供了source maps,会把编译后的代码映射回源代码,以以上例子为例,如果a.js报错了source maps就会准确地告诉你是它报错了。source maps有很多的选项可用,最好仔细地阅读一下这些配置以便按需配置。本指南里我们使用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') } };
在print.js中造一个错误:
src/print.js
export default function printMe() {- console.log('I get called from print.js!');+ cosnole.error('I get called from print.js!'); }
跑起来:
Hash: 7bf68ca15f1f2690e2d1Version: webpack 3.1.0Time: 1224ms Asset Size Chunks Chunk Names app.bundle.js 1.44 MB 0, 1 [emitted] [big] appprint.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 moduleChild 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
在浏览器打开index.html,点击按钮可以看到如下输出:
Uncaught ReferenceError: cosnole is not defined at HTMLButtonElement.printMe (print.js:2)
它会打印出错误信息和文件及位置,可以说非常好用了。
选择一个开发工具:
ps:一些文本编辑器具有“安全写入”功能,可能会干扰以下某些工具。阅读官方的调整文本编辑器以解决这些问题。
每次编译代码时手动运行npm run build会很麻烦,webpack里有几个选项可以帮助你在代码发生变化后自动编译代码:
- webpack's Watch Mode
- webpack-dev-server
- webpack-dev-middleware
大多数情况下你会倾向于使用webpack-dev-server,但是了解所有选项也是非常有必要的。
使用观察模式:
你可以指示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" } }
现在用npm run watch来看看这个模式怎么编译的,你会看到编译码,但是命令行不会退出了,因为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'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { mode: 'development', 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') } };
这样配置就等于告诉webpack-dev-server在localhost:8080下建立服务,并且去dist文件夹下查找文件。再加个脚本快捷运行服务:
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",+ "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" } }
ps:webpack-dev-server编译后不会产生任何输出文件,它只会保存打包后的存在于内存中的文件,并且会把它们当成挂载在服务器根目录下的真实文件。如果你的页面需要在别的目录下查找到打包后的文件,可以通过配置dev server的publicPath选项。
现在运行npm start的话浏览器就会自动加载页面了,而且你对某些文件做出改动并保存的话浏览器也会自动刷新。
使用webpack-dev-middleware:
webpack-dev-middleware会把webpack处理后的文件发送给一个服务器。webpack-dev-server内部也使用了它,为了满足一些自定义启动需求它也可以作为一个单独的包来使用,下面来看一个webpack-dev-middleware结合express服务器的例子。
首先安装:
npm install --save-dev express webpack-dev-middleware
针对webpack-dev-middleware做一些配置改动:
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { mode: 'development', entry: { app: './src/index.js', print: './src/print.js' }, devtool: 'inline-source-map', devServer: { contentBase: './dist' }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Output Management' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'),+ publicPath: '/' } };
publicPath会在服务器脚本中用到来确保资源文件能在http://localhost:3000下正确访问,端口号我们之后再设置,先来配置一下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');});
来配置一下快捷启动脚本:
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", "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" } }
现在运行npm run server你应该可以看到如下输出:
Example app listening on port 3000!... Asset Size Chunks Chunk Names app.bundle.js 1.44 MB 0, 1 [emitted] [big] appprint.bundle.js 6.57 kB 1 [emitted] print index.html 306 bytes [emitted]...webpack: Compiled successfully.
打开浏览器前往http://localhost:3000就可以看到项目正常运行了。
调整编辑器:
使用自动编译代码功能的时候可能会在保存文件的时候遇到一些问题,有些编辑器有"安全写入"功能可能会影响重新编译,以下是禁用一些浏览器这个功能的方法:
- Sublime Text 3 - 在用户首选项(user preferences)中添加
atomic_save: "false"
。 - IntelliJ - 在首选项(preferences)中使用搜索,查找到 "safe write" 并且禁用它。
- Vim - 在设置(settings)中增加
:set backupcopy=yes
。 - WebStorm - 在
Preferences > Appearance & Behavior > System Settings
中取消选中 Use"safe write"
。