output的publicPath
output中的path的作用是告知webpack之后的输出目录:
- 比如静态资源的js、css等输出到哪里,常见的会设置为dist、build文件夹等;
output中还有一个publicPath属性,该属性是指定index.html文件打包引用的一个基本路径;
- 它的默认值是一个空字符串,所以我们打开后引入js文件时,路径是bundle.js
- 在开发中,我们也将其设置为 / ,路径是 /bundle.js,那么浏览器会根据所在的域名+路径去请求对应的资源;
- 如果我们希望在本地直接带开html文件来运行,会将其设置为 ./ ,路径是 ./bundle.js,可以根据相对路径去查找资源;
devServer的publicPath
devServer中也有一个publicPath属性,该属性是用来指定本地服务所在的文件夹的:
- 它的默认值是 / ,也就是我们直接访问端口即可访问其中的资源 http://localhost:8080
- 如果我们将其设置为了 /abc,呢么我们需要通过 http://localhost:8080/abc 才能访问到对应的打包后的资源
- 并且这个时候,我们其中的 bundle.js 通过 http://localhost:8080/bundle.js 也是无法访问的
- 所以必须将 output.publicPath 也设置为 /abc
- 官方其实有提到,建议 devServer.public 与 outpu.publicPath 相同
注意:
webpack5.64.2版本以后,这一功能已经被合并进最新的static属性,配置如下
devServer: {
hot: true,
static: {
directory: path.join(__dirname, 'public'),
publicPath: '/abc',
},
},
devServer的contentBase
devServer中contentBase对于我们直接访问打包后的资源其实并没有太大的作用,它的主要作用是如果我们打包后的资源,有依赖于其他的一些资源,那么就需要指定从哪里来查找这个内容:
- 比如在index.html中,我们需要依赖一个 abc.js 文件,这个文件我们存放在 public 文件中;
- 在 index.html 中,我们应该如何去引入这个文件呢?
- 比如代码是这样的:
- 但是这样打包后浏览器是无法通过相对路径去找到这个文件夹的
- 所以代码是这样的:
- 但是我们如何让他去查找到这个文件的存在呢?设置contentBase即可
- 比如代码是这样的:
注意:
webpack5.64.2版本以后,这一功能已经被合并进最新的static属性,新属性值为directory,配置如下
hotOnly、host配置
hotOnly
hotOnly是当代码编译失败被修复后,我们会重新刷新整个页面,如果不希望重新刷新整个页面,可以设置hotOnly为true
注意:
webpack5.64.2版本以后,只要给hot属性赋值为only即可,配置如下
host设置主机地址
默认值是localhost
如果希望其他地方也可以访问,可以设置为0.0.0.0
localhost和0.0.0.0的区别
- localhost:本质上是一个域名,通常情况下会被解析成127.0.0.1
- 127.0.0.1:回环地址(Loop Back Address),表达的意思是我们主机自己发出去的包,直接被自己接收
- 正常的数据包: 应用层 - 传输层 - 网络层 - 数据链路层 - 物理层
- 回环地址:在网络层就被获取,不经过数据链路层和物理层
- 所以我们监听127.0.0.1时,在同一个网段下的主机中,铜鼓oip地址是不能访问的
- 0.0.0.0:监听IPV4上所有的地址,再根据端口找到不同的应用程序
- 比如我们监听0.0.0.0时,在同一个网段下的主机中,通过ip地址是可以访问的
配置如下
module.exports = {
//...
devServer: {
host: '0.0.0.0',
},
};
port、open、compress
port
指定监听请求的端口号:
module.exports = {
//...
devServer: {
port: 8080,
},
};
open
告诉 dev-server 在服务器已经启动后打开浏览器。设置其为 true
以打开你的默认浏览器。
module.exports = {
//...
devServer: {
open: true,
},
};
compress
是否为静态文件开启 gzip compression
默认值是false,可以设置为true
module.exports = {
//...
devServer: {
compress: true,
},
};
Proxy代理
proxy是我们开发中非常常用的一个配置选项,它的目的是设置代理来解决跨域访问的问题:
- 比如我们的一个api请求是 http://localhost:8888,但是本地启动服务器的域名是 http://localhost:8000,这个时候发送网络请求就会出现跨域的问题
- 那么我们可以将请求先发送到一个代理服务器,代理服务器和API服务器没有跨域的问题,就可以解决我们的跨域问题了
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000',
},
},
};
如果想要代理https地址,可以如下配置
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '^/api': '' },
},
},
},
};
changeOrigin的解析
changeOrigin
默认情况下,代理时会保留主机头的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。 在某些情况下,例如使用 name-based virtual hosted sites,它很有用。
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
},
},
},
};
historyApiFallback
historyApiFallback是开发中非常常见的属性,它主要的作用是解决SPA页面在路由跳转之后,进行页面刷新时,返回404的错误
module.exports = {
//...
devServer: {
historyApiFallback: true,
},
};
通过提供一个对象,这种行为可以通过像 rewrites 这样的配置项进一步控制:
module.exports = {
//...
devServer: {
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' },
],
},
},
};
resolve
resolve用于设置模块如何被解析
- 在开发中我们会有各种各样的模块依赖,这些模块可能来自于自己编写的代码,也可能来自第三方库
- resolve可以帮助webpack从每个 require/import 语句中,找到需要引入到合适的模块代码
- webpack使用enhanced-resolve来解析文件路径
webpack能解析三种文件路径:
绝对路径
- 由于已经获得文件的绝对路径,因此不需要再进一步解析
相对路径
- 在这种情况下,使用import或require的资源文件所处的目录,被认为是上下文目录
- 在import/require中给定的相对路径,会拼接此上下文路径,来生成模块的绝对路径
模块路径
- 在resolve.modules中指定的所有目录检索模块
- 默认值是[‘mode_modules’],所以默认会从node_modules中查找文件
- 我们可以通过设置别名的方式来替换初始模块路径
确定是文件还是文件夹
如果是一个文件:
- 如果文件具有扩展名,则直接打包文件
- 否则,将使用 resolve.extensions 选项作为文件扩展名解析
- extensions 默认只有 [‘.js’, ‘.json’, ‘.wasm’] 这三个后缀名,可以自定义
如果是一个文件夹
- 会在文件夹中根据 resolve.mainFiles 配置选项中指定的文件顺序查找
- resolve.mainFiles的默认值是[‘index’]
- 再根据 resolve.extensions 来解析扩展名
extensions和alias配置
extensions是解析到文件时自动添加扩展名:
- 默认值是 [‘.js’, ‘.json’, ‘.wasm’]
- 所以如果我们代码中想要添加加载 .vue 或者 jsx 或者 ts 等文件时,我们必须自己写上扩展名
alias用于设置别名:
- 特别是当我们的项目结构很深的时候,它的路径可能是 ‘../../../‘ 这种形式
- 我们还可以给常用路径起一个别名,比如 src