目录
上节:使用 loader 之打包样式下
首先删除 bundles, 删完后目录如下:
之前每次都要 npm run build 后才能看打包后的效果,在开发阶段是不可能这么干地,我们需要一个能使代码及时生效的功能。
webpack 自带的 webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载
基本使用
修改配置:
webpack.config.js:
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {filename: '[name].[contenthash:8].js',
path: resolve(__dirname, 'bundles')
},
// 开启 devServer
devServer: {},
module: {
rules: [{test: /\.(gif|jpg|jpeg|png|svg)$/,
use: ['url-loader']
}, {
test: /\.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({template: './index.html'}),
new CleanWebpackPlugin()]
};
src/index.js:
import './styles/index.less'
window.addEventListener('DOMContentLoaded', function() {const root = document.getElementById('root');
root.innerText = _.join(['hellow', 'webpack'], '~');
});
src/styles/index.less:
#root{color: blue;}
修改 package.json 的 script 对象:
// 省略
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
// 省略
webpack-dev-server 和 webpack 都会默认读取根目录下的 webpack.config.js
安装依赖:npm i webpack-dev-server -D
装完后执行 npm run dev,就会开启一个 node 服务:
浏览器访问:http:localhost:8080, 应出现如下页面:
这时每次修改 src/index.js,浏览器就会自动刷新咯。
热模块更新
现在修改代码后,浏览器会有一个刷新的动作,如果想达到无刷新的效果,需要配置写选项
webpack.config.js:
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {filename: '[name].[hash:8].js',
path: resolve(__dirname, 'bundles')
},
// 开启 devServer
devServer: {
hot: true,
// 可选,即使代码没生效,也不刷新浏览器
hotOnly: true
},
module: {
rules: [{test: /\.(gif|jpg|jpeg|png|svg)$/,
use: ['url-loader']
}, {
test: /\.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({template: './index.html'}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin()]
};
这时重新执行 npm run dev, 打开浏览器,字体颜色应该是蓝的,这时随便换个颜色,浏览器就能无刷新生效了。
但是有个问题,如果改变 src/index.js 的代码,浏览器不会有任何反应,原因是开启了 hotOnly,如果把 hotOnly 去掉
devServer: {hot: true}
这时改 index.less 没问题,但是改 index.js,浏览器还是会刷新一下,这说明改 js 并未实现热更新效果。
继续改代码,在 src 下新建 js 目录,并新建 counter.js 和 number.js
src/js/counter.js:
let num = 1;
export default function counter() {const div = document.createElement('div');
div.setAttribute('id', 'counter');
div.innerText = num;
div.onclick = function () {div.innerText = ++num;}
document.body.appendChild(div);
}
src/js/number.js:
export default function number() {const div = document.createElement('div');
div.setAttribute('id', 'number');
div.innerText = 1000;
document.body.appendChild(div);
}
src/index.js:
import counter from './js/counter';
import number from './js/number';
counter();
number();
然后浏览器运行如图:
随机点击数次数字 1 后如图:
此时是 13 和 1000,然后改变 number.js 里的 1000,在看浏览器:
浏览器会刷新一下,1000 变成了 3000,但是 13 也重置成了 1
我们的想法是,当我们改变 number.js 文件时,页面上只改变 number.js 那部分内容,其它地方保持原样,比如保持 13,这时就需要再做点事情
src/index.js:
import counter from './js/counter';
import number from './js/number';
counter();
number();
if (module.hot) { // 如果开启了热更新
module.hot.accept('./js/number', function() {
// ./js/number 变化时执行
console.log('number updated!');
document.body.removeChild(document.getElementById('number'));
number();})
}
这时在此点击几次数字 1:
比如页面上是:6 和 3000
再来改变 number.js, 把 3000 改成 1000,观察浏览器:
此时浏览器没有刷新,单页面已经发生变化,3000 变成了 1000,并且上面那个数字还是 6
这里就有个问题了, 为啥之前改 less 时 hmr 能直接生效,改 js 就要自己手动写一坨逻辑呢?
那是因为 style-loader 底层已经帮我们写好了这种逻辑。
下节:webpack-dev-server 下(待更新)