最近負責的項目用的是element-ui庫,sass編譯用的是官網推薦的dart-sass,但是項目上線后會出現偶爾亂碼的情況

通過檢查發現,icon那里的content變成奇怪的字符了

原因
分析了一下這個問題出現的原因,如果一般使用不會出現這個問題,因為一般引入的是element-ui的css文件,問題出在於為了主題色變化啊,需要用到scss變量引入了scss文件
@import "~element-ui/packages/theme-chalk/src/index";
而dart-sass在編譯element-ui里icon偽元素的content unicode編碼時會轉換成對應unicode明文,所以通過偽元素來展示的圖標如el-icon-arrow:before{ content: "\e6df"},編譯之后就變成了el-icon-arrow:before{ content: ""},“”便是一個雙字節字符,導致出現亂碼
解決方法
1、element-ui采用的時node-sass編譯,可以把dart-sass換成node-sass,但是官網主推dart-sass,dart-sass會是未來主流
2、查網上資料發現可以和后端商量下,讓css資源請求的響應頭的Content-Type增加"charset=utf-8"聲明,因為涉及到后端,所以具體筆者沒試驗過,不知道可不可行。
3、這個方法是網上查來的 https://github.com/styzhang/css-unicode-loader
對scss文件增加一層loader來將dart-scss編譯成的css文件里面的雙字節字符再轉回16進制碼
const CONTENT_MATCH_REG = /(?<!-)content\s*:\s*([^;\}]+)/g; // 找出偽元素里content那塊內容
const UNICODE_MATCH_REG = /[^\x00-\xff]/g; // 找出非單字節符
function fun(source) {
source = source.replace(CONTENT_MATCH_REG, function (m, p1) {
return m.replace(UNICODE_MATCH_REG, function (m) {
return "\\" + m.charCodeAt(0).toString(16); // m.charCodeAt(0)返回字符串第一個字符的 Unicode 編碼,后面再轉16進制,前面加一斜杠
});
});
return source;
}
let test = `.el-icon-ice-cream-square:before {
content: "";
}
`;
console.log(fun(test));
// 打印結果
// .el-icon-ice-cream-square:before {
// content: "\e6da";
// }
可以通過安裝大牛寫的loader
npm install --save-dev css-unicode-loader
如果是vuecli3+ 則可以按如下配置
// vue.config.js
module.exports = {
configureWebpack: config => {
config.module.rules.filter(rule => {
return rule.test.toString().indexOf("scss") !== -1;
})
.forEach(rule => {
rule.oneOf.forEach(oneOfRule => {
oneOfRule.use.splice(oneOfRule.use.indexOf(require.resolve('sass-loader')), 0,
{ loader: require.resolve("css-unicode-loader")})
})
})
}
}
