背景
項目使用vue-cli-service@4打包一個bundle.js;
希望bundle引用的文件使用cdn,但是發現publicPath設置無效:
我們打印了最終生成的webpack config
// 打印 config
api.configureWebpack(config => {
console.log('hyhy', config);
});
// 打印結果
{
...
output: {
path: '/ks-puzzle/custom-widgets/customization-table/dist',
filename: '[name].js',
publicPath: 'https://hyhyhy.com',
libraryTarget: 'umd'
},
...
}
可以看到我們設置的publicPath是生效的;但是生成的打包產物中publicPath未生效,如下:
...
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // on error function for async loading
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
...
這裏的__webpack_require__.p就是publicPath,值是空字符串,設置無效。
遇到問題後首先百度谷歌了一下publicPath not work等相關關鍵字,一段時間後未找到答案,開始進入源碼找原因。
切入點:__webpack_require__.p
我們來到webpack中設置__webpack_require__.p的地方;
可以看到這裏設置得publicPath為空字符串。以這裏為起點開始追查
webpack入口
一直追溯到了webpack的起點
可以看到webpack接收到的publicPath就是空值,那麼問題可能出在上一層也就是vue-cli-service這一層
vue-cli-service對publicPath的處理
在包@vue/cli-service中搜索publicPath,找到了下面這段代碼
可以看到當使用vue-cli-service進行lib方式打包時,publicPath會恆置為空。問題定位到了
解決方案
獲取到了進一步的信息後,重新進入谷歌搜索vue-cli-service target lib publicPath not work;
找到了社區解決方法:https://github.com/vuejs/vue-cli/issues/4896#issuecomment-569001811
使用自定義webpack plugin,在beforeRun的時候重新修改publicPath,明細如下:
function PublicPathWebpackPlugin() {}
PublicPathWebpackPlugin.prototype.apply = function (compiler) {
compiler.hooks.beforeRun.tap('PublicPathWebpackPlugin', compiler => {
compiler.options.output.publicPath = 'https://hyhyhy.com';
});
};
api.configureWebpack(config => {
config.plugins.unshift(new PublicPathWebpackPlugin());
});
打包後發現__webpack_require__.p設置正常,問題解決,done
PS
libraryTarget
追查問題過程中發現libraryTarget設置也是無效的
...
const configMap = {
commonjs: genConfig('commonjs2', 'common'),
umd: genConfig('umd', undefined, true),
'umd-min': genConfig('umd', 'umd.min')
}
function genConfig(format, postfix = format, genHTML) {
...
// set output target before user configureWebpack hooks are applied
config.output.libraryTarget(format)
// set entry/output after user configureWebpack hooks are applied
const rawConfig = api.resolveWebpackConfig(config)
...
}
可以看到使用vue-cli-service打包必然打出3種包commonjs;umd;umd.min;。
解決思路
總結下日常解決項目中問題的思路
- 首先使用
百度、Google、chatgpt查詢,看是否有人遇到過類似問題,如果查到了那麼問題解決,如果沒查到可能有以下幾種原因:
- 有人遇到過類似的問題
- 關鍵字設置的有誤導致答案沒有搜索出來;修改關鍵字或者添加關鍵字。
- 根據當前信息無法推導出有效關鍵字。
- 無人遇到過這個問題;
- 超過1小時未解決,進入
第2步
- 進入源碼尋找答案
- 找到問題切入點(最難)
- 向上層源碼追溯問題原因
- 根據問題具體原因,重新搜索解法或者自定義解法