11.webpack中的幾個路徑配置


一、相對路徑和絕對路徑

  1. 相對路徑
    相對路徑是指以當前的文件作為起點,相較於當前目錄的位置而被指向並且加以引用的文件資源。
  • /表示當前文件所在目錄的根目錄
  • ./表示當前文件所在目錄
  • ../表示當前文件所在目錄的上一級目錄
  1. 絕對路徑
    絕對路徑是指在當前文件的電腦硬盤上真正存在的路徑,必須准確,起點是系統的根目錄也就是各個盤的盤符。
    比如: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  // 當靜態資源文件變化的時候也重新刷新瀏覽器
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM