目录css
上节:使用loader之打包样式下html
首先删除bundles, 删完后目录以下:node
以前每次都要 npm run build后才能看打包后的效果,在开发阶段是不可能这么干地,咱们须要一个能使代码及时生效的功能。
webpack自带的webpack-dev-server 为你提供了一个简单的 web 服务器,而且可以实时从新加载webpack
修改配置:
webpack.config.js:web
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:npm
import './styles/index.less' window.addEventListener('DOMContentLoaded', function() { const root = document.getElementById('root'); root.innerText = _.join(['hellow', 'webpack'], '~'); });
src/styles/index.less:json
#root{ color: blue; }
修改package.json的script对象:segmentfault
// 省略 "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底层已经帮咱们写好了这种逻辑。