一般情況下,我們對應(yīng)用進行配置打包秤茅,要對圖片字體等資源進行下面配置稚补,使得資源路徑正常加載。但是嫂伞,在微前端模式下孔厉,子應(yīng)用打包部署后,往往會出現(xiàn)子應(yīng)用 css
文件里面引入資源路徑加載失敗的問題帖努,下面就讓我們來探究一下撰豺。
?? 獨立應(yīng)用下的 url-loader
配置:
// vue-cli 2 寫法
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
// 此處的 utils.assetsPath 是函數(shù),返回根據(jù)配置項拼接好的路徑拼余,如 static/fonts/[name].[hash:7].[ext]
name: utils.assetsPath("img/[name].[hash:7].[ext]")
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
// 此處的 utils.assetsPath 是函數(shù)污桦,返回根據(jù)配置項拼接好的路徑,如 static/fonts/[name].[hash:7].[ext]
name: utils.assetsPath("fonts/[name].[hash:7].[ext]")
}
}
]
}
因為 url-loader
的 options
項的屬性 publicPath
屬性默認是 ''
匙监,表示相對路徑凡橱,即打包出來的資源引用 url
都會加上相對路徑尋找 static
靜態(tài)資源入口小作,比如:
/* static/css/app.e99e9aae.css */
background-header {
background: url(../../static/img/bg_header.790a94f4.png);
}
所有應(yīng)用編譯打包部署后,當(dāng)主應(yīng)用加載子應(yīng)用稼钩,子應(yīng)用加載自身的 css
文件樣式時顾稀,由于 其對應(yīng)的 css 文件里面的圖片 url
引用是相對路徑,會出現(xiàn)子應(yīng)用的資源相對路徑拼接主應(yīng)用 domain
的情況坝撑,即子應(yīng)用的 ../../static/img/bg_header.790a94f4.png
會在主應(yīng)用的 domain
下進行資源的尋找静秆,導(dǎo)致加載失敗 404
的情況。
解決打包后的 css 背景圖片與字體圖標路徑問題
如果項目有用到第三方庫巡李,比如 element-ui
抚笔,那么就更有必要進行處理了。因為 element-ui
的字體圖標是在 css
里面引入的侨拦,還有相關(guān)背景圖片的引入也是在 css
里累舷,所以需要配置 webpack
的 url-loader
哨坪,生產(chǎn)模式情況下直接指定資源前綴,使之成為絕對路徑。
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
name: utils.assetsPath("img/[name].[hash:7].[ext]"),
//這里 192.168.2.192:7100 是子應(yīng)用部署地址
publicPath: process.env.NODE_ENV === 'production' ? '//192.168.2.192:7100' : ''
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
name: utils.assetsPath("fonts/[name].[hash:7].[ext]"),
publicPath: process.env.NODE_ENV === 'production' ? '//192.168.2.192:7100' : ''
}
}
]
}
這樣配置后邓尤,打包出來的 css 樣式文件會變成:
/* static/css/app.e99e9aae.css */
background-header {
background: url(//192.168.2.192:7100/static/img/bg_header.790a94f4.png);
}
資源是絕對路徑砍聊,就不會出現(xiàn)上面子應(yīng)用資源加載失敗的情況唧龄。
但是局冰,這種前端配置文件寫死路徑的做法靈活性并不好,比如不能做到編譯一次训貌,任意部署制肮,因為路徑寫死,所以如果需要部署到其他服務(wù)器的話递沪,就需要重新編譯了豺鼻。
接下來,講的是實現(xiàn)靈活部署的方案款慨。
結(jié)合 nginx 配置資源引用路徑代理轉(zhuǎn)發(fā)
我們在只編譯打包一次前端應(yīng)用的前提下儒飒,為了實現(xiàn)靈活部署,需要借助 nginx
來實現(xiàn)檩奠。
下面以 vue-cli 3
的配置為例桩了,與 vue-cli 2
只是寫法上的區(qū)別,其他都一樣埠戳。
不過 vue-cli 3 對 webpack 配置進行了抽象井誉,要理解配置中包含的東西會比較困難,尤其是當(dāng)我們需要重寫或者調(diào)整配置的時候整胃,可以參考 審查項目的 webpack 配置颗圣。
module.exports = {
chainWebpack: (config) =>
config.module
.rule("fonts")
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
.use("url-loader")
.loader("url-loader")
.options({
limit: 4096,
name: 'static/fonts/[name].[hash:8].[ext]',
publicPath: process.env.NODE_ENV === 'production' ? '/live' : '',
});
config.module
.rule("images")
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
.use("url-loader")
.loader("url-loader")
.options({
limit: 4096,
// name 代表 url-loader 會將資源寫到 static/fonts/ 下
name: 'static/img/[name].[hash:8].[ext]',
// publicPath 代表資源引入 url 會生成 /live 的前綴,比如 /live/static/img/bg_header.790a94f4.png
publicPath: process.env.NODE_ENV === 'production' ? '/live' : '',
});
}
}
假設(shè)主應(yīng)用部署地址是 192.168.2.192
,子應(yīng)用的部署地址是 192.168.2.192:7102
在岂。
打包編譯部署后奔则,子應(yīng)用的 css 文件里面的圖片資源引用 url
如下:
/* static/css/app.e99e9aae.css */
background-header {
background: url(/live/static/img/bg_header.790a94f4.png);
}
主應(yīng)用加載子應(yīng)用的時候,子應(yīng)用的資源拼接主應(yīng)用 domian
后蔽午,子應(yīng)用的 css
文件里面的圖片資源加載路徑 url
就會變成:
192.168.2.192/live/static/img/bg_header.790a94f4.png
此時的關(guān)鍵就是要訪問到子應(yīng)用的資源易茬,而不是去主應(yīng)用資源目錄去找。
所以我們采用 nginx
路徑代理轉(zhuǎn)發(fā)端口的方案祠丝,當(dāng)應(yīng)用訪問 192.168.2.192/live
這個路徑時疾呻,經(jīng)過 nginx
進行路徑代理轉(zhuǎn)發(fā)配置,轉(zhuǎn)發(fā)到子應(yīng)用端口写半。
配置 nginx
代理規(guī)則:
# nginx.conf
http {
server {
listen 80;
server_name 192.168.2.192;
location /live {
proxy_pass 127.0.0.1:7102
try_files $uri $uri/ /index.html;
}
}
}
此時真正訪問的資源路徑(子應(yīng)用資源路徑)是:
192.168.2.192:7102/static/img/bg_header.790a94f4.png
?? 至此,通過修改配置 url-loader
的 publicPath
以及配置 nginx
的路徑代理轉(zhuǎn)發(fā)尉咕,就可以實現(xiàn)編譯打包一次叠蝇,到處部署的目的。