vue项目中icon乱码的问题
问题描述最近发现项目在测试环境下icon偶尔会出现乱码的情况,我自己本地一直没能复现,在测试环境复现的话就需要打开控制台,然后按键刷新,一次不行就多刷新几次,就可以复现这个问题。原因分析这个问题可能是因为项目中有用到element-ui库,而项目中安装的sass和element-ui源码中的sass(node-sass)安装版本不一致造成的。项目中的sass具体:一般使用不会出现这个问题,因为一般
·
问题描述
最近发现项目在测试环境下icon偶尔会出现乱码的情况,我自己本地一直没能复现,在测试环境复现的话就需要打开控制台,然后按键刷新
,一次不行就多刷新几次,就可以复现这个问题。
原因分析
这个问题可能是因为项目中有用到element-ui库,而项目中安装的sass和element-ui源码中的sass(node-sass)安装版本不一致造成的。
- 项目中的sass
具体:
- 一般使用不会出现这个问题,因为一般引入的是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: “”},“”便是一个双字节字符,导致出现乱码。
- https://www.cnblogs.com/shandou/p/14867943.html
解决方法
- 直接uninstall项目中的sass,然后安装node-sass(因为是公司项目,不好做修改)
- node-sass 是用 node(调用 cpp 编写的 libsass)来编译 sass;node-sass是自动编译实时的
- dart-sass 是用 drat VM 来编译 sass;dart-sass需要保存后才会生效
- node-sass 因为国情问题经常装不上
- sass官方已经将dart-sass作为未来主要的的开发方向了,有任何新功能它会优先支持
- 和后端商量下,让css资源请求的响应头的Content-Type增加"charset=utf-8"声明。(没做尝试)
看到大佬写的一个方法
https://github.com/styzhang/css-unicode-loader- 安装大佬写的loader
yarn add css-unicode-loader --dev
- 对应的配置
if use vue-cli 4+ and scss(sass), add the loader in the vue config file .// vue.config.js module.exports = { configureWebpack: config => { const sassLoader = require.resolve('sass-loader'); config.module.rules.filter(rule => { return rule.test.toString().indexOf("scss") !== -1; }) .forEach(rule => { rule.oneOf.forEach(oneOfRule => { const sassLoaderIndex = oneOfRule.use.findIndex(item => item.loader === sassLoader); oneOfRule.use.splice(sassLoaderIndex, 0, { loader: require.resolve("css-unicode-loader") }); }); }); } }
- 安装大佬写的loader
vue.config.js具体配置
const path = require('path');
const webpack = require('webpack');
const buildDate = JSON.stringify(new Date().toLocaleString());
let devServer = null;
try {
devServer = require('./devServer');
}
catch (e) {
devServer = {};
}
function resolve(dir) {
return path.join(__dirname, dir);
}
// 将之前的plugins提出来封装成一个函数
function getPlugins() {
const plugins = [
// Ignore all locale files of moment.js
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new webpack.DefinePlugin({
APP_VERSION: `"${require('./package.json').version}"`,
BUILD_DATE: buildDate,
}),
];
return plugins;
}
const vueConfig = {
// configureWebpack: {
// // webpack plugins
// plugins: [
// // Ignore all locale files of moment.js
// new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// new webpack.DefinePlugin({
// APP_VERSION: `"${require('./package.json').version}"`,
// BUILD_DATE: buildDate,
// }),
// ],
// },
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') });
});
});
// 获取plugins函数的内容
const plugins = getPlugins();
//这里要返回一个对象
return { plugins };
},
chainWebpack: (config) => {
config.plugin('html')
.tap(args => {
args[0].title = process.env.VUE_APP_TITLE;
return args;
});
config.module
.rule('svg')
.exclude.add(resolve('./src/assets/icons'))
.end();
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('./src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader');
},
css: {
loaderOptions: {
less: {
// DO NOT REMOVE THIS LINE
javascriptEnabled: true,
},
},
},
devServer,
// disable source map in production
productionSourceMap: false,
lintOnSave: true,
// babel-loader no-ignore node_modules/*
transpileDependencies: [],
};
module.exports = vueConfig;
验证方法
修改前yarn build,检查dist/css/app.xxx.css
文件中的emp-icon-xxx:before{content:""}
修改后 yarn build ,检查dist/css/app.xxx.css
文件中的emp-icon-xxx:before{content: '\xxx'}
更多推荐
已为社区贡献1条内容
所有评论(0)