webpack-dev-server 是 Webpack 官方推出的一款开发工具,根据它的名字我们就应该知道,它提供了一个开发服务器,并且将自动编译和自动刷新浏览器等一系列对开发友好的功能全部集成在了一起。
webpack-dev-server 的NPM地址:https://www.npmjs.com/package/webpack-dev-server
1. 安装运行
安装 webpack-dev-server
npm install webpack-dev-server --save-dev
或
yarn add webpack-dev-server --dev
运行 webpack-dev-server
npx webpack-dev-server
可以在 package.json
文件中写入运行命令,这样就可以用 npm run start
来启动 dev 操作
可以为 webpack-dev-server
命令传入一个 --open
的参数,用于自动唤起浏览器打开我们的应用。打开浏览器过后,此时如果你有两块屏幕,就可以把浏览器放到另外一块屏幕上,然后体验一边编码,一边即时预览的开发环境了。
"scripts": {
"start": "webpack-dev-server --open",
"build": "webpack --config webpack.config.js",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
2. 配置选项
Webpack 配置对象中可以有一个叫作 devServer 的属性,专门用来为 webpack-dev-server 提供配置
详细配置可查看 webpack 文档: https://www.webpackjs.com/configuration/dev-server/#devserver
静态资源访问 (contentBase)
在实际使用 Webpack 时,我们一般都会把 copy-webpack-plugin
这种插件留在上线前的那一次打包中使用,而开发过程中一般不会用它。因为在开发过程中,我们会频繁重复执行打包任务,假设这个目录下需要拷贝的文件比较多,如果每次都需要执行这个插件,那打包过程开销就会比较大,每次构建的速度也就自然会降低。
webpack-dev-server 默认会将构建结果和输出文件全部作为开发服务器的资源文件,也就是说,只要通过 Webpack 打包能够输出的文件都可以直接被访问到。但是如果你还有一些没有参与打包的静态文件也需要作为开发服务器的资源被访问,那你就需要额外通过配置告诉 webpack-dev-server。
这里我们先移除 CopyWebpackPlugin
,确保这里的打包不会输出 public 目录中的静态资源文件。
配置devServer
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
progress: true,
openPage: 'dist/index.html',
},
默认情况下,将使用当前工作目录作为提供内容的目录,但是你可以修改为其他目录:
contentBase: path.join(__dirname, "public")
注意:推荐使用绝对路径。
但是也可以从多个目录提供内容:
contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")]
禁用 contentBase:
contentBase: false
Usage via the CLI
webpack-dev-server --content-base /path/to/content/dir
Proxy 代理
由于 webpack-dev-server 是一个本地开发服务器,所以我们的应用在开发阶段是独立运行在 localhost 的一个端口上,而后端服务又是运行在另外一个地址上。但是最终上线过后,我们的应用一般又会和后端服务部署到同源地址下。
那这样就会出现一个非常常见的问题:在实际生产环境中能够直接访问的 API,回到我们的开发环境后,再次访问这些 API 就会产生跨域请求问题。我们可以用跨域资源共享(CORS)解决这个问题。如果我们请求的后端 API 支持 CORS,那这个问题就不成立了。但是并不是每种情况下服务端的 API 都支持 CORS。如果前后端应用是同源部署,也就是协议 / 域名 / 端口一致,那这种情况下,根本没必要开启 CORS,所以跨域请求的问题仍然是不可避免的。
那解决这种开发阶段跨域请求问题最好的办法,就是在开发服务器中配置一个后端 API 的代理服务,也就是把后端接口服务代理到本地的开发服务地址。
webpack-dev-server 就支持直接通过配置的方式,添加 proxy
代理服务。
官方文档地址:https://www.webpackjs.com/configuration/dev-server/#devserver-proxy
配置 proxy
// ./webpack.config.js
module.exports = {
// ...
devServer: {
proxy: {
'/api': {
target: 'https://api.github.com',
pathRewrite: {
'^/api': '' // 替换掉代理地址中的 /api
},
changeOrigin: true // 确保请求 GitHub 的主机名就是:api.github.com
}
}
}
}
那此时我们请求 http://localhost:8080/api/users ,就相当于请求了 https://api.github.com/users。
pathRewrite
属性来实现代理路径重写,重写规则就是把路径中开头的/api
替换为空,pathRewrite
最终会以正则的方式来替换请求路径。
changeOrigin
属性设置为 true
,就会以实际代理请求地址中的主机名去请求
( 默认代理服务器会以我们实际在浏览器中请求的主机名,也就是 localhost:8080 作为代理请求中的主机名。而一般服务器需要根据请求的主机名判断是哪个网站的请求,那 localhost:8080 这个主机名,对于 GitHub 的服务器来说,肯定无法正常请求,所以需要修改。)。
默认情况下,不接受运行在 HTTPS 上,且使用了无效证书的后端服务器。如果你想要接受,修改配置如下:
proxy: {
"/api": {
target: "https://other-server.example.com",
secure: false
}
}