在了解使用了Unocss
后,就完全被它迷住了。接手过的所有项目都配置使用了它,包括一些旧项目,也跟同事分享了使用Unocss
的便捷性。
这里分享一下旧项目如何配置和使用Unocss
的,项目是vue2+vue-cli
构建的,node<20
平常开发这些项目都需要切换到16.x
去启动。
vscode插件UnoCSS
使用前先安装vscode
插件,有了它对于编写UnoCSS
的样式类提供了极大的便利,真的是事半功倍。
安装依赖
官方提供了两种方式的配置,一个是作为postcss
的插件@unocss/postcss
;一个是作为webpack插件@unocss/webpack
本来是选择了postcss
插件去安装的,但是偶尔会出现依赖安装时卡住就不动了,多个同事反映之后就改为了webpack插件的方式。目前没有发现任何问题。
ok,采用webpack
插件的方式,安装依赖:
sh
npm install -D @unocss/webpack unocss
创建unocss
配置文件uno.config.ts
:
可以暂时不需要考虑配置自定义的规则等,在慢慢使用过程中熟悉之后再去查看每个配置的功能作用,我们这里配置拉满。
js
import {
defineConfig,
presetAttributify,
presetUno,
presetIcons,
presetTypography,
transformerVariantGroup,
} from 'unocss';
export default defineConfig({
rules: [
// 这里可以自定义一些规则
],
presets: [
presetUno(),
presetAttributify(),
presetIcons(),
presetTypography(),
],
transformers: [transformerVariantGroup()],
});
@unocss/webpack
插件需要依赖style-loader
和css-loader
为了加载.css
文件。正常来说使用了vue-cli
构建的项目,已经具备加载.css
的能力。
配置webpack
在配置插件之前,确认一下@vue/cli-service
的版本,针对不同的版本,它依赖的webpack
版本也不同,就需要不同的配置,分为wepack@4
和 webpack@5
两种情况。
可以在package-lock.json
查找@vue/cli-service
依赖的webpack
版本
我当前项目的@vue/cli-service@3.9.0
依赖的webpack版本是4.0
。但是我们安装的是最新版的unocss@0.65
,从v0.59
开始仅支持ESM的加载方式,所以配置时需要动态加载。
为了避免被旧依赖安装配置的问题所缠绕,也为了使用到最新版的unocss
功能。对当前项目的@vue/cli-service
进行升级,升级版本到@vue/cli-service@5
升级版本不是很麻烦,我们查看开发环境所需的依赖的版本,如果太旧了删除掉重新安装,比如@vue/*
开头、babel
、eslint
等,在安装新版本时,如果出现依赖冲突可以降低一个版本安装。
折腾了一两个小时,更新之后发现代码里出现
eslint
规则校验问题有这么多。
推荐 一个可以查看依赖版本的工具,可以 升级依赖,查看依赖关系图
升级完成之后按照当前版本配置修改vue.config.js
,因为原来的vue.config.js
导出的是一个配置对象,而且@vue/cli-service@3
只支持对象,这使我不得不放弃直接配置unocss
的想法,选择了项目升级。
js
module.exports = {
// ...
}
升级后的vue-cli
是支持定义函数加载的,我们修改配置如下,使用import
动态加载,可以使用defineConfig
:
升级完成后的
@vue/cli-service
版本是^5.0.8
,配置按照webpack 5
js
const { defineConfig } = require("@vue/cli-service");
// ...
module.exports = async () => {
const { default: UnoCSS } = await import('@unocss/webpack');
reutnr {
chainWebpack: (config) => {
config.module.rule('vue').uses.delete('cache-loader');
// 使用了ts 开启
// config.module.rule('tsx').uses.delete('cache-loader')
config.merge({
cache: false,
});
// ...other
},
configureWebpack: {
plugins: [UnoCSS()],
optimization: {
realContentHash: true,
},
},
css: {
extract:
process.env.NODE_ENV === 'development'
? {
filename: '[name].css',
chunkFilename: '[name].[hash:9].css',
}
: true,
},
}
}
配置完插件之后,我们还需要最后一步,在主入口文件中加载import 'uno.css'
css文件。在main.js
中添加:
js
import 'uno.css';
这里就配置完成了,记得安装vscode
的插件,可愉快的在代码里写样式了。
配置postcss
插件
项目里配置了postcss
插件postcss-px-to-viewport
,本来是用@unocss/postcss
是不需要再处理的,现在改为配置为webpack
插件,需要处理下px
转vw
的问题。
基准设计图尺寸为1920px
,定义转换的方法:
js
// unocss px转vw
const px2Vw = (width) => {
if (Math.abs(width) < 2) {
return width + "px";
}
return ((width / 1920) * 100).toFixed(5) + "vw";
};
根据参数类型定义找到了一个插件的配置项,可以在生成数据对象后进行一次处理。
ts
{
//... other
/**
* Postprocess the generate utils object
*/
postprocess?: Arrayable<Postprocessor>
}
这里的postprocess
可以是一个对象;也可以是一个数组;type Postprocessor = (util: UtilObject) => void
定义一个函数,参数是一个UtilObject
对象。我们可以直接修改对象里的数据,不需要返回。
可以自己打印输出这个对象里有什么,也可以看源码类型定义。在函数中可以拿到已经生成的css
样式,然后可以直接修改。
ts
interface UtilObject {
selector: string
entries: CSSEntries
parent: string | undefined
layer: string | undefined
sort: number | undefined
noMerge: boolean | undefined
}
util.entries
是一个数组,它把我们定义的比如font-size-20px
拆分成了['font-size','20px']
,这样我们需要遍历这个数组,将值为px
的属性值转换成vw
。
OK,到这之后我们就可以在webpack
的unocss
插件定义postprocess
来处理。
js
UnoCSS({
postprocess: (util) => {
// 匹配px值
const pxReg = /^-?[\.\d]+px$/;
util.entries.forEach((item) => {
const value = item[1];
if (value && typeof value === "string" && pxReg.test(value)) {
// 调用方法直接赋值
item[1] = px2Vw(value.slice(0, -2) * 1);
}
});
}
}),
测试可以看到生成的css
样式已经转换成vw
了。
unocss
的版本选择
开始升级选择了安装最新的版本,发现使用时开发环境下没有问题。线上同事打包时说报错,打包不了,心想只能是这个版本的问题了,然后直接退回到0.59
版本,这个版本在其他项目里也用肯定没问题,线上部署过后。尝试了从最新版本慢慢降级,最后测试降低了两个小版本才正常。
解决类名冲突
旧项目也定义了大量的css
中,unocss
可能会把原项目中的class
类名识别并增加了样式,这就导致之前样式出现问题,为了暂时解决这个问题,我们屏蔽掉unocss
中有冲突的css
类名。
修改配置 uno.config.js
:
js
export default defineConfig({
// ...
blocklist: ["container", "table"],
})
通过设置blocklist
白名单,排除这些类名.container
和.table
的css生成。