@antebudimir/eslint-plugin-vanilla-extract (英语)
保持这个插件需要时间和小心! 如果你认为它很有价值,请考虑支持它的发展:
GitHub赞助商: https://github.com/赞助商/antebudimir 互联网档案馆的存檔,存档日期2013-12-21
☕: https://ko-fi.com/antebudimir (英语)
* 革命: https://revolut.me/antebudimir 页面存档备份,存于互联网档案馆
自由报: https://liberapay.com/antebudimir 页面存档备份,存于互联网档案馆
用于香草取材的 ESLint 综合插件,用于执行其中的最佳做法 香草摘录 CSS风格. 包括支助CSS财产订购(麻痹, 同心圆),和自定义组顺序),高级样式林出规则,自动固定,并验证了香草-取材所特有的样式图案. 确保零运行时间安全,并与多个香草抽取的API相融合,以促进各项目之间可维护、一致的代码
演示
特征
- 执行 CSS 属性命令 :
- 按字母顺序排列的干净、可预测的风格组织
- 逻辑、外部财产安排的同心命令
- 自定义组命令更多精细控件的选项
- 与 ESLint 8.57.0+, 9.x 和 10.x (平面配置)相兼容
- 提供自动排序属性的自动固定能力
- 处理多组香草-取出 API(样式,样式变异,配方,全球Style等)
- 处理嵌入对象、样式阵列和伪选择器等复杂案件
- 与 vanilla- extract 中使用的 Case 属性有关的工作
- 提高代码质量的其他规则(见即将出现的特性路线图)
- 自动包装器函数检测 - 使用自定义的包装器函数调用 vanilla-extract API 引用跟踪以应用所有规则,无论香草-提取函数是如何包裹的
所需资源
- ESLint 8.57.0或以上(8.57、9.x和10.x都得到支持和测试)
- 20.19.0或以上的节点
- 无害环境管理(ECMAScript模块)
- 使用任意一种的平面配置系统 :
eslint.config.mjs(建议,总是与无害环境管理插件合作)eslint.config.js(除非你的包裹.json已经)"type": "module"(中文(简体) )
ESLint 10用户的说明: 如果您同时使用
typescript-eslint,确保你在typescript-eslintQQ 8.46 (首次发布声明ESLint 10支持)以避免 相互依赖的冲突.
安装
# Using npm
npm install --save-dev @antebudimir/eslint-plugin-vanilla-extract
# Using yarn
yarn add --dev @antebudimir/eslint-plugin-vanilla-extract
# Using pnpm
pnpm add -D @antebudimir/eslint-plugin-vanilla-extract
# For ESLint 8.57.0 with flat config, you'll also need:
npm install --save-dev @eslint/eslintrc @eslint/js
yarn add --dev @eslint/eslintrc @eslint/js
pnpm add -D @eslint/eslintrc @eslint/js
使用量
注:此插件仅限无害环境管理. 它必须使用无害环境管理配置,不能使用通用JS require()。 。 。 .
配置选项
您的 ESLint 平面配置中有两种主要配置插件的方法:
备选案文1:使用扩展(建议,可从v1.1.0.0获得)
适用建议规则的最简单和最简洁的方式:
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
ignores: ['src/**/theme-contract.css.ts'],
extends: [vanillaExtract.configs.recommended],
// You can still override rules when using extends
// rules: {
// 'vanilla-extract/concentric-order': 'off',
// 'vanilla-extract/alphabetical-order': 'error',
// },
},
];
备选案文2:使用带有明确规则的插件
这种方法更加明确 - 您手动注册插件并传播推荐的规则 :
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
ignores: ['src/**/theme-contract.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
rules: {
// Apply all recommended rules
...vanillaExtract.configs.recommended.rules,
// Optionally override specific rules
// 'vanilla-extract/concentric-order': 'warn', // Change severity from error to warn
// 'vanilla-extract/no-empty-style-blocks': 'off', // Disable a recommended rule
// 'vanilla-extract/no-zero-unit': 'warn', // Change severity from error to warn
// Switch to a different ordering rule (see "Important" section below)
// 'vanilla-extract/concentric-order': 'off',
// 'vanilla-extract/alphabetical-order': 'error',
},
},
];
重要: 一次只启用一个顺序规则
插件包括三个CSS属性订购规则: alphabetical-order, (中文(简体) ), concentric-order,以及 custom-order。 。 。 . 一次只允许一个命令规则 以避免自定义冲突.
如果您想要使用与推荐配置中的规则不同的顺序规则, 您必须明确禁用默认规则 .
示例:从同心圆切换到字母顺序
export default [
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
rules: {
...vanillaExtract.configs.recommended.rules,
'vanilla-extract/concentric-order': 'off', // Disable the default
'vanilla-extract/alphabetical-order': 'error', // Enable alphabetical
},
},
];
示例: 使用自定义顺序代替推荐的同心- 顺序
export default [
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
rules: {
...vanillaExtract.configs.recommended.rules,
'vanilla-extract/concentric-order': 'off', // Disable the default
'vanilla-extract/custom-order': [
'error',
{
groupOrder: ['font', 'dimensions', 'margin', 'padding', 'position', 'border'],
sortRemainingProperties: 'alphabetical',
},
],
},
},
];
QQ 警告 : 如果同时启用多条订购规则,它们会生成ESLint无法应用的相冲突自定义,导致自定义被保存失败. 总是确保只有一个命令规则有效 .
使用FlatCompat(用于ESLint 8.57.0和8.57.1)
如果你从遗留的ESLint配置中迁移出去,你可以使用 FlatCompat 用于在添加时转换它们
香草-提取支持 :
import path from 'path';
import { fileURLToPath } from 'url';
import { FlatCompat } from '@eslint/eslintrc';
import js from '@eslint/js';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
// Mimic CommonJS variables
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Create a compatibility layer instance
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
});
export default [
// Convert your existing ESLint configs
...compat.config({
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
// etc
],
}),
// Add vanilla-extract by using explicit rule config
{
files: ['**/*.css.ts'],
ignores: ['src/**/theme-contract.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
rules: {
// Apply all recommended rules
...vanillaExtract.configs.recommended.rules,
// or specify rule by rule as described above
},
},
];
与平面兼容的常见问题
-
错误: “ 意外的顶层属性“ 文件 ”
- 解决方案: 当使用时
compat.config(),使用时overrides改为files在顶层.
- 解决方案: 当使用时
-
错误: FlatCompat 构造器中“ 缺少参数“ 建议的Config”
- 解决方案:导入
js从@eslint/js添加recommendedConfig: js.configs.recommended切换到平面 建筑师.
- 解决方案:导入
-
错误 : “ 在用户定义的索引 0 下未定义的配置 ”
- 解决方案:确保您在配置阵列中使用默认导出.
VS 代码整合
用于 VS 代码用户,将这些设置添加到您的 .vscode/settings.json数字 :
{
"eslint.useFlatConfig": true,
"eslint.experimental.useFlatConfig": true,
"eslint.validate": ["javascript", "typescript", "typescriptreact"]
}
建议配置
推荐的配置可以使以下规则具有出错的严重程度:
vanilla-extract/concentric-order执行 同心圆 CSS 属性排序vanilla-extract/no-empty-style-blocks: 防止空样式块vanilla-extract/no-trailing-zero: 取消在数值 CSS 中以 0 为后缀vanilla-extract/no-unknown-unit:禁止使用未识别的CSS单元vanilla-extract/no-zero-unit: 删除零值不必要的单位
可用的其他规则 (默认无法启用) :
vanilla-extract/alphabetical-order: 备选顺序规则(平分)vanilla-extract/custom-order: 备选排序规则(基于海关集团的排序)vanilla-extract/no-px-unit: 取消带有可选允许列表的 px 单位vanilla-extract/no-unitless-values: 取消 CSS 属性需要单位的单位值vanilla-extract/prefer-logical-properties: 在物理方向属性上执行逻辑 CSS 属性vanilla-extract/prefer-theme-tokens: 执行主题符而不是硬码值, 用于颜色、 间隔、 字体大小、 边框半径、 边框宽度、 阴影、 z- 索引、 不透明、 字体权重、 过渡/ 动画( 可选择评价助手函数和模板字节)
您可以使用推荐的配置作为起点, 并根据您的项目需要推翻规则 。 参见上面关于如何在命令规则之间切换的配置示例.
自定义配置
如果您不愿使用推荐的配置, 您仍然可以手动配置规则 :
export default [
{
files: ['**/*.css.ts'],
ignores: ['src/**/theme-contract.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
rules: {
// 'vanilla-extract/alphabetical-order': 'warn',
// OR
// 'vanilla-extract/concentric-order': 'warn',
// OR
'vanilla-extract/custom-order': [
'warn',
{
groupOrder: ['font', 'dimensions', 'margin', 'padding', 'position', 'border'], // example group order
// optional
sortRemainingProperties: 'concentric', // 'alphabetical' is default
},
],
'vanilla-extract/no-unknown-unit': 'error',
'vanilla-extract/no-zero-unit': 'warn',
},
},
];
说明: 记住每次只允许一个命令规则 。 关于订购规则之间的切换细节见上文"重要"部分.
全球设置( 建议用于共享包装)
如果使用跨越多条顺序规则的导入的包装器函数,请在 ESLint 中配置一次 settings。 。 。 .
所有订购规则( E)alphabetical-order, (中文(简体) ), concentric-order, (中文(简体) ), custom-order)读取此值.
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
settings: {
'vanilla-extract': {
style: ['componentStyle', 'layerStyle'],
recipe: ['componentRecipe'],
},
},
rules: {
...vanillaExtract.configs.recommended.rules,
},
},
]);
仅通过 ESLint 配置包装名 settings (单位:千美元)style, (中文(简体) ), recipe) (中文(简体) ).
规则
香草-抽取/止痛-顺序
此规则强制要求 香草- extract 样式对象的 CSS 属性遵循字母顺序 .
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const myStyle = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: 19,
marginBottom: 1,
marginLeft: 2,
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
alignItems: 'center',
display: 'flex',
height: 19,
justifyContent: 'center',
marginBottom: 1,
marginLeft: 2,
});
字母顺序的全局设置 : settings['vanilla-extract'].style
vanilla-extract/alphabetical-order 从 Global ESLint 设置中读取包裹名称.
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
settings: {
'vanilla-extract': {
style: ['componentStyle'],
},
},
rules: {
'vanilla-extract/alphabetical-order': 'error',
},
},
]);
香草-提取/同心-顺序
此规则强制要求 香草- extract 样式对象遵循 CSS 属性 同心圆 CSS 命令模式,将属性从外部组织到内部.
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const myStyle = style({
color: 'red',
display: 'flex',
position: 'relative',
padding: '10px',
margin: '20px',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
position: 'relative',
display: 'flex',
margin: '20px',
padding: '10px',
color: 'red',
});
同心圆顺序的全局设置 : settings['vanilla-extract'].style
从本地模块导入样式包装时使用此设置( 例如) componentStyle, (中文(简体) ), layerStyle) (中文(简体) ).
如果列出一个折叠函数名称,则规则处理调用该函数的方式如下: style(...) 打电话.
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
settings: {
'vanilla-extract': {
style: ['componentStyle', 'layerStyle'],
},
},
rules: {
'vanilla-extract/concentric-order': 'error',
},
},
]);
香草-抽取/海关订单
这个 vanilla-extract/custom-order 规则允许您执行 CSS 属性自定义命令
香草-取材风格. 您可以按首选顺序指定一系列属性组, 该规则将保证
这些群体中的财产按其在 同心CSS模型。 。 。 .
这一规则的主要特点包括:
- 自定义组排序 : 定义 CSS 属性组的首选顺序 .
- 未指定组的处理: 自定义数组中未包含的所有组,其属性排序如下 最后一个指定组.
- 灵活排序选项:您可以选择按字母排序或按字母排序其余属性
设置 CSS 顺序
sortRemainingProperties选项为“同心”或“同心”.
默认行为 :
- 如果没有设定,
sortRemainingProperties默认为“ alphabetic” . - 若无
groupOrder指定或提供空数组,规则将默认排序所有属性 按字母顺序排列sortRemainingProperties即使设定了也会被忽略.
要配置规则,请将规则添加到您的 ESLint 配置文件中,并附上您想要的选项 。 您可以自定义
groups 数组包括您想要执行的任何可用的 CSS 属性组, 至少包含一个组
所需经费.
自定义顺序的全球设置 : settings['vanilla-extract'].style
vanilla-extract/custom-order 也读作 style 从全球环境与
groupOrder 财务报告和审定财务报表 sortRemainingProperties。 。 。 .
import { defineConfig } from 'eslint/config';
import vanillaExtract from '@antebudimir/eslint-plugin-vanilla-extract';
export default defineConfig([
{
files: ['**/*.css.ts'],
plugins: {
'vanilla-extract': vanillaExtract,
},
settings: {
'vanilla-extract': {
style: ['componentStyle'],
},
},
rules: {
'vanilla-extract/custom-order': [
'error',
{
groupOrder: ['font', 'dimensions', 'margin', 'padding', 'position', 'border'],
sortRemainingProperties: 'alphabetical',
},
],
},
},
]);
// ❌ Incorrect (Unordered)
import { style } from '@vanilla-extract/css';
export const myStyle = style({
color: 'blue',
padding: '10px',
fontFamily: 'Arial, sans-serif',
margin: '20px',
width: '200px',
border: '1px solid black',
display: 'flex',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
// font group
fontFamily: 'Arial, sans-serif',
color: 'blue',
// dimensions group
width: '200px',
// margin group
margin: '20px',
// padding group
padding: '10px',
// display group
display: 'flex',
// border group
border: '1px solid black',
});
香草-取出/无空-风格-块
此规则在 vanilla-extract 样式表中检测并预防空样式块. 它有助于维护更清洁的密码库 取消由于不完全重构或被遗忘的执行而产生的空样式定义.
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const emptyStyle = style({});
export const nestedEmpty = style({
color: 'blue',
':hover': {},
'@media': {
'(min-width: 768px)': {},
},
});
export const recipeWithEmptyVariants = recipe({
base: { color: 'black' },
variants: {},
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const nestedEmpty = style({
color: 'blue',
});
export const recipeWithEmptyVariants = recipe({
base: { color: 'black' },
});
自动固定安全
规定只有在安全时才能自动转移声明. 声明是: 未报告 自动修正 (你必须手动解决)
- 声明 导出 (单位:千美元)
export const x = style({})——出口标识符可被进口 用作一种className在其它文件中,规则无法看到. - 标识符的 仍在同一文件中的其他地方引用 ——例如,作为类名钩子在a
globalStyle()选择器模板文字 :
// ❌ Reported, but not auto-fixed (the identifier's still referenced)
import { globalStyle, style } from '@vanilla-extract/css';
// used only as a class-name hook, not for its own props
export const buttonWrapper = style({});
globalStyle(`${buttonWrapper} > svg`, {
color: 'red',
});
宣告无标识符的空块( 如 . globalStyle('ul', {}))和无参考、无出口
声明仍然完全可自动固定.
如果有意使用空声明作为类名钩,而根本不希望报告,则启用
ignoreReferenced 选项 :
选项
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
ignoreReferenced | boolean | false | 不要报告被导出或仍在他处引用的空样式声明(如故意类名钩). |
{
"rules": {
"vanilla-extract/no-empty-style-blocks": ["error", { "ignoreReferenced": true }]
}
}
真正的未使用的空声明仍然被报告,并随此选项自动删除. 财产一级探测
(空选者, @media编号 :@supports 对象,空变位值等)也保持活性——只有
出口/参考申报的完整申报报告被删除.
香草-抽取/无px-单位
此规则不允许使用硬码 px 以香草-取材样式申报的单位。 偏爱 rem, (中文(简体) ), em,或主题符号。 配置允许列表允许您使用特定属性 px 必要时。 允许列表支持 CameCase 和 kebab 大小写属性名称 .
带有允许列表的配置 :
{
"rules": {
"vanilla-extract/no-px-unit": ["error", { "allow": ["borderWidth", "outline-offset"] }]
}
}
在此之前:
import { style } from '@vanilla-extract/css';
export const box = style({
marginTop: '8px',
padding: '16px',
selectors: {
'&:hover': { gap: '4px' },
},
});
在(建议用雷姆显示的固定)之后:
import { style } from '@vanilla-extract/css';
export const box = style({
marginTop: '8rem',
padding: '16rem',
selectors: {
'&:hover': { gap: '4rem' },
},
});
香草-提取/无拖动-零
此规则不允许在 vanilla- extract 样式对象中, 在数字 CSS 值中排入零 。 它有助于保持清洁 和更加一致的CSS,从小数中去除不必要的后缀零.
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const myStyle = style({
margin: '1.0px',
padding: '2.50rem',
opacity: 1.0,
lineHeight: 2.50,
width: '0.0em',
transition: 'all 0.30s ease',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
margin: '1px',
padding: '2.5rem',
opacity: 1,
lineHeight: 2.5,
width: '0',
transition: 'all 0.3s ease',
});
香草-抽取/无单位值
此规则不允许 CSS 属性的单位数字值, 这些属性需要 vanilla-extract 样式对象中的单位 。 它帮助偏爱显性单位的团队避免混淆,因为香草-取出会自动将无单位数字转换为: px 在运行时间.
说明: 这是一个可选规则(在推荐配置中未启用). 只有当您的团队更喜欢清晰的单位 而不是香草的自动复制时, 才能启用它 px 转换.
带有允许属性的配置 :
{
"rules": {
"vanilla-extract/no-unitless-values": ["warn", { "allow": ["width", "height"] }]
}
}
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const myStyle = style({
width: 100,
margin: 20,
padding: 10.5,
height: '50',
top: '-10',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
width: '100px',
margin: '20px',
padding: 0,
height: '50rem',
opacity: 0.5, // opacity accepts unitless values
lineHeight: 1.5, // line-height accepts unitless values
zIndex: 10, // z-index accepts unitless values
});
需要单位属性 :
- 框型号 :
width, (中文(简体) ),height, (中文(简体) ),minWidth, (中文(简体) ),maxWidth, (中文(简体) ),minHeight, (中文(简体) ),maxHeight, (中文(简体) ),min-width, (中文(简体) ),max-width, (中文(简体) ),min-height, (中文(简体) ),max-height - 间距 :
margin, (中文(简体) ),marginTop, (中文(简体) ),marginRight, (中文(简体) ),marginBottom, (中文(简体) ),marginLeft, (中文(简体) ),marginBlock, (中文(简体) ),marginBlockStart, (中文(简体) ),marginBlockEnd, (中文(简体) ),marginInline, (中文(简体) ),marginInlineStart, (中文(简体) ),marginInlineEnd, (中文(简体) ),margin-top, (中文(简体) ),margin-right, (中文(简体) ),margin-bottom, (中文(简体) ),margin-left, (中文(简体) ),margin-block, (中文(简体) ),margin-block-start, (中文(简体) ),margin-block-end, (中文(简体) ),margin-inline, (中文(简体) ),margin-inline-start, (中文(简体) ),margin-inline-end, (中文(简体) ),padding, (中文(简体) ),paddingTop, (中文(简体) ),paddingRight, (中文(简体) ),paddingBottom, (中文(简体) ),paddingLeft, (中文(简体) ),paddingBlock, (中文(简体) ),paddingBlockStart, (中文(简体) ),paddingBlockEnd, (中文(简体) ),paddingInline, (中文(简体) ),paddingInlineStart, (中文(简体) ),paddingInlineEnd, (中文(简体) ),padding-top, (中文(简体) ),padding-right, (中文(简体) ),padding-bottom, (中文(简体) ),padding-left, (中文(简体) ),padding-block, (中文(简体) ),padding-block-start, (中文(简体) ),padding-block-end, (中文(简体) ),padding-inline, (中文(简体) ),padding-inline-start, (中文(简体) ),padding-inline-end - 位置设置 :
top, (中文(简体) ),right, (中文(简体) ),bottom, (中文(简体) ),left, (中文(简体) ),inset, (中文(简体) ),insetBlock, (中文(简体) ),insetBlockStart, (中文(简体) ),insetBlockEnd, (中文(简体) ),insetInline, (中文(简体) ),insetInlineStart, (中文(简体) ),insetInlineEnd, (中文(简体) ),inset-block, (中文(简体) ),inset-block-start, (中文(简体) ),inset-block-end, (中文(简体) ),inset-inline, (中文(简体) ),inset-inline-start, (中文(简体) ),inset-inline-end - 边框 :
borderWidth, (中文(简体) ),borderTopWidth, (中文(简体) ),borderRightWidth, (中文(简体) ),borderBottomWidth, (中文(简体) ),borderLeftWidth, (中文(简体) ),borderBlockWidth, (中文(简体) ),borderBlockStartWidth, (中文(简体) ),borderBlockEndWidth, (中文(简体) ),borderInlineWidth, (中文(简体) ),borderInlineStartWidth, (中文(简体) ),borderInlineEndWidth, (中文(简体) ),border-width, (中文(简体) ),border-top-width, (中文(简体) ),border-right-width, (中文(简体) ),border-bottom-width, (中文(简体) ),border-left-width, (中文(简体) ),border-block-width, (中文(简体) ),border-block-start-width, (中文(简体) ),border-block-end-width, (中文(简体) ),border-inline-width, (中文(简体) ),border-inline-start-width, (中文(简体) ),border-inline-end-width, (中文(简体) ),borderRadius, (中文(简体) ),borderTopLeftRadius, (中文(简体) ),borderTopRightRadius, (中文(简体) ),borderBottomLeftRadius, (中文(简体) ),borderBottomRightRadius, (中文(简体) ),borderStartStartRadius, (中文(简体) ),borderStartEndRadius, (中文(简体) ),borderEndStartRadius, (中文(简体) ),borderEndEndRadius, (中文(简体) ),border-radius, (中文(简体) ),border-top-left-radius, (中文(简体) ),border-top-right-radius, (中文(简体) ),border-bottom-left-radius, (中文(简体) ),border-bottom-right-radius, (中文(简体) ),border-start-start-radius, (中文(简体) ),border-start-end-radius, (中文(简体) ),border-end-start-radius, (中文(简体) ),border-end-end-radius - 类型 :
fontSize, (中文(简体) ),font-size, (中文(简体) ),letterSpacing, (中文(简体) ),letter-spacing, (中文(简体) ),wordSpacing, (中文(简体) ),word-spacing, (中文(简体) ),textIndent, (中文(简体) ),text-indent - 布局 :
gap, (中文(简体) ),rowGap, (中文(简体) ),columnGap, (中文(简体) ),row-gap, (中文(简体) ),column-gap, (中文(简体) ),flexBasis, (中文(简体) ),flex-basis - 大纲 :
outlineWidth, (中文(简体) ),outline-width, (中文(简体) ),outlineOffset, (中文(简体) ),outline-offset - 其他情况:
blockSize, (中文(简体) ),inlineSize, (中文(简体) ),minBlockSize, (中文(简体) ),maxBlockSize, (中文(简体) ),minInlineSize, (中文(简体) ),maxInlineSize, (中文(简体) ),block-size, (中文(简体) ),inline-size, (中文(简体) ),min-block-size, (中文(简体) ),max-block-size, (中文(简体) ),min-inline-size, (中文(简体) ),max-inline-size
接受无单位值的属性 :
- 常见 :
opacity, (中文(简体) ),zIndex, (中文(简体) ),z-index, (中文(简体) ),lineHeight, (中文(简体) ),line-height, (中文(简体) ),flexGrow, (中文(简体) ),flex-grow, (中文(简体) ),flexShrink, (中文(简体) ),flex-shrink, (中文(简体) ),order, (中文(简体) ),fontWeight, (中文(简体) ),font-weight, (中文(简体) ),zoom - 动画:
animationIterationCount, (中文(简体) ),animation-iteration-count - 布局 :
columnCount, (中文(简体) ),column-count, (中文(简体) ),orphans, (中文(简体) ),widows - 网格 :
gridColumn, (中文(简体) ),grid-column, (中文(简体) ),gridColumnEnd, (中文(简体) ),grid-column-end, (中文(简体) ),gridColumnStart, (中文(简体) ),grid-column-start, (中文(简体) ),gridRow, (中文(简体) ),grid-row, (中文(简体) ),gridRowEnd, (中文(简体) ),grid-row-end, (中文(简体) ),gridRowStart, (中文(简体) ),grid-row-start - SVG : (英语)
fillOpacity, (中文(简体) ),fill-opacity, (中文(简体) ),strokeOpacity, (中文(简体) ),stroke-opacity, (中文(简体) ),strokeMiterlimit, (中文(简体) ),stroke-miterlimit
为什么用这个规则?
当香草-提取物安全地将单数转换为 px,一些团队更喜欢明确的单位,因为:
- 它使预定单位清晰(px, rem,em,%等)
- 它防止在选择雷姆或其他单位时意外使用px
- 它符合中央支助系统关于明确各单位的最佳做法
自动修补 : 不详。 由于不同的队伍更喜欢不同的单位(px,rem,em,%),所以您必须手动添加首选的单位.
香草-抽取/无名单位
此规则强制在香草-提取样式对象中使用有效的 CSS 单元. 防止打字和非标准单位 ,这可能造成样式问题或浏览器相容性问题.
// ❌ Incorrect
import { style, globalStyle, recipe } from '@vanilla-extract/css';
export const invalidStyle = style({
margin: '5abc', // Non-existent unit
fontSize: '1.5rems', // Typo in unit
});
export const myRecipe = recipe({
variants: {
size: {
large: { padding: '4xm' }, // Invalid unit
},
},
});
// ✅ Correct
import { style, globalStyle, recipe } from '@vanilla-extract/css';
export const validStyle = style({
margin: '5rem',
fontSize: '1.5rem',
});
export const myRecipe = recipe({
variants: {
size: {
large: { padding: '4em' },
},
},
});
香草-抽取/零单位
此规则强制删除香草-提取样式对象中零值的不必要的单位. 帮助维持 通过去除值为零的冗余单位来更清洁更一致的CSS.
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const myStyle = style({
margin: '0px',
padding: '0rem',
width: '0%',
height: '0vh',
top: '-0em',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const myStyle = style({
margin: '0',
padding: '0',
width: '0',
height: '0',
top: '0',
});
香草-摘录/优先逻辑-财产
此规则强制使用 CSS 逻辑属性而非香草-提取样式声明中的物理(向)属性. 逻辑属性适应了不同的书写方向(LTR/RTL)和书写模式,使你的作风更加国际化而友好. 支持 140+ 属性映射跨边距,贴地,边框,内置,大小,外溢,和滚动属性. 配置允许列表允许您通过 allow 选项(支持骆驼Case和kebab-case).
带有允许列表的配置 :
{
"rules": {
"vanilla-extract/prefer-logical-properties": ["error", { "allow": ["top", "left"] }]
}
}
// ❌ Incorrect
import { style } from '@vanilla-extract/css';
export const box = style({
marginLeft: '1rem',
paddingTop: '2rem',
width: '100%',
borderRight: '1px solid',
textAlign: 'left',
});
// ✅ Correct
import { style } from '@vanilla-extract/css';
export const box = style({
marginInlineStart: '1rem',
paddingBlockStart: '2rem',
inlineSize: '100%',
borderInlineEnd: '1px solid',
textAlign: 'start',
});
香草-摘录/预选主题
执行主题符号而不是硬码的 CSS 值. 分析您的主题合同文件并给出建议 特定符号 当找到匹配时.
选项 :
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
themeContracts | string[] | [] | 主题合同文件路径( 相对于项目根或绝对) |
checkColors | boolean | true | 检查颜色( hex, rgb, hsl, 命名) |
checkSpacing | boolean | true | 检查间隔( 边距、 垫入、 间隙、 宽度、 高度) |
checkFontSizes | boolean | true | 检查字体大小( fontSize, 行高) |
checkBorderRadius | boolean | true | 检查边框半径值 |
checkBorderWidths | boolean | true | 检查边框宽度(包括 border 缩写) |
checkShadows | boolean | true | 检查阴影( 框 Shadow, 文本 Shadow, 过滤器) |
checkZIndex | boolean | true | 检查 Z 索引值 |
checkOpacity | boolean | true | 检查不透明值 |
checkFontWeights | boolean | true | 检查字体权重( 数字并命名) |
checkTransitions | boolean | true | 检查转换和动画 |
allowedValues | string[] | [] | 白色列表特定值( 例如 ), ["0", "auto", "100vh"](中文(简体) ) |
allowedProperties | string[] | [] | 跳过检查特定属性 |
autoFix | boolean | false | 当一个符号匹配时自动修正 |
remBase | number | 16 | 基本字体大小 rem() 计算 |
checkHelperFunctions | boolean | false | 检查助手的呼叫像 rem(48), (中文(简体) ), `${rem(4)}` |
抚养关系说明
本规则使用安全表达式评估器可选择分析帮助者在 checkHelperFunctions 已启用。 为此,插件内部依赖 @babel/parser 财务报告和审定财务报表 @babel/types 以解析小表达式片段(例如模板字节, rem() 电话). 这些被运出为插件依赖,所以用户不需要手动安装. 它们只有在 checkHelperFunctions 打开.
示例
{
"rules": {
"vanilla-extract/prefer-theme-tokens": ["error", {
"themeContracts": ["./src/theme.css.ts"],
"checkColors": true,
"checkSpacing": true,
"allowedValues": ["0", "auto", "100%"],
"allowedProperties": ["borderWidth"],
"autoFix": false,
"checkHelperFunctions": false
}]
}
}
如何运作:
-
分析主题合同 - 阅读主题文件并评价计算值:
rem(16)→"1rem"`${rem(4)} ${rem(8)}`→"0.25rem 0.5rem"- 算术表达式
-
检测硬编码值 - 检查字面、数字和(可选的)帮助函数:
color: '#0055FF' // ❌ Always flagged padding: '16px' // ❌ Always flagged opacity: 0.5 // ❌ Always flagged (numeric literal) margin: rem(48) // ❌ Only with checkHelperFunctions: true boxShadow: `${rem(4)}...` // ❌ Only with checkHelperFunctions: true -
建议特定符号 - 将值与主题符号相匹配:
❌ Hard-coded color '#0055FF'. Use theme token: vars.colors.brand ❌ Hard-coded padding '16px'. Use theme token: vars.spacing.md- 单一匹配: 显示一个建议 + 自动修正( 如果启用)
- 多个匹配: 全部显示为快速修复选项
主题合同实例:
// theme.css.ts
export const [themeClass, vars] = createTheme({
colors: { brand: '#0055FF', text: '#1f2937' },
spacing: { sm: '8px', md: '16px' },
});
// styles.css.ts
export const button = style({
backgroundColor: '#0055FF', // ❌ Use vars.colors.brand
padding: '8px', // ❌ Use vars.spacing.sm
});
帮助函数检测 :
默认情况下, 只检查 字节启用 checkHelperFunctions: true 还检查计算值:
// checkHelperFunctions: false (default)
padding: rem(48) // ✅ Not flagged
padding: '3rem' // ❌ Flagged
// checkHelperFunctions: true
padding: rem(48) // ❌ Flagged if theme has matching token
padding: '3rem' // ❌ Flagged if theme has matching token
说明: Opt-in rule (不在推荐配置中). 准备执行设计符时启用 .
字体面部声明
对于 fontFace 财务报告和审定财务报表 globalFontFace API 调用,所有三种订购规则(同心同德、同心同德)都执行
同一特殊订单:
- 这个
src属性总是先出现 - 所有剩余属性按字母顺序排序
采用这种特殊处理方式的原因是:
- 这个
src属性是字体面额声明中最重要的属性 - 一致订购提高了这些特定API的可读性
- 字体相关属性具有专门性,并受益于标准化订购
// ✅ Correct ordering for font faces
export const theFont = fontFace({
src: ['url("/fonts/MyFont.woff2") format("woff2")', 'url("/fonts/MyFont.woff") format("woff")'],
ascentOverride: '90%',
descentOverride: '10%',
fontDisplay: 'swap',
fontFeatureSettings: '"liga" 1',
fontStretch: 'normal',
// ...other properties in alphabetical order
});
有观点,但这是它是什么。 如果有人有更好的订单建议 告诉我!
同心CSS模型
以下是所有可用的团体列表 来自提供 同心团 数组 :
- 框大小
- 职位
- 显示
- 弹性
- 网格
- 对齐
- 栏
- 转换
- 过渡
- 可见度
- 形状
- 边距
- 大纲
- 边框
- 框阴影
- 背景情况
- 光标
- 粘贴
- 维度
- 溢出额
- 列表样式
- 图表
- 动画
- 文本
- 文本间距
- 字体
- 内容
- 计数器
- 间断
这些组别代表了CSS属性的不同类别,由外到内按同心排列. 每个组包含相关的CSS属性,会影响元素的造型和布局的特定方面.
路线图
路线图概述了该项目的现状和未来计划:
已完成的里程碑
- 初始发布时支持字母,同心,以及自定义组 CSS 命令.
- 将自动固定能力整合入ESLint.
- 支持多个香草-提取API(例如,
style, (中文(简体) ),styleVariants, (中文(简体) ),recipe, (中文(简体) ),globalStyle, (中文(简体) ),fontFace(见a/c.5/49/70,附件). no-empty-style-blocks规则不允许空块.- 为插件推荐的 ESLint 配置 .
no-zero-unit规则,当值为零时,取消单位.no-unknown-unit规则不允许未知单位.no-trailing-zero规则不允许在数字后出现零.- 支持通过扩展字段使用插件推荐的配置( 如在 问题3(中文(简体) )
- 全面规则测试.
no-px-unit不允许使用px带有可配置的白名单的单位.prefer-logical-properties规则强制使用逻辑属性.prefer-theme-tokens规则执行主题符号而不是硬编码值,用于颜色、间隔、字体大小、边框半径、边框宽度、阴影、z-index、不透明、字体权重和过渡/动画(可选择评价帮助器函数和模板文字).no-unitless-values规则不允许需要单位的 CSS 属性的无单位数值.
即将到来的特点
property-unit-match规则执行 CSS 属性规格的有效单位. 说明: 此特性将仅是 如果社区有足够的兴趣就执行.- 选择在用户定义的同心组合内按字母顺序排序属性,而不是遵循同心组合 秩序。 秩序. 说明:这个特性只有在社区有足够的兴趣的情况下才会被实施.
捐款
当然,欢迎所有善意的贡献! 请随意提交拉动请求或通过 GitHub问题.
许可证
这个项目根据麻省理工学院许可证颁发——见 自由主义 详细文件.