node-sass 4.x iconfont 乱码

615 阅读1分钟

最近接手一个项目,sass-loader(8.x)使用的node-sass进行scss文件的编译转换,node-sass的版本是4.14.1。在项目的scss文件中引入了iconfont,代码示例如下:

$icon-content-arrow-right: "\e619";

结果编译后,变成了如下的字符:

iconfont.jpg

导致页面引入该css后,字体图标变成了乱码

通过搜集网上资料,查明原因后,可以通过如下方法,将构建后的css还原成unicode字符,具体做法如下:

编写webpack自定义构建插件

代码示例如下:

// 找出伪元素里content那块内容
const CONTENT_MATCH_REG = /(?<!-)content\s*:\s*([^;\}]+)/g;
// 找出非单字节符
const UNICODE_MATCH_REG = /[^\x00-\xff]/g;
function encodeCssContentUnicodeChar(source) {
  source = source.replace(CONTENT_MATCH_REG, (m, p1) => {
    return m.replace(UNICODE_MATCH_REG, (_m) => {
      // _m.charCodeAt(0)返回字符串第一个字符的 Unicode 编码,后面再转16进制,前面加一斜杠
      return '\\' + _m.charCodeAt(0).toString(16);
    });
  });
  return source;
}

class CssContentUnicodePlugin {
  apply(compiler) {
    compiler.hooks.emit.tap('CssUnicodePlugin', (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;
        });
    });
  }
}

然后在webpack.config.js中配置该插件即可