webpack-dev-server是利用express开启的dev服务器 。
基本使用
webpack v5 开启dev-server的方式是:
{
// ...
devServer: {
open: true, // 自动打开浏览器
static: { // 以前的contentBase换成了static
directory: path.join(__dirname, 'dist'),
},
compress: true, // gzip压缩
port: 9000,
},
}
“static.directory ”就是把某个目录作为静态server的根目录。dev-server开启的时候,会自动打包,可能看不到打包输出,但是其实是打包并按照配置输出了。
配合HtmlWebpackPlugin
一般前端项目,js文件打包之后,最好指定html入口,所以配合插件HtmlWebpackPlugin:
const HtmlWebpackPlugin = require("html-webpack-plugin")
{
//...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, 'public', 'index.html')
})
],
}
这个插件的作用是生成一个index.html,其模版就是上面template指定的,然后输出到webpack配置的output里面。同时,生成的这个新的html中,自动将打包好的js文件插入为script标签。
请求代理proxy
dev-server常用的另一个功能就是proxy,将前端请求代理:
{
devServer : {
// ...
proxy: {
'/api': {
target: 'http://localhost:3000',
// pathRewrite: { '^/api': '' },
},
},
}
}
配置好了以后,在开发过程中,前端中发起的请求将根据请求前缀,决定是否转发到target的地址中,这个转发是express做的,所以不会有跨域问题。
fetch('/api/user').then(res => res.json()).then(data => {
// do something
})
比如上面这个请求,就会代理到:http://localhost:3000/api/user。
pathRewrite就是就是前缀的替换规则,比如开启pathRewrite后:pathRewrite: { ‘^/api’: ‘’ },把api替换成空字符串,那么上面的请求就会代理到:http://localhost:3000/user。
代理之后,如何debug代理请求的目标对不对呢,可以这样,利用bypass属性:
{
devServer : {
// ...
proxy: {
'/api': {
target: 'http://localhost:3000',
// pathRewrite: { '^/api': '' },
bypass: function (req, res, proxyOptions) {
// req
// res
// 都是express的
const urlPath = getRealUrl(req, proxyOptions)
// 加一个自定义头
res.setHeader('yxnne-real-url', urlPath)
},
},
},
},
}
}
// 得到真实url
function getRealUrl (req, proxyOptions) {
const { pathRewrite, target } = proxyOptions
let urlPath = req.path
if (pathRewrite) {
Object.keys(pathRewrite).forEach(key => {
urlPath = urlPath.replace(new RegExp(key), pathRewrite[key])
})
urlPath = `${target.replace(/\/$/, '')}${urlPath}`
} else {
urlPath = target + req.path
}
return urlPath
}
简单来讲,bypass就是代理的请求会走这个函数。
所以可以在里面拿到一些关心的信息,并设置在请求、返回头上,或者其他操作。