背景
在我们的开发中,很多的代码会频繁的变动,如果每次改动都使用npm run build
来打包的话,是一件效率很低的事情,而且这个服务,一般来说,打包的时候,才需要使用,因此需要一个本地服务的,可以快捷的看到打包后的内容
方案
webpack为这种情况,提供了观察者模式,在每次文件发生变动的时候,自动执行编译,就不用每次都npm run build
来打包了
写法
watch 自动编译修改的文件
我们可以在scripts
中,新加一条命令webpack --watch
来启动观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| //package.json { "dependencies": { "babel-loader": "^8.0.6", "copy-webpack-plugin": "^5.1.1", "webpack": "^4.41.5", "webpack-cli": "^3.3.10" }, "name": "webpack_learn", "version": "1.0.0", "main": "index.js", "devDependencies": { "@babel/core": "^7.7.7", "@babel/preset-env": "^7.7.7", "babel-core": "^6.26.3", "babel-preset-env": "^1.7.0" }, "scripts": { "build": "webpack", + "watch": "webpack --watch", "dev": "webpack --mode development", "product": "webpack --mode production", "testParams": "webpack --mode production --env.production product --param1 1 --param2 2 --explane 这是一个说明", "showColorAndProgress": "webpack --progress --colors", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "description": "" }
|
然后在命令行中执行
1
| npm run watch #也可以yarn watch
|
然后我们在浏览器中,打开刚才的文件,并且查看控制台,控制台中打印了大家好,我的名字是小明
,然后我们修改一下/src/let.js
,及index.html
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| //let.js - let name = '小明'; + let name = '小刚; module.exports = name; //index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> - <script src="./main.js" type="text/javascript" charset="utf-8"></script> + <script src="./bundle.js" type="text/javascript" charset="utf-8"></script> </body> </html>
|
然后保存文件,然后在刚打开的浏览器里,刷新页面,然后控制台中,变成了大家好,我的名字是小刚
。这样,每次修改就不用执行打包指令了
sourceMap 查找报错所在
开发中,最重要的一个环节,就是代码的调试,如果我们在写的代码中,出现了报错,希望很快的知道是哪里的报错,但是在webpack中,代码经过层层的模块打包,合并成了最后的一个js文件,里面的内容是编译后的内容,
我们尝试一下报错,将刚刚的get.js
中,加一个报错信息。
1 2 3 4 5
| //get.js module.exports = function(name){ console.log(name) + throw new Error('这里有个报错') };
|
1 2 3 4 5 6
| bundle.js:1 Uncaught Error: 这里有个报错 at e.exports (bundle.js:1) at Object.<anonymous> (bundle.js:1) at n (bundle.js:1) at bundle.js:1 at bundle.js:1
|
报错信息指向了bundle.js
打包后的文件,这显然不是我们想要的
这个时候,我们可以使用sourceMap
来解决这个问题。
1 2 3 4 5 6 7 8 9 10 11 12
| //webpack.config.js module.exports = { entry:{ ... }, output:{ ... }, + devtool: 'inline-source-map', module:{}, plugins:{} }
|
然后重新执行
这样,控制台的报错就变成了
1 2 3 4 5 6
| get.js:3 Uncaught Error: 这里有个报错 at e.exports (get.js:3) at Object.<anonymous> (index.js:4) at n (bootstrap:19) at bootstrap:83 at bundle.js:1
|
指向了正确的位置,我们复原代码,进行下一步尝试
1 2 3 4 5
| //get.js module.exports = function(name){ console.log(name) - throw new Error('这里有个报错') };
|
webpack-dev-server 自动刷新页面
前面讲述了观察者模式及报错位置查找,但是美中不足的是,我们每次需要手动刷新来观察变化,这种情况下,可以使用webpack
中的的webpack-dev-server
模块,来完成自动更新的行为
首先安装webpack-dev-server
1
| npm install webpack-dev-server #或者yarn add webpack-dev-server
|
安装完毕后,修改一下webpack.config.js
文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const path = require('path') const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports = { //配置函数接受两个参数env和argv //env:环境对象 //Webpack-CLI 的命令行选项 entry: './src/index.js', //设置默认 output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, devtool: 'inline-source-map', + devServer: { + contentBase: './dist' + }, module: { rules: [{ //里面为匹配的规则 test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } }] }, plugins: [ new CopyWebpackPlugin([ { from: path.join(__dirname, '/staticFrom/'), to: path.join(__dirname+'/dist/') } ]) ] }
|
声明开发服务,并将 dist
目录下的文件,作为可访问文件,并且修改package.json
中声明一条
1 2 3 4 5 6 7
| { ..., "scripts":{ ..., + "serve": "webpack-dev-server --open" } }
|
然后执行
1
| npm run serve # 或者yarn serve
|
执行完毕后,浏览器自动打开了一个地址为localhost:8080
的网页,打开控制台,可以看到我们刚刚写入的大家好,我的名字是小刚
,然后我们继续把小刚,改回刚才的小明
1 2 3 4
| //let.js - let name = '小刚; + let name = '小明'; module.exports = name;
|
然后保存,浏览器的控制台,自动的就变化成了大家好,我的名字是小明
;
这样就建立了一个开发用的服务器,且每次修改,都会重新编译。