滴滴云控制台为了升级vue,UI库和脚手架,使用qiankun做了拆分。拆分后的发现Icon的展示有问题。
项目结构如下1
2
3
4
5
6
7|____node_modules
| |____ui-lib
| | |____index.css
| | |____fonts
| | | |____ui-lib.woff
|____src
| |____main.js
main.js1
import 'ui-lib/index.css'
node_modules中的ui-lib1
@font-face{font-family:ui-lib;src:url(fonts/ui-lib.woff) format("woff")}
vue.config.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44const publicPath = process.env.NODE_ENV === "production" ? '//cdn.myservice.com/' : `/`;
module.exports = {
publicPath,
configureWebpack: {
entry: { app:'./src/main.js'},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
},
execute: true,
},
},
],
},
],
},
},
chainWebpack: config => {
const imgRule = config.module.rule('images');
imgRule.uses.clear();
imgRule
.use('file-loader')
.loader('file-loader')
.options({
name: 'img/[name].[hash:8].[ext]',
publicPath
})
.end()
},
}
编译后的文件app.css1
@font-face{font-family:ui-lib;src:url(../fonts/ui-lib.woff) format("woff")}
这里变成了../fonts/ui-lib.woff
,而没有变成预期的cdn.myservice.com/fonts/ui-lib.woff
。所以浏览器加载的时候path报错了。
我最先尝试的是在configureWebpack.module.rules增加url-loader
1
2
3
4
5
6
7
8{
test: /\.(woff?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 2048,
name: 'fonts/[name].[hash:7].[ext]'
}
},
结果顺利的被解析成了base64。而base64的内容是module.exports = __webpack_public_path__ + "node_modules/ui-lib//fonts/ui-lib.b3909f8.woff";
虽然浏览器调试台里preview展示如下,但是Icon仍然没展示出来。(这里为什么展示出来,但是没生效我也没想明白)
项目是vue-cli搭建的,其实非常困惑的是 const imgRule = config.module.rule('images');
这里的images是代表什么,又没定义过,只好去翻vue-cli的文档
这里忍不住想吐槽一下vue-cli,为了简化上手成本,它默认内置了常用的loader和plugin,但是没有暴露出来。webpack的配置进到@vue/cli-service的项目中都看不到webpack的配置。根据文档,vue inspect > output.js
。可以把所有内置的webpack信息输出出来。
1 | ➜ demo git: ✗ vue inspect --rules |
同上例的config.module.rule(‘fonts’)一样,images也是对图片适用的loader配置,这猜破了脑袋也猜不出来(小声比比)。这页文档太宝贵了,这个问题迟早得遇到,早遇到早明白。
能解决问题的配置1
2
3
4
5
6
7
8 config.module.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
.use('url-loader')
.loader('file-loader')
.options({
publicPath,
name: 'fonts/[name].[hash:8].[ext]'
})
上边的配置强行解释一波,把fonts
的规则,test改为/\.(woff2?|eot|ttf|otf)(\?.*)?$/
,把原来fonts的url-loader
改为带options的file-loader
。
顺手把woff文件刨了一下,扔到解析网站,发现它是如下的样子
具体为什么在content里写上对应的code,就展示出了对应的icon。我也没搞懂。