webpack使用笔记(三)配置devServer
配置 devServer 之前需要先下载
yarn add webpack-dev-server -D
下载好之后,就可以在 webpack 配置项中去配置 webpack-dev-server 啦。
devServer 的配置项很多,这里只对使用比较多的配置项做一下介绍。devServer 的配置应该是在开发环境下进行。下面是一个简单的配置内容:
if(isDev){ // 如果是开发环境
config.devServer = {
// 设置 host(默认就是 localhost)
// 如果你希望服务器外部可访问
// 可以这样指定:127.0.0.1
// 即:通过 IP 地址的形式
host: "localhost",
// 设置端口号
port: "8888",
// 告诉服务器从哪个目录中提供内容
// 默认它会查找 index.html 文件作为页面根路径展示
contentBase: path.join(__dirname,"../build"),
// 这个publicPath代表静态资源的路径(打包后的静态资源路径)
publicPath: '/build/',
// 当设置成 true时,任意的 404 响应都可能需要被替代为 index.html
historyApiFallback: true,
// 是否开启 模块热替换功能
hot: true,
// 是否让浏览器自动打开(默认是 false)
open: true,
// 被作为索引文件的文件名。
// 默认是 index.html,可以通过这个来做更改
index: 'demo.html',
// 使用代理服务器
proxy: {
'/api': {
// 当请求 /api 的路径时,就是用 target 代理服务器
target: "http://loaclhost:3000",
// 重写路径
pathRewrite: {
'/api': ''
}
}
}
}
}
有时候我们不想使用代理,只是想单纯的模拟数据。就可以使用 webpack 给我们提供的一个 before
函数:
{
devServer: {
// app 参数就是 express 框架的 express 实例
before(app){
app.get('/api',(req,res) => {
// to do something...
})
}
}
}
在服务器内部执行自定义中间件之前 before
方法会被执行。与 before
方法对应的还有一个 after
方法,它会在服务器内部执行所有其他中间件之后执行。
第三种方式,就是使用 webpack 的端口(服务端和 webpack(前端) 是一个端口)在服务端需要下载一个中间件:webpack-dev-middleware
。
yarn add webpack-dev-middleware -D
然后服务端写入以下代码:
const express = require("express");
const webpack = require("webpack");
const webpackMiddleware = require("webpack-dev-middleware");
// 引入写好的 webpack 配置文件
let config = require("./webpack.config.js");
let compiler = webpack(config);
// 绑定中间件
app.use(webpackMiddleware(compiler));
配置命令
来到 package.json 文件中,再添加一条命令,叫做 start
,写下下面的内容:
{
"script": {
"build": "cross-env NODE_ENV='development' webpack --config config/webpack.config.dev.js",
"start": "cross-env NODE_ENV=development webpack-dev-server --config config/webpack.config.dev.js"
}
}
然后运行 npm start
就会自动打开浏览器,跳转到我们指定的 localhost:8888
端口。
有一点需要注意,在开发环境不要设置 publicPath,因为开发环境下 devServer 执行打包的内容是在内存里的,如果设置了 publicPath 保存后页面反而不会有刷新。应在生产环境再用 publicPath。还有一点就是,每次修改配置项都要重新运行命令,这是很费时的一件事,如何在更新配置文件后不用再次重启服务呢?这在下面会说到。
historyApiFallback 更具体的配置
通过传入一个对象,比如使用 rewrites 这个选项,可进一步地控制。
{
devServer: {
historyApiFallback: {
// 是个数组
rewrites: [
// 表示 以 “/” 开头请求的页面,会返回 to 对应路径下的 html 文件
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
// 别的则会返回 404 页面
{ from: /./, to: '/views/404.html' }
]
}
}
}
devServer 中 publicPath 的配置
devServer 中的 publicPath 与 output 中的并不同。devServer 中的 publicPath 指的是 webpack-dev-server 的静态资源服务路径。假如我们打包的内容在 build 文件夹下,则 publicPath 应是 /build/
,这里有个技巧,output 中指定的打包路径,比如:path: path.join(__dirname,'../build')
那么 devServer 的 publicPath 一般就是 join方法中的那个 build
。如果指定别的路径,很可能就会访问不到资源。
开启模块热替换功能
开启这个功能可以让我们修改文件并保持后,页面不会出现刷新的情况,页面中的内容是被动态更替了!这样减少了页面重新绘制的时间。在 devServer 中单纯的让 hot: true
是没有作用的,还需要一个 webpack 插件。这个插件是 webpack 内置的插件,不需要下载。具体配置步骤如下:
/**
* 来到 webpack 配置文件
* 引入 热更替插件
*/
const webpack = require('webpack');
// 来到 devServer 选项
{
devServer: {
hot: true
},
// 添加 plugin
plugins: [
new webpack.HotModuleReplacementPlugin(),
]
}
配置好 webpack 之后,还需要在入口程序处检测 module.hot 是否存在(这个对象是在 webpack 打包后自动加入的)。
假如我们的程序入口文件是 index.js,可以这么来写:
// index.js
if(module.hot){
// 调用 accept 方法开启热更替
module.hot.accept();
}
上面步骤做完后,就可以使用热更替了。如果有多个页面,则应为每个页面的入口作检验。
accept
还可以传入一个参数,如:
// index.js
import util from './utils';
// ...
if(module.hot){
// module.hot.decline();
module.hot.accept(['./utils.js'], () => {
console.log('utils.js hot module replace!!!');
});
}
当 utils.js 内部发生变更时可以告诉 webpack 接受更新的模块,回调函数会在热模块更替后触发。decline
方法与 accept
方法作用相反,它接受一个字符串数组或者字符串(模块的路径),它会拒绝给定依赖模块的更新。
React 中使用热模块更替
在 React 中,index.js 常常做程序的入口,而 App.js 往往需要 index.js 的导入。在 index.js 中可以这么来写:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
function render(){
ReactDOM.render(
<App />,
document.getElementById('root')
)
}
render();
if (module.hot) {
// 当第一个参数是数组时
// 表示 有多个路径需要热模块更替
// 回调用于在模块更新后触发的函数
module.hot.accept('./App.jsx',() => {
render();
});
}
React 官方提供了一个热更替模块 —— react-hot-loader
。使用它时需要下载,然后需要配置。
- 首先需要配置 webpack 文件:
// 更改 entry:
{
entry: ['react-hot-loader/patch', '../src/index.js'],
}
- 然后来到
.babelrc
文件,添加一个 plugin:
{
"plugins": ["react-hot-loader/babel"]
}
- 来到 index.js 文件处,你就可以直接把原来判断 module.hot 的内容给删掉了。而且 webpack 配置文件也不需要再引入热更新插件(恢复没有热更新配置时的样子,但是 hot 项不要变成 false)。
- 来到 App.js 文件,更改内容:
import { hot } from 'react-hot-loader';
function App(){
// ....
}
// 最后这样导出:
export default hot(module)(App);
还没完,还应该重新下载一个包:yarn add @hot-loader/react-dom
这个包和 react-dom
一样,只是它有热替换功能。下载之后,在 webpack resolve 配置项中写入:
alias: {
// 这样,你在引入 react-dom 时,就会引入这个包
'react-dom': '@hot-loader/react-dom'
}
最后,重启服务,热更替模块就可以用了。使用 react-hot-loader 的好处就是,可以避免 React 组件的不必要渲染。
上一篇: webpack插件的配置
下一篇: Webpack DevServer配置
推荐阅读
-
为什么我们要做三份 Webpack 配置文件
-
在webpack中使用eslint配置(详细教程)
-
Spring学习笔记之RedisTemplate的配置与使用教程
-
Spring学习笔记之RedisTemplate的配置与使用教程
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用
-
SpringBoot入坑笔记之spring-boot-starter-web 配置文件的使用
-
小米笔记本配置曝光:确定三个尺寸 极致性价比
-
小米笔记本配置曝光:确定三个尺寸 极致性价比
-
前端笔记之微信小程序(三)GET请求案例&文件上传和相册API&配置https
-
PHP中使用memcache存储session的三种配置方法