problem found
Recently, when using the shuttle frame component in the company's component library, it was found that the icon
icons were all garbled.
analyse problem
After the investigation found that the component style file ( scss
) introduced iconfont
vector font icons, build, \e601
such Unicode
characters after sass
compiled, it becomes a literal characters (double-byte characters), resulting in garbled
.icon-ok:before {
content: "\e601";
}
Sass
after compilation
.icon-ok:before {
content: "";
}
Solve the problem
(1) Upgrade sass version
This problem has been fixed in the Sass@1.38.0
version. The version used in the project can be 1.38.0+
to 0616e891fda1b4. For details, see Sass
update log
// index.scss
.icon-ok:before {
content: "\e601";
}
Execute npx sass@1.38.0 index.scss index.css
// index.css
.icon-ok:before {
content: "\e601";
}
/*# sourceMappingURL=index.css.map */
(2) Custom webpack loader
When it comes to building the analysis of the above problems Sass
will Unicode
characters compiled into a text character, then we can in loader
queue sass-loader
after adding our custom loader
, the CSS
text characters in translated Unicode
characters? Of course it is possible
const CONTENT_MATCH_REG = /(?<!-)content\s*:\s*([^;\}]+)/g; // 找出伪元素里content那块内容
const UNICODE_MATCH_REG = /[^\x00-\xff]/g; // 找出非单字节符
function fun(source) {
this.cacheable(); // 利用缓存来提高编译效率
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;
}
test
let test = `.el-icon-ice-cream-square:before {
content: "";
}
`;
console.log(fun(test));
// 打印结果
// .el-icon-ice-cream-square:before {
// content: "\e6da";
// }
You can refer to: https://github.com/styzhang/css-unicode-loader
(3) Custom webpack plugin
Several necessary conditions for developing the webpack
- Obtain the compiler object, through which you can obtain information including
config
configuration, resource files, compilation information, hook functions, etc. - Compile the life cycle function of the phase, find a suitable hook function to handle the corresponding logic
- The returned result supports both synchronous and asynchronous methods
/**
* 编码unicode字符串
* encodeUnicodeChar('•') // 等价于 '\\2022';
*/
module.exports.encodeUnicodeChar = function (str) {
let content = "";
for (let i = 0; i < str.length; i++) {
const codePoint = str.codePointAt(i);
if (codePoint > 127) {
content += "\\" + str.codePointAt(i).toString(16);
} else {
content += str.charAt(i);
}
}
return content;
};
module.exports.encodeCssContentUnicodeChar = function (css) {
return css.replace(
/([{\s;]content:\s?['"])(.+?)(['"][;\s}])/g,
(match, p1, p2, p3, offset, str) => {
return p1 + module.exports.encodeUnicodeChar(p2) + p3;
}
);
};
Execute before outputting the generated resource file after the build to the target directory, emit
is an asynchronous series of hooks
const { encodeCssContentUnicodeChar } = require("./utils");
class CssContentUnicodePlugin {
apply(compiler) {
compiler.hooks.emit.tap("CssUnicodePlugin", function (compilation) {
Object.keys(compilation.assets)
.filter((filename) => /\.css$/.test(filename))
.forEach((filename) => {
const asset = compilation.assets[filename];
let fileContent = asset.source();
fileContent = encodeCssContentUnicodeChar(fileContent);
asset.source = () => fileContent;
asset.size = () => fileContent.length;
});
});
}
}
module.exports = CssContentUnicodePlugin;
refer to:
sass unicode character encoding problem
Sass: Unicode escape is not saved in the .css file
webpack articles-plugin development
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。