webpack中的path、publicPath、contentBase的區分

output.publicPath & devServer.publicPath

  • output裏面的publicPath表示的是打包生成的index.html文件裏面引用資源的前綴;
  • devServer裏面的publicPath表示的是打包生成的靜態文件所在的位置(若是devServer裏面的publicPath沒有設置,則會認爲是output裏面設置的publicPath的值);

兩個publicPath可以看作是devServer對生成目錄dist設置的虛擬目錄,devServer首先從devServer.publicPath中取值,如果它沒有設置,就取output.publicPath的值作爲虛擬目錄,如果它也沒有設置,就取默認值 “/”。

output.publicPath,不僅可以影響虛擬目錄的取值,也影響利用html-webpack-plugin插件生成的index.html中引用的js、css、img等資源的引用路徑。會自動在資源路徑前面追加設置的output.publicPath。

示例

基本目錄

在這裏插入圖片描述

配置

var path = require("path");
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
	entry: {
		app: './src/app.js'
	},
	output: {
		path: path.join(__dirname, "dist"),
		filename: "[name].js",
		libraryTarget: "umd",
		publicPath: '/asset/'
	},
	resolve: {
		extensions: ['.js', '.vue', '.json']
	},
	externals: {
		tools: "tools"
	},
	module: {
		rules: [
			{
				test: /\.vue$/,
				loader: 'vue-loader',
				
			}
		]
	},
	plugins: [
		new HtmlWebpackPlugin({
			title: 'hello world',
			template: './src/index.html',
			filename: 'index.html'
		})
	],
	devServer: {
		host: 'test.m.iqiyi.com',
		port: '9393'
	}
};

通過訪問 http://test.m.iqiyi.com:9393/, 我們發現無法訪問到頁面,只是顯示出了目錄
在這裏插入圖片描述

如果我們訪問http://test.m.iqiyi.com:9393/, 可以正常訪問到頁面
在這裏插入圖片描述

通過上面兩個圖片的對比,能得出output.publicPath影響着devServer的虛擬目錄的設置。同時內部引用的js路徑也被修改爲output.publicPath

如果我們修改配置:

devServer {
	publicPath: "test"
}

訪問 http://test.m.iqiyi.com:9393/test/, 如下圖所示:
在這裏插入圖片描述

我們會發現,虛擬目錄優先取devServer中的publicPath,index.html中的js路徑仍然取的output.publicPath,但是由於兩者值不一樣,所以server找不到 /asset/的虛擬目錄。

contentBase

devServer裏面的contentBase表示的是告訴服務器從哪裏提供內容。(也就是服務器啓動的根目錄,默認爲當前執行目錄,一般不需要設置)

path

output裏面的path表示的是output目錄對應的一個絕對路徑

html-webpack-plugin

這個插件用於將css和js添加到html模版中,其中template和filename會受到路徑的影響,從源碼中可以看出
template作用:用於定義模版文件的路徑
源碼:

this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

複製代碼因此template只有定義在webpack的context下才會被識別,webpack context的默認值爲process.cwd(),既運行 node 命令時所在的文件夾的絕對路徑

filename作用:輸出的HTML文件名,默認爲index.html,可以直接配置帶有子目錄
源碼:

this.options.filename = path.relative(compiler.options.output.path, filename);

複製代碼所以filename的路徑是相對於output.path的,而在webpack-dev-server中,則是相對於webpack-dev-server配置的publicPath。

如果webpack-dev-server的publicPath和output.publicPath不一致,在使用html-webpack-plugin可能會導致引用靜態資源失敗,因爲在devServer中仍然以output.publicPath引用靜態資源,和webpack-dev-server的提供的資源訪問路徑不一致,從而無法正常訪問。

有一種情況除外,就是output.publicPath是相對路徑,這時候可以訪問本地資源

所以一般情況下都要保證devServer中的publicPath與output.publicPath保持一致。

參考文章:
https://juejin.im/post/5bb085dd6fb9a05cd24da5cf
https://juejin.im/post/5ae9ae5e518825672f19b094

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章