11.webpack中的几个路径配置
作者:互联网
一、相对路径和绝对路径
- 相对路径
相对路径是指以当前的文件作为起点,相较于当前目录的位置而被指向并且加以引用的文件资源。
- /表示当前文件所在目录的根目录
- ./表示当前文件所在目录
- ../表示当前文件所在目录的上一级目录
- 绝对路径
绝对路径是指在当前文件的电脑硬盘上真正存在的路径,必须准确,起点是系统的根目录也就是各个盘的盘符。
比如:C:\Users\克林辣舞\Desktop\kelinlawu这就是一个绝对路径
二、entry入口路径配置
-
功能: 用于指定webpack在打包的时候依据哪个文件当做打包的入口。
-
默认值: ./src/index.js
-
注意:enrty属性的值其相对的路径不是webpack.config.js文件所在路径,而是项目的根路径
假设有下面这样一个项目目录:
|---config
|---webpack.config.js
|
|---src
|---main.js
在webpack.config.js中的配置是这样的:
module.exports = {
entry:"../src/main.js"
}
按照常理来说,webpack.config.js文件中按照相对路径去读取入口文件也就是src目录下的main.js文件,那么entry是应该写成上述这种相对路径:'../src/main.js',代表去webpack.config.js文件的上一级目录中查找src文件夹下的main.js文件当做入口文件,这一切看起来都是正常的,但是在执行npm run build的时候却会报错,报错的内容是:
Module not found: Error: Can't resolve '../src/main.js' in 'C:\Users\克林辣舞\Desktop\webpack\webpack-demo - 副本'
意思是说在"C:\Users\克林辣舞\Desktop\webpack\webpack-demo - 副本"此目录的上一级目录中没有找到src文件夹中的main.js。这说明了一个问题:那就是不管webpack.config.js配置文件放在什么目录下,其中entry属性的值都是以当前项目的根路径来进行配置的,所以正确的配置方法应该是:
module.exports = {
entry:"./src/main.js" // 也可以配置为/src/main.js /代表当前文件所在的根路径,和./是一个意思
}
以上配置代表webpack在打包的时候寻找项目的根路径下的src文件夹中的main.js文件当做入口文件进行打包,运行npm run build之后打包成功,说明这种配置是正确的。
- webpack.config.js配置文件路径影响脚本配置
这里有一个注意的地方就是webpack.config.js配置文件一般情况下是放置在项目的根目录下的,此时在package.json中配置脚本的时候是不需要指定webpack.config.js文件的路径的:
"scripts": {
"build": "webpack ",
"serve": "webpack serve --open",
}
而如果我们手动建立了一个config文件夹,将webpack.config.js配置文件放在了这个文件夹中,此时必须要借助于--config参数指定webpack.config.js配置文件的存放路径:
"scripts": {
"build": "webpack --config ./config/webpack.config.js",
"serve": "webpack serve --config ./config/webpack.config.js --open",
}
三、output出口若干路径配置
filename
- 功能:用于指定webpack打包之后输出的主文件的名称,该文件将会写入到path选项指定的目录下
- 默认值:'./dist/main.js'
- 注意
filename的值必须是一个相对路径,而不能是一个绝对路径,以下写法都被认为是有效的路径:
- bundle.js
- ./js/bundle.js
但是以下写法被认为是无效的路径: - /js/bundle.js
path
- 功能:用于指定webpack打包之后所有生成的文件存放的目录
- 默认值:./dist文件夹,代表会将所有打包之后的文件存放在当前项目根目录下的dist文件夹中
- 注意:path属性的值是一个绝对路径,它是通过path.resolve方法来生成的一个绝对路径
假设有下面这样一个项目目录,其根目录是:"C:\Users\克林辣舞\Desktop\webpack\webpack-demo - 副本"
|---config
|---webpack.config.js
|
|---src
|---main.js
在webpack.config.js中有如下配置:
module.exports = {
output: {
filename: "js/bundle.js",
path: path.resolve(__dirname, "../build"),
},
}
这里的path的值经过path.resolve方法处理之后将会得到一个绝对路径:"C:\Users\克林辣舞\Desktop\webpack\webpack-demo - 副本\build",也就是说webpack在对此项目打包之后会将所有打包的文件放入当前项目的根目录下的build文件夹下,而在build文件夹中的js文件夹中存放着项目打包后的主文件bundle.js。
publicPath
-
功能:publicPath用于对webpack打包之后得到的静态资源前面进行一个路径的拼接
-
默认值:"" 空字符串
为什么在开发的时候需要配置publicPath为"/"?
当我们在本地基于webpack dev server启动了一个本地服务之后,此时浏览器就会基于WDS提供的静态服务去获取加载所需的资源,比如index.html文件。浏览器在解析html的时候遇到link标签和script标签的时候又会去请求css、js等静态资源,比如遇到一个script资源去获取js文件:
<script defer="" src="/js/bundle.js"></script>
浏览器在解析到script标签中包含一个src属性的时候便知道这是一个外部js脚本,要基于src属性所指向资源的路径去获取js资源,而浏览器客户端在获取资源的时候可以基于不同的协议去获取,比如http协议、或者是file协议。
由于浏览器当前加载的index.html就是浏览器从WDS提供的静态服务器上获取的,所以浏览器就会基于当前页面的协议+域名,然后在后面依次拼接上output.publicPath和src属性指定的资源路径去本地服务器获取资源,所以浏览器的请求地址其实是:
http://localhost:8080 + output.publicPath + js/bundle.js
如果output.publicPath的值没有配置那就是默认值为空串,拼接之后的路径就是:"http://localhost:8080js/bundle.js",很显然这种url路径端口号和路径没有用/分隔开,所以大多数浏览器会默认在两者之间加一个/以避免资源加载失败,因此最终拼接完成的请求地址是:
http://localhost:8080/js/bundle.js
由于WDS已经将我们打包后的资源放在了本地服务器上,所以在开发环境下浏览器会正确的基于这个地址拿到js资源并加载,页面就会正常加载。
然而为什么诸如Vue CLI等这种官方脚手架的webpack.config.js会将output.publicPath的值配置为一个"/"呢?这是为了避免有的浏览器不会默认在域名和路径之间加/,最终导致请求路径拼接错误导致页面加载失败,为了保证在所有浏览器中都可以正确获取到资源,所以会在这里显式的配置output.publicPath的值为"/"。
为什么在打包的时候需要配置publicPath值为"./"
如果我们在npm run build的时候也配置publicPath的值为/,然后我们直接在本地加载打包后dist文件夹中的index.html的时候,此时浏览器在解析html文件中的script标签中的src值去获取资源的时候是无法获取的,还是以上面的例子来说明:
<script defer="" src="/js/bundle.js"></script>
当浏览器基于src的属性去获取js文件的时候,由于此时index.html文件是在本地打开的,所以此时浏览器其实是基于file协议去加载资源的,其请求地址是:
file:///C:/js/bundle.js
因为浏览器在解析路径:"/js/bundle.js"的时候会将最前面的/解析为本地文件的根路径也就是盘符C:,很明显在C盘的根目录下是没有js/bundle.js文件的,因此会找不到资源加载失败。
而如果我们在打包前将publicPath的值设置为"./",那么浏览器在解析路径:"./js/bundle.js"的时候会将其解析为相对当前index.html同一目录下的js/bundle.js,此时浏览器的请求路径就变成了:
file:///C:/Users/克林辣舞/Desktop/webpack/webpack-demo - 副本/build/js/bundle.js
很明显基于上面这个路径去本地获取资源是可以成功获取的,因此如果我们想将打包后的资源在本地打开后也正常加载的话就需要将output.publicPath的值设置为"./"
devServer
四、devServer中的若干路径配置
publicPath(webpack4中配置,V5版本已经没有此属性)
- 功能:指定本地服务在运行的时候获取打包后资源所在的文件夹路径
- 默认值:'/' 也就是直接访问端口即可访问其中的资源http://localhost:8080
- 注意:devServer.publicPath很少主动配置
在devServer的配置属性中也有一个publicPath属性,该属性的主要作用就是指定项目在浏览器中打开之后默认去本地服务器上的那个文件夹中获取打包之后的资源,如果不配置devServer.publicPath那么就读取默认值'/',此时获取资源的路径就是:
http://localhost:8080/ 代表直接去当前服务器的根目录下获取打包之后的资源即可
如果将devServer.publicPath的值配置为:'/project',那么此时获取资源的路径是:
http://localhost:8080/project 代表直接去当前服务器的project目录下获取打包之后的资源
官方建议:devServer.publicPath的值应该始终和output.publicPath的保持一致,否则会导致资源获取失败。
contentBase(webpack4中配置,V5版本已经没有此属性)
如果我们使用webpack来打包资源前在index.html中引入了某些第三方的静态资源,而这些静态资源并不会成为webpack依赖图中的一员所以也就不会被最终打包到dist目录下,但是在WDS启动本地服务之后浏览器加载打包之后的index.html的时候,还是会按照打包前的路径去引入这些第三方静态资源,此时就会出错。
打包前的index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webpack module</title>
/* 引入第三方静态资源 等于是直接读取的本地文件*/
<script src="./vender/vender.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
WDS服务起来之后的index.html
此时等于基于http协议去本地服务器获取这个文件:http://localhost:8080/vender/vender.js,由于此文件并不在打包的dist文件夹中,所以本地服务器会找不到这个资源。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webpack module</title>
/* 等于是基于http协议去本地服务器获取这个文件:http://localhost:8080/vender/vender.js */
<script src="./vender/vender.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
所以我们需要告诉WDS的本地服务器,应该如何去加载这种没有包含在打包依赖中的第三方静态资源:
在webpack4中,我们需要配置devServer.contentBase如下,告诉webpack要将第三方静态资源放在vender文件夹下进行读取:
devServer:{
hot:true,
contentBase:path.resolve(__dirname,"./vender") // 绝对路径
}
在webpack5中,我们需要配置static中的directory和publicPath如下:
devServer:{
hot:true,
static:{
directory:path.resolve(__dirname,"./vender"),
publicPath:"/vender",
watch:true // 当静态资源文件变化的时候也重新刷新浏览器
}
}
标签:11,路径,js,webpack,publicPath,config,打包 来源: https://www.cnblogs.com/gaokai/p/15971153.html