@moluoxixi/css-module-global-root-plugin 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +317 -0
- package/es/index.d.ts +9 -0
- package/es/index.mjs +53 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# cssModuleGlobalRootPlugin
|
|
2
|
+
|
|
3
|
+
PostCSS 插件:处理 CSS Module 文件中的 `:root` 选择器。
|
|
4
|
+
|
|
5
|
+
## 功能说明
|
|
6
|
+
|
|
7
|
+
该插件专门用于处理 CSS Module 文件中的 `:root` 选择器,提供以下功能:
|
|
8
|
+
|
|
9
|
+
1. **`:root` 处理**:根据配置移除或替换 `:root` 选择器
|
|
10
|
+
2. **CSS Module 支持**:仅处理后缀为 `.module.css`、`.module.scss`、`.module.less`、`.module.sass`、`.module.styl` 的文件
|
|
11
|
+
3. **特殊规则保护**:保护 `:global :root` 开头的选择器不被处理
|
|
12
|
+
4. **灵活配置**:支持两种处理模式(移除或替换)
|
|
13
|
+
|
|
14
|
+
## 使用场景
|
|
15
|
+
|
|
16
|
+
在 CSS Module 中,当需要在 `:global()` 作用域内定义全局 CSS 变量时,使用 `:root` 会导致选择器过于具体。该插件可以帮助调整作用域,使 CSS 变量能够正确应用。
|
|
17
|
+
|
|
18
|
+
## 安装
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @moluoxixi/utils
|
|
22
|
+
# 或
|
|
23
|
+
yarn add @moluoxixi/utils
|
|
24
|
+
# 或
|
|
25
|
+
pnpm add @moluoxixi/utils
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 使用方法
|
|
29
|
+
|
|
30
|
+
### 在 Vite 配置中使用
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { defineConfig } from 'vite'
|
|
34
|
+
import cssModuleGlobalRootPlugin from '@moluoxixi/utils/cssModuleGlobalRootPlugin/index.mts'
|
|
35
|
+
|
|
36
|
+
export default defineConfig({
|
|
37
|
+
css: {
|
|
38
|
+
postcss: {
|
|
39
|
+
plugins: [
|
|
40
|
+
cssModuleGlobalRootPlugin(),
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 配置选项
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { defineConfig } from 'vite'
|
|
51
|
+
import cssModuleGlobalRootPlugin from '@moluoxixi/utils/cssModuleGlobalRootPlugin/index.mts'
|
|
52
|
+
|
|
53
|
+
export default defineConfig({
|
|
54
|
+
css: {
|
|
55
|
+
postcss: {
|
|
56
|
+
plugins: [
|
|
57
|
+
cssModuleGlobalRootPlugin({
|
|
58
|
+
removeRoot: true, // 默认值:移除 :root
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 配置选项说明
|
|
67
|
+
|
|
68
|
+
### CssModuleGlobalRootPluginOptions
|
|
69
|
+
|
|
70
|
+
| 选项 | 说明 | 类型 | 默认值 |
|
|
71
|
+
| --- | --- | --- | --- |
|
|
72
|
+
| `removeRoot` | 是否移除 `:root` | `boolean` | `true` |
|
|
73
|
+
|
|
74
|
+
### removeRoot 说明
|
|
75
|
+
|
|
76
|
+
- **`true`(默认)**:移除 `:root`,查找选择器中的 `:global :root`,替换为 `:global`
|
|
77
|
+
- 例如:`.root :global :root` → `.root :global`
|
|
78
|
+
- **`false`**:将 `:root` 替换为 `*`
|
|
79
|
+
- 例如:`.root :root` → `.root *`
|
|
80
|
+
|
|
81
|
+
## 处理规则
|
|
82
|
+
|
|
83
|
+
### 1. 文件类型识别
|
|
84
|
+
|
|
85
|
+
插件仅处理以下文件类型:
|
|
86
|
+
- `.module.css`
|
|
87
|
+
- `.module.scss`
|
|
88
|
+
- `.module.less`
|
|
89
|
+
- `.module.sass`
|
|
90
|
+
- `.module.styl`
|
|
91
|
+
|
|
92
|
+
### 2. 特殊规则保护
|
|
93
|
+
|
|
94
|
+
以下选择器不会被处理(保持原样):
|
|
95
|
+
- `:global :root` 开头的选择器
|
|
96
|
+
|
|
97
|
+
### 3. 处理模式
|
|
98
|
+
|
|
99
|
+
#### 模式 1:移除 `:root`(默认)
|
|
100
|
+
|
|
101
|
+
**输入:**
|
|
102
|
+
```css
|
|
103
|
+
.root :global :root {
|
|
104
|
+
--primary: #007bff;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.root :root {
|
|
108
|
+
--secondary: #6c757d;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**输出:**
|
|
113
|
+
```css
|
|
114
|
+
.root :global {
|
|
115
|
+
--primary: #007bff;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.root {
|
|
119
|
+
--secondary: #6c757d;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### 模式 2:替换为 `*`
|
|
124
|
+
|
|
125
|
+
**输入:**
|
|
126
|
+
```css
|
|
127
|
+
.root :global :root {
|
|
128
|
+
--primary: #007bff;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.root :root {
|
|
132
|
+
--secondary: #6c757d;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**输出:**
|
|
137
|
+
```css
|
|
138
|
+
.root :global * {
|
|
139
|
+
--primary: #007bff;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.root * {
|
|
143
|
+
--secondary: #6c757d;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 使用示例
|
|
148
|
+
|
|
149
|
+
### 示例 1:基本使用(移除 :root)
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { defineConfig } from 'vite'
|
|
153
|
+
import cssModuleGlobalRootPlugin from '@moluoxixi/utils/cssModuleGlobalRootPlugin/index.mts'
|
|
154
|
+
|
|
155
|
+
export default defineConfig({
|
|
156
|
+
css: {
|
|
157
|
+
postcss: {
|
|
158
|
+
plugins: [
|
|
159
|
+
cssModuleGlobalRootPlugin({
|
|
160
|
+
removeRoot: true, // 默认值
|
|
161
|
+
}),
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**CSS Module 文件(styles.module.scss):**
|
|
169
|
+
```scss
|
|
170
|
+
.root :global :root {
|
|
171
|
+
--primary-color: #007bff;
|
|
172
|
+
--secondary-color: #6c757d;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.root :root {
|
|
176
|
+
--text-color: #333;
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**处理后:**
|
|
181
|
+
```scss
|
|
182
|
+
.root :global {
|
|
183
|
+
--primary-color: #007bff;
|
|
184
|
+
--secondary-color: #6c757d;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.root {
|
|
188
|
+
--text-color: #333;
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 示例 2:替换为 * 模式
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { defineConfig } from 'vite'
|
|
196
|
+
import cssModuleGlobalRootPlugin from '@moluoxixi/utils/cssModuleGlobalRootPlugin/index.mts'
|
|
197
|
+
|
|
198
|
+
export default defineConfig({
|
|
199
|
+
css: {
|
|
200
|
+
postcss: {
|
|
201
|
+
plugins: [
|
|
202
|
+
cssModuleGlobalRootPlugin({
|
|
203
|
+
removeRoot: false,
|
|
204
|
+
}),
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
})
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**CSS Module 文件(styles.module.scss):**
|
|
212
|
+
```scss
|
|
213
|
+
.root :global :root {
|
|
214
|
+
--primary-color: #007bff;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.root :root {
|
|
218
|
+
--text-color: #333;
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**处理后:**
|
|
223
|
+
```scss
|
|
224
|
+
.root :global * {
|
|
225
|
+
--primary-color: #007bff;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.root * {
|
|
229
|
+
--text-color: #333;
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 示例 3:在 Vue 组件中使用
|
|
234
|
+
|
|
235
|
+
```vue
|
|
236
|
+
<template>
|
|
237
|
+
<div :class="$style.root">
|
|
238
|
+
<h1>标题</h1>
|
|
239
|
+
</div>
|
|
240
|
+
</template>
|
|
241
|
+
|
|
242
|
+
<style module>
|
|
243
|
+
.root :global :root {
|
|
244
|
+
--primary-color: #007bff;
|
|
245
|
+
--font-size: 16px;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.root :root {
|
|
249
|
+
--text-color: #333;
|
|
250
|
+
}
|
|
251
|
+
</style>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**处理后:**
|
|
255
|
+
```vue
|
|
256
|
+
<style module>
|
|
257
|
+
.root :global {
|
|
258
|
+
--primary-color: #007bff;
|
|
259
|
+
--font-size: 16px;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.root {
|
|
263
|
+
--text-color: #333;
|
|
264
|
+
}
|
|
265
|
+
</style>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## 工作原理
|
|
269
|
+
|
|
270
|
+
1. **文件检测**:插件检查文件路径,仅处理 CSS Module 文件
|
|
271
|
+
2. **选择器遍历**:遍历所有 CSS 规则的选择器
|
|
272
|
+
3. **特殊规则检查**:跳过 `:global :root` 开头的选择器
|
|
273
|
+
4. **`:root` 处理**:根据配置移除或替换 `:root`
|
|
274
|
+
5. **选择器更新**:更新处理后的选择器
|
|
275
|
+
|
|
276
|
+
## 注意事项
|
|
277
|
+
|
|
278
|
+
1. **仅处理 CSS Module 文件**:插件只处理 `.module.*` 后缀的文件,不影响其他 CSS 文件
|
|
279
|
+
2. **保护特殊规则**:`:global :root` 开头的选择器不会被处理,保持原样
|
|
280
|
+
3. **不修改其他内容**:插件只修改选择器,不修改 CSS 变量、样式属性等内容
|
|
281
|
+
4. **PostCSS 插件**:这是一个 PostCSS 插件,需要在 PostCSS 配置中使用
|
|
282
|
+
5. **处理时机**:插件在 CSS Module 处理完毕后执行,处理的是已经转换后的选择器
|
|
283
|
+
|
|
284
|
+
## 调试
|
|
285
|
+
|
|
286
|
+
插件会在控制台输出处理信息:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
[css-module-global-root] 移除 :root: ".root :global :root" -> ".root :global"
|
|
290
|
+
[css-module-global-root] 替换为 *: ".root :root" -> ".root *"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
可以通过这些日志了解插件的工作情况。
|
|
294
|
+
|
|
295
|
+
## 常见问题
|
|
296
|
+
|
|
297
|
+
### Q: 为什么我的 CSS Module 文件没有被处理?
|
|
298
|
+
|
|
299
|
+
A: 检查以下几点:
|
|
300
|
+
1. 确保文件后缀是 `.module.css`、`.module.scss` 等
|
|
301
|
+
2. 确保插件已正确配置在 PostCSS 插件列表中
|
|
302
|
+
3. 检查文件路径是否正确
|
|
303
|
+
|
|
304
|
+
### Q: `:global :root` 为什么没有被处理?
|
|
305
|
+
|
|
306
|
+
A: 这是设计如此,`:global :root` 开头的选择器会被保护,不会被处理。如果需要处理,可以修改选择器格式。
|
|
307
|
+
|
|
308
|
+
### Q: 插件会影响其他 CSS 文件吗?
|
|
309
|
+
|
|
310
|
+
A: 不会。插件只处理 CSS Module 文件(`.module.*` 后缀),不会影响其他 CSS 文件。
|
|
311
|
+
|
|
312
|
+
### Q: 如何选择处理模式?
|
|
313
|
+
|
|
314
|
+
A:
|
|
315
|
+
- 如果希望 CSS 变量作用域更广,使用 `removeRoot: true`(默认)
|
|
316
|
+
- 如果希望保持选择器的语义性,使用 `removeRoot: false`
|
|
317
|
+
|
package/es/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from 'postcss';
|
|
2
|
+
export interface CssModuleGlobalRootPluginOptions {
|
|
3
|
+
removeRoot?: boolean;
|
|
4
|
+
}
|
|
5
|
+
declare function cssModuleGlobalRootPlugin(options?: CssModuleGlobalRootPluginOptions): Plugin;
|
|
6
|
+
declare namespace cssModuleGlobalRootPlugin {
|
|
7
|
+
var postcss: boolean;
|
|
8
|
+
}
|
|
9
|
+
export default cssModuleGlobalRootPlugin;
|
package/es/index.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function cssModuleGlobalRootPlugin(options = {}) {
|
|
2
|
+
const { removeRoot = true } = options;
|
|
3
|
+
return {
|
|
4
|
+
postcssPlugin: "css-module-global-root",
|
|
5
|
+
Once(root, { result }) {
|
|
6
|
+
var _a;
|
|
7
|
+
const filePath = ((_a = result.root.source) == null ? void 0 : _a.input.from) || "";
|
|
8
|
+
const isCssModule = /\.module\.(?:css|scss|less|sass|styl)$/i.test(filePath);
|
|
9
|
+
if (!isCssModule) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const specialRules = [
|
|
13
|
+
/^\s*:global\s+:root/
|
|
14
|
+
];
|
|
15
|
+
function isSpecialRule(selector) {
|
|
16
|
+
const trimmed = selector.trim();
|
|
17
|
+
for (const pattern of specialRules) {
|
|
18
|
+
if (pattern.test(trimmed)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
root.walkRules((rule) => {
|
|
25
|
+
const originalSelector = rule.selector;
|
|
26
|
+
if (!originalSelector.includes(":root")) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const selectors = Array.isArray(rule.selectors) && rule.selectors.length > 0 ? rule.selectors : [originalSelector];
|
|
30
|
+
const transformedSelectors = selectors.map((selector) => {
|
|
31
|
+
if (!selector.includes(":root")) {
|
|
32
|
+
return selector;
|
|
33
|
+
}
|
|
34
|
+
if (isSpecialRule(selector)) {
|
|
35
|
+
return selector;
|
|
36
|
+
}
|
|
37
|
+
if (removeRoot) {
|
|
38
|
+
return selector.replace(/(\S+)\s+:global\s+:root/g, "$1 :global");
|
|
39
|
+
}
|
|
40
|
+
return selector.replace(/:root/g, "*");
|
|
41
|
+
});
|
|
42
|
+
const newSelector = transformedSelectors.join(", ");
|
|
43
|
+
if (newSelector !== originalSelector) {
|
|
44
|
+
rule.selector = newSelector;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
cssModuleGlobalRootPlugin.postcss = true;
|
|
51
|
+
export {
|
|
52
|
+
cssModuleGlobalRootPlugin as default
|
|
53
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@moluoxixi/css-module-global-root-plugin",
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "cssModuleGlobalRootPlugin 组件",
|
|
5
|
+
"sideEffects": [
|
|
6
|
+
"*.css",
|
|
7
|
+
"*.scss"
|
|
8
|
+
],
|
|
9
|
+
"peerDependencies": {},
|
|
10
|
+
"dependencies": {},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"module": "es/index.mjs",
|
|
16
|
+
"types": "es/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./es": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./es/index.d.ts",
|
|
21
|
+
"default": "./es/index.mjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
".": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./es/index.d.ts",
|
|
27
|
+
"default": "./es/index.mjs"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|