eslint-plugin-light 1.0.19 → 1.0.20

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## <small>1.0.20 (2025-12-18)</small>
2
+
3
+ * feat(project-config-pixui): add try-catch for version-info ([775fb7b](https://github.com/novlan1/plugin-light/commits/775fb7b))
4
+
5
+
6
+
1
7
  ## <small>1.0.19 (2025-12-12)</small>
2
8
 
3
9
  * chore: update docs ([dc64df7](https://github.com/novlan1/plugin-light/commits/dc64df7))
package/README.md CHANGED
@@ -592,6 +592,71 @@ module.exports = {
592
592
  | ------ | -------- | ----------------------------------- |
593
593
  | regexp | 匹配正则 | `/\[[^\](]*\.\d+[a-zA-Z]+[^\]]*\]/` |
594
594
 
595
+ ### 4.17. valid-pmd-import
596
+
597
+ 禁止在 `packages/xx` 目录下引入对应的 `pmd-xx` 包,需要使用相对路径。
598
+
599
+ 这个规则主要用于 monorepo 项目中,防止包内部引入自己的发布版本,而是使用相对路径引入源码,避免循环依赖和版本不一致问题。
600
+
601
+ 比如,在 `packages/components` 目录下:
602
+
603
+ ```js
604
+ // ❌ 错误:引入自己的包名
605
+ import { Button } from 'pmd-components';
606
+ const utils = require('pmd-components/lib/utils');
607
+
608
+ // ✅ 正确:使用相对路径
609
+ import { Button } from '../src';
610
+ const utils = require('../../src/utils');
611
+ ```
612
+
613
+ 如果加了 `--fix`,会被自动转换为相对路径。
614
+
615
+ Usage:
616
+
617
+ ```js
618
+ // .eslintrc.js
619
+
620
+ module.exports = {
621
+ plugins: [
622
+ 'light',
623
+ ],
624
+ rules: {
625
+ 'light/valid-pmd-import': 2,
626
+ },
627
+ }
628
+ ```
629
+
630
+ 配置选项:
631
+
632
+ | 字段 | 说明 | 默认值 |
633
+ | ------- | ---------------- | ------- |
634
+ | baseDir | 包源码的基础目录 | `'src'` |
635
+
636
+ 例如,如果你的包源码不在 `src` 目录:
637
+
638
+ ```js
639
+ // .eslintrc.js
640
+
641
+ module.exports = {
642
+ plugins: [
643
+ 'light',
644
+ ],
645
+ rules: {
646
+ 'light/valid-pmd-import': [2, {
647
+ baseDir: 'lib'
648
+ }],
649
+ },
650
+ }
651
+ ```
652
+
653
+ 该规则会检查以下导入方式:
654
+
655
+ - ES6 `import` 语句
656
+ - CommonJS `require()` 调用
657
+ - 动态 `import()` 表达式
658
+ - `export ... from` 语句
659
+
595
660
  ## 5. 更新日志
596
661
 
597
662
  [点此查看](./CHANGELOG.md)
@@ -0,0 +1,170 @@
1
+ const path = require('path');
2
+
3
+ module.exports = {
4
+ meta: {
5
+ type: 'problem',
6
+ docs: {
7
+ description: '禁止在 packages/xx 目录下引入对应的 pmd-xx 包,需要使用相对路径',
8
+ category: 'Best Practices',
9
+ recommended: false,
10
+ },
11
+ fixable: 'code',
12
+ schema: [
13
+ {
14
+ type: 'object',
15
+ properties: {
16
+ baseDir: {
17
+ type: 'string',
18
+ description: '基础目录,默认为 src',
19
+ default: 'src',
20
+ },
21
+ },
22
+ additionalProperties: false,
23
+ },
24
+ ],
25
+ },
26
+
27
+ create(context) {
28
+ const options = context.options[0] || {};
29
+ const baseDir = options.baseDir || 'src';
30
+
31
+ const filename = context.getFilename();
32
+ const absolutePath = path.resolve(filename);
33
+
34
+ // 提取当前包名
35
+ const getCurrentPackage = (filePath) => {
36
+ const normalizedPath = path.normalize(filePath);
37
+ const match = normalizedPath.match(/packages[\\/]([^\\/]+)/);
38
+ return match ? match[1] : null;
39
+ };
40
+
41
+ const currentPackage = getCurrentPackage(absolutePath);
42
+ if (!currentPackage) {
43
+ return {};
44
+ }
45
+
46
+ const pmdPackageName = `pmd-${currentPackage}`;
47
+
48
+ /**
49
+ * 获取应该使用的相对路径
50
+ */
51
+ const getRelativePath = (importPath, currentFilePath) => {
52
+ // 移除包名前缀
53
+ const subPath = importPath.replace(pmdPackageName, '').replace(/^\/lib/, '');
54
+
55
+ const currentDir = path.dirname(currentFilePath);
56
+
57
+ // 查找当前包的根目录
58
+ const parts = absolutePath.split(path.sep);
59
+ const packageIndex = parts.findIndex((part, index) => part === 'packages' && parts[index + 1] === currentPackage);
60
+
61
+ if (packageIndex === -1) {
62
+ return '.'; // 回退到当前目录
63
+ }
64
+
65
+ // 构建包的根路径
66
+ const packageRootParts = parts.slice(0, packageIndex + 2);
67
+ const packageRoot = packageRootParts.join(path.sep);
68
+
69
+ // 构建目标路径
70
+ const targetRelative = subPath ? `${baseDir}${subPath}` : baseDir;
71
+ const targetPath = path.join(packageRoot, targetRelative);
72
+
73
+ // 计算相对路径
74
+ let relativePath = path.relative(currentDir, targetPath);
75
+
76
+ // 处理特殊情况
77
+ if (relativePath === '') {
78
+ relativePath = '.';
79
+ } else if (!relativePath.startsWith('.')) {
80
+ relativePath = `./${relativePath}`;
81
+ }
82
+
83
+ // 标准化路径分隔符
84
+ relativePath = relativePath.replace(/\\/g, '/');
85
+
86
+ return relativePath;
87
+ };
88
+
89
+ /**
90
+ * 获取引号字符
91
+ */
92
+ const getQuoteChar = (node, sourceCode) => {
93
+ if (node.source) {
94
+ const text = sourceCode.getText(node.source);
95
+ return text[0]; // 第一个字符应该是引号
96
+ } if (node.arguments && node.arguments[0]) {
97
+ const text = sourceCode.getText(node.arguments[0]);
98
+ return text[0];
99
+ }
100
+ return '\''; // 默认使用单引号
101
+ };
102
+
103
+ /**
104
+ * 获取需要修复的节点
105
+ */
106
+ const getFixNode = (node) => {
107
+ if (node.source) return node.source;
108
+ if (node.arguments && node.arguments[0]) return node.arguments[0];
109
+ return node;
110
+ };
111
+
112
+ /**
113
+ * 检查并报告非法引入
114
+ */
115
+ const checkAndReport = (node, importPath) => {
116
+ if (importPath && importPath.startsWith(pmdPackageName)) {
117
+ const sourceCode = context.getSourceCode();
118
+ const fixNode = getFixNode(node);
119
+
120
+ context.report({
121
+ node: fixNode,
122
+ message: `禁止在 packages/${currentPackage} 目录下引入 ${pmdPackageName},请使用相对路径`,
123
+ data: { importPath },
124
+ fix(fixer) {
125
+ const relativePath = getRelativePath(importPath, absolutePath);
126
+ const quoteChar = getQuoteChar(node, sourceCode);
127
+ return fixer.replaceText(fixNode, `${quoteChar}${relativePath}${quoteChar}`);
128
+ },
129
+ });
130
+ }
131
+ };
132
+
133
+ return {
134
+ ImportDeclaration(node) {
135
+ if (node.source && node.source.value) {
136
+ checkAndReport(node, node.source.value);
137
+ }
138
+ },
139
+
140
+ CallExpression(node) {
141
+ if (
142
+ node.callee
143
+ && node.callee.name === 'require'
144
+ && node.arguments.length > 0
145
+ && node.arguments[0].type === 'Literal'
146
+ ) {
147
+ checkAndReport(node, node.arguments[0].value);
148
+ }
149
+ },
150
+
151
+ ImportExpression(node) {
152
+ if (node.source && node.source.type === 'Literal') {
153
+ checkAndReport(node, node.source.value);
154
+ }
155
+ },
156
+
157
+ ExportNamedDeclaration(node) {
158
+ if (node.source && node.source.value) {
159
+ checkAndReport(node, node.source.value);
160
+ }
161
+ },
162
+
163
+ ExportAllDeclaration(node) {
164
+ if (node.source && node.source.value) {
165
+ checkAndReport(node, node.source.value);
166
+ }
167
+ },
168
+ };
169
+ },
170
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-light",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Simple Eslint Plugin",
5
5
  "keywords": [
6
6
  "eslint",
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "minimatch": "^10.0.1",
29
29
  "requireindex": "^1.2.0",
30
- "t-comm": "^3.0.3"
30
+ "t-comm": "^3.0.22"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@babel/core": "^7.18.9",