@weapp-vite/oxlint 0.0.0-stage → 0.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ice breaker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,43 @@
1
- # Temporary Holding Version
1
+ # @weapp-vite/oxlint
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 为原生、Wevu 与 React 小程序提供 Oxlint 脚本规则预设及组合语言检查 CLI。规则复用 `@weapp-vite/eslint` 的运行时 API 与 Wevu 兼容清单;不会给小程序源码启用浏览器或 Node.js 环境。
4
+
5
+ ```ts
6
+ import { miniProgramRecommended } from '@weapp-vite/oxlint'
7
+ import { defineConfig } from 'vite-plus'
8
+
9
+ export default defineConfig({
10
+ lint: miniProgramRecommended,
11
+ })
12
+ ```
13
+
14
+ Wevu 项目使用 `wevuRecommended`,React 项目使用 `reactRecommended`。Vite Plus 模板使用 Vite+ 1.2.0,其内置 Oxlint 为 1.88.0。预设通过 `@weapp-vite/oxlint/plugin` 注册自己的 JS 插件,无须额外安装另一份 Oxlint。
15
+
16
+ | 规则 | 级别 | 适用预设 |
17
+ | --- | --- | --- |
18
+ | `weapp-vite/no-unsupported-runtime-api` | error | 原生、React、Wevu |
19
+ | `weapp-vite/no-implicit-runtime-polyfill` | warn | 原生、React、Wevu |
20
+ | `weapp-vite/no-unsupported-api` | error | Wevu |
21
+ | `weapp-vite/no-risky-api` | warn | Wevu |
22
+ | `react/rules-of-hooks` | error | React |
23
+ | `react/exhaustive-deps` | warn | React |
24
+
25
+ 运行时规则只检查 `src` 下的 JS、TS、JSX、TSX 和 Vue 脚本;忽略测试、脚本、Web-only 文件、`node.*`、受管支持文件及生成产物。局部变量、显式兼容实现导入、`typeof` 能力探针与类型引用不会被当成隐式宿主 API。
26
+
27
+ `no-debugger` 与 `eqeqeq` 默认报错,Oxlint correctness 类规则默认警告。React 预设额外启用内置 React 插件,检查 Hooks 调用顺序和依赖数组,仍保留小程序宿主的 API 边界。配置与构建脚本使用独立的 Node.js 环境。
28
+
29
+ Wevu 预设启用 Oxlint 内置 Vue 规则。Oxlint 不提供 `vue-eslint-parser` 的完整模板访问接口,需要 parser services 的 Vue 模板检查继续使用 ESLint 的 `wevu/no-unsupported-template-feature`。WXSS、ACSS、TTSS、QSS、JXSS、TYSS、CSS、SCSS 和 Vue `<style>` 的语义检查继续使用 Stylelint,关闭与 Oxfmt 重复的格式规则。
30
+
31
+ ```sh
32
+ pnpm exec weapp-vite-lint
33
+ pnpm exec weapp-vite-lint --fix
34
+ pnpm exec weapp-vite-lint --native-only
35
+ ```
36
+
37
+ 组合 CLI 执行标准 `vp lint`,并使用 `@weapp-vite/language-service` 检查 WXML、AXML、TTML、SWAN、JXML、QML、KSML、XHSML、TYML,以及独立/内联 WXS、SJS、KS、filter 和对应编译源文件。`--fix` 只自动修复 Oxlint 负责的内容,原生语言错误需修改源码;`--native-only` 单独运行平台语言诊断。`--deny-warnings` 将语言警告一并计为失败。
38
+
39
+ 平台配置放在 `vite.config.ts` 的 `weapp.language` 中,支持按文件 glob 覆盖;SJS 等共享后缀存在歧义或引用冲突时需明确平台。原生模块按平台的模块系统和内建 API 校验,不能把 AppService 的 JS/TS 规则套在所有脚本模块上。配置、诊断偏移和作用域模型与 VSCode 共用。
40
+
41
+ 普通 `vp lint` / `oxlint` 仍可直接使用这些预设,但不会替代组合 CLI 的原生语言检查。此工具不新增完整模板类型检查器;静态检查、VSCode 与构建通过不代表真实小程序 IDE runtime 已验收。
42
+
43
+ 可直接展开预设再添加 `rules` 或 `overrides`;添加 override 时保留预设的 `overrides` 数组,避免取消运行时代码范围约束。
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export {}
package/dist/cli.mjs ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ import process from "node:process";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { analyzeProject, loadProjectConfig, printDiagnostic } from "@weapp-vite/language-service/project";
6
+ import { execa } from "execa";
7
+ // src/project.ts
8
+ /** 原生语言分析与标准 Oxlint 分别处理所属文件,避免未知后缀被静默跳过。 */
9
+ async function runLint(args, cwd = process.cwd()) {
10
+ const inputs = [];
11
+ const flags = [];
12
+ let nativeOnly = false;
13
+ let configFile;
14
+ for (let index = 0; index < args.length; index++) {
15
+ const argument = args[index];
16
+ if (argument === "--native-only") nativeOnly = true;
17
+ else if (argument === "--fix" || argument === "--deny-warnings") flags.push(argument);
18
+ else if (argument === "-c" || argument === "--config") {
19
+ configFile = args[++index];
20
+ if (!configFile || configFile.startsWith("-")) throw new Error("--config 需要配置文件路径");
21
+ flags.push(argument, configFile);
22
+ } else if (argument === "-h" || argument === "--help") {
23
+ process.stdout.write("weapp-vite-lint [--fix] [--deny-warnings] [--native-only] [-c config] [paths...]\n");
24
+ return;
25
+ } else if (argument.startsWith("-")) throw new Error(`未知参数:${argument}`);
26
+ else inputs.push(argument);
27
+ }
28
+ const project = await loadProjectConfig(cwd, {
29
+ configFile,
30
+ configKind: "lint"
31
+ });
32
+ const paths = inputs.length ? inputs : ["."];
33
+ const scopedInputs = paths.map((input) => {
34
+ const negative = input.startsWith("!");
35
+ const relative = path.relative(project.root, path.resolve(cwd, negative ? input.slice(1) : input)).split(path.sep).join("/");
36
+ return `${negative ? "!" : ""}${relative || "."}`;
37
+ });
38
+ const documents = await analyzeProject(project.root, scopedInputs, project.language, project.lint?.ignorePatterns);
39
+ let failed = false;
40
+ for (const document of documents) for (const diagnostic of document.analysis.diagnostics) {
41
+ process.stderr.write(`${printDiagnostic(document.fileName, document.source, diagnostic)}\n`);
42
+ failed ||= diagnostic.severity === "error" || diagnostic.severity === "warning" && flags.includes("--deny-warnings");
43
+ }
44
+ if (!nativeOnly) {
45
+ const vp = fileURLToPath(new URL("../bin/vp", import.meta.resolve("vite-plus")));
46
+ const result = await execa(process.execPath, [
47
+ vp,
48
+ "lint",
49
+ ...flags,
50
+ ...paths
51
+ ], {
52
+ cwd,
53
+ stdio: "inherit",
54
+ reject: false
55
+ });
56
+ failed ||= result.exitCode !== 0;
57
+ }
58
+ if (failed) process.exitCode = 1;
59
+ }
60
+ // src/cli.ts
61
+ runLint(process.argv.slice(2)).catch((error) => {
62
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
63
+ process.exitCode = 1;
64
+ });
65
+ export {};
@@ -0,0 +1,160 @@
1
+ /** 原生小程序的脚本检查预设,不启用浏览器或 DOM 环境。 */
2
+ export declare const miniProgramRecommended: {
3
+ categories: {
4
+ correctness: "warn";
5
+ };
6
+ env: {
7
+ builtin: true;
8
+ browser: false;
9
+ node: false;
10
+ };
11
+ jsPlugins: {
12
+ name: string;
13
+ specifier: string;
14
+ }[];
15
+ ignorePatterns: string[];
16
+ rules: {
17
+ 'no-debugger': "error";
18
+ eqeqeq: "error";
19
+ };
20
+ overrides: ({
21
+ files: string[];
22
+ excludeFiles: string[];
23
+ globals: {
24
+ App: "readonly";
25
+ Page: "readonly";
26
+ Component: "readonly";
27
+ Behavior: "readonly";
28
+ getApp: "readonly";
29
+ getCurrentPages: "readonly";
30
+ wx: "readonly";
31
+ require: "readonly";
32
+ };
33
+ rules: {
34
+ 'weapp-vite/no-unsupported-api': "error";
35
+ 'weapp-vite/no-risky-api': "warn";
36
+ 'weapp-vite/no-unsupported-runtime-api': "error";
37
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
38
+ } | {
39
+ 'weapp-vite/no-unsupported-runtime-api': "error";
40
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
41
+ };
42
+ env?: undefined;
43
+ } | {
44
+ files: string[];
45
+ env: {
46
+ node: true;
47
+ };
48
+ excludeFiles?: undefined;
49
+ globals?: undefined;
50
+ rules?: undefined;
51
+ })[];
52
+ };
53
+ /** 在小程序脚本检查基础上增加 Wevu 的上游 API 兼容诊断。 */
54
+ export declare const wevuRecommended: {
55
+ plugins: ("unicorn" | "typescript" | "oxc" | "vue")[];
56
+ categories: {
57
+ correctness: "warn";
58
+ };
59
+ env: {
60
+ builtin: true;
61
+ browser: false;
62
+ node: false;
63
+ };
64
+ jsPlugins: {
65
+ name: string;
66
+ specifier: string;
67
+ }[];
68
+ ignorePatterns: string[];
69
+ rules: {
70
+ 'no-debugger': "error";
71
+ eqeqeq: "error";
72
+ };
73
+ overrides: ({
74
+ files: string[];
75
+ excludeFiles: string[];
76
+ globals: {
77
+ App: "readonly";
78
+ Page: "readonly";
79
+ Component: "readonly";
80
+ Behavior: "readonly";
81
+ getApp: "readonly";
82
+ getCurrentPages: "readonly";
83
+ wx: "readonly";
84
+ require: "readonly";
85
+ };
86
+ rules: {
87
+ 'weapp-vite/no-unsupported-api': "error";
88
+ 'weapp-vite/no-risky-api': "warn";
89
+ 'weapp-vite/no-unsupported-runtime-api': "error";
90
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
91
+ } | {
92
+ 'weapp-vite/no-unsupported-runtime-api': "error";
93
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
94
+ };
95
+ env?: undefined;
96
+ } | {
97
+ files: string[];
98
+ env: {
99
+ node: true;
100
+ };
101
+ excludeFiles?: undefined;
102
+ globals?: undefined;
103
+ rules?: undefined;
104
+ })[];
105
+ };
106
+ /** React 小程序增加 Hooks 约束,仍沿用小程序宿主环境。 */
107
+ export declare const reactRecommended: {
108
+ plugins: ("react" | "unicorn" | "typescript" | "oxc")[];
109
+ rules: {
110
+ 'react/rules-of-hooks': "error";
111
+ 'react/exhaustive-deps': "warn";
112
+ 'no-debugger': "error";
113
+ eqeqeq: "error";
114
+ };
115
+ categories: {
116
+ correctness: "warn";
117
+ };
118
+ env: {
119
+ builtin: true;
120
+ browser: false;
121
+ node: false;
122
+ };
123
+ jsPlugins: {
124
+ name: string;
125
+ specifier: string;
126
+ }[];
127
+ ignorePatterns: string[];
128
+ overrides: ({
129
+ files: string[];
130
+ excludeFiles: string[];
131
+ globals: {
132
+ App: "readonly";
133
+ Page: "readonly";
134
+ Component: "readonly";
135
+ Behavior: "readonly";
136
+ getApp: "readonly";
137
+ getCurrentPages: "readonly";
138
+ wx: "readonly";
139
+ require: "readonly";
140
+ };
141
+ rules: {
142
+ 'weapp-vite/no-unsupported-api': "error";
143
+ 'weapp-vite/no-risky-api': "warn";
144
+ 'weapp-vite/no-unsupported-runtime-api': "error";
145
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
146
+ } | {
147
+ 'weapp-vite/no-unsupported-runtime-api': "error";
148
+ 'weapp-vite/no-implicit-runtime-polyfill': "warn";
149
+ };
150
+ env?: undefined;
151
+ } | {
152
+ files: string[];
153
+ env: {
154
+ node: true;
155
+ };
156
+ excludeFiles?: undefined;
157
+ globals?: undefined;
158
+ rules?: undefined;
159
+ })[];
160
+ };
package/dist/index.mjs ADDED
@@ -0,0 +1,93 @@
1
+ import { MINI_PROGRAM_RUNTIME_DEFAULT_FILES, MINI_PROGRAM_RUNTIME_DEFAULT_IGNORES } from "@weapp-vite/eslint";
2
+ // src/index.ts
3
+ const runtimeRules = {
4
+ "weapp-vite/no-unsupported-runtime-api": "error",
5
+ "weapp-vite/no-implicit-runtime-polyfill": "warn"
6
+ };
7
+ const compatibilityRules = {
8
+ "weapp-vite/no-unsupported-api": "error",
9
+ "weapp-vite/no-risky-api": "warn"
10
+ };
11
+ function createPreset(wevu) {
12
+ return {
13
+ categories: { correctness: "warn" },
14
+ env: {
15
+ builtin: true,
16
+ browser: false,
17
+ node: false
18
+ },
19
+ jsPlugins: [{
20
+ name: "weapp-vite",
21
+ specifier: "@weapp-vite/oxlint/plugin"
22
+ }],
23
+ ignorePatterns: [
24
+ "**/node_modules/**",
25
+ "**/dist/**",
26
+ "**/dist-*/**",
27
+ "**/.weapp-vite/**",
28
+ "**/miniprogram_npm/**",
29
+ "**/generated/**"
30
+ ],
31
+ rules: {
32
+ "no-debugger": "error",
33
+ "eqeqeq": "error"
34
+ },
35
+ overrides: [{
36
+ files: [...MINI_PROGRAM_RUNTIME_DEFAULT_FILES],
37
+ excludeFiles: [
38
+ ...MINI_PROGRAM_RUNTIME_DEFAULT_IGNORES,
39
+ "**/*.{wxs,sjs,ks}.{js,ts}",
40
+ "**/*.filter.{js,ts}"
41
+ ],
42
+ globals: {
43
+ App: "readonly",
44
+ Page: "readonly",
45
+ Component: "readonly",
46
+ Behavior: "readonly",
47
+ getApp: "readonly",
48
+ getCurrentPages: "readonly",
49
+ wx: "readonly",
50
+ require: "readonly"
51
+ },
52
+ rules: wevu ? {
53
+ ...runtimeRules,
54
+ ...compatibilityRules
55
+ } : { ...runtimeRules }
56
+ }, {
57
+ files: [
58
+ "*.config.*",
59
+ "scripts/**",
60
+ "**/*.{test,spec}.{js,mjs,cjs,jsx,ts,mts,cts,tsx}"
61
+ ],
62
+ env: { node: true }
63
+ }]
64
+ };
65
+ }
66
+ /** 原生小程序的脚本检查预设,不启用浏览器或 DOM 环境。 */
67
+ const miniProgramRecommended = createPreset(false);
68
+ /** 在小程序脚本检查基础上增加 Wevu 的上游 API 兼容诊断。 */
69
+ const wevuRecommended = {
70
+ ...createPreset(true),
71
+ plugins: [
72
+ "typescript",
73
+ "unicorn",
74
+ "oxc",
75
+ "vue"
76
+ ]
77
+ };
78
+ /** React 小程序增加 Hooks 约束,仍沿用小程序宿主环境。 */
79
+ const reactRecommended = {
80
+ ...createPreset(false),
81
+ plugins: [
82
+ "typescript",
83
+ "unicorn",
84
+ "oxc",
85
+ "react"
86
+ ],
87
+ rules: {
88
+ ...miniProgramRecommended.rules,
89
+ "react/rules-of-hooks": "error",
90
+ "react/exhaustive-deps": "warn"
91
+ }
92
+ };
93
+ export { miniProgramRecommended, reactRecommended, wevuRecommended };
@@ -0,0 +1,13 @@
1
+ /** 复用 ESLint 的脚本规则及能力清单;Vue 模板规则仍由 vue-eslint-parser 执行。 */
2
+ declare const plugin: {
3
+ meta: {
4
+ name: string;
5
+ };
6
+ rules: {
7
+ 'no-unsupported-api': import("eslint").Rule.RuleModule;
8
+ 'no-risky-api': import("eslint").Rule.RuleModule;
9
+ 'no-unsupported-runtime-api': import("eslint").Rule.RuleModule;
10
+ 'no-implicit-runtime-polyfill': import("eslint").Rule.RuleModule;
11
+ };
12
+ };
13
+ export { plugin as default };
@@ -0,0 +1,12 @@
1
+ import { miniProgramRuntimePlugin, wevuCompatibilityPlugin } from "@weapp-vite/eslint";
2
+ // src/plugin.ts
3
+ /** 复用 ESLint 的脚本规则及能力清单;Vue 模板规则仍由 vue-eslint-parser 执行。 */
4
+ const plugin = {
5
+ meta: { name: "weapp-vite" },
6
+ rules: {
7
+ ...miniProgramRuntimePlugin.rules,
8
+ "no-unsupported-api": wevuCompatibilityPlugin.rules["no-unsupported-api"],
9
+ "no-risky-api": wevuCompatibilityPlugin.rules["no-risky-api"]
10
+ }
11
+ };
12
+ export { plugin as default };
package/package.json CHANGED
@@ -1,6 +1,87 @@
1
1
  {
2
2
  "name": "@weapp-vite/oxlint",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "description": "Oxlint presets and mini-program compatibility rules for weapp-vite",
6
+ "license": "MIT",
7
+ "homepage": "https://vite.weapp.dev/packages/oxlint",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/weapp-vite/weapp-vite.git",
11
+ "directory": "packages/oxlint"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/weapp-vite/weapp-vite/issues"
15
+ },
16
+ "keywords": [
17
+ "weapp-vite",
18
+ "miniprogram",
19
+ "oxlint",
20
+ "lint"
21
+ ],
22
+ "sideEffects": false,
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.mts",
26
+ "import": "./dist/index.mjs"
27
+ },
28
+ "./plugin": {
29
+ "types": "./dist/plugin.d.mts",
30
+ "import": "./dist/plugin.mjs"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "main": "./dist/index.mjs",
35
+ "module": "./dist/index.mjs",
36
+ "types": "./dist/index.d.mts",
37
+ "bin": {
38
+ "weapp-vite-lint": "./dist/cli.mjs"
39
+ },
40
+ "files": [
41
+ "dist"
42
+ ],
43
+ "engines": {
44
+ "node": "^22.23.4 || ^24.22.1 || >=26.12.1"
45
+ },
46
+ "peerDependencies": {
47
+ "vite-plus": ">=1.2.0 <2"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "vite-plus": {
51
+ "optional": true
52
+ }
53
+ },
54
+ "dependencies": {
55
+ "@types/eslint": "^9.6.1",
56
+ "@weapp-vite/eslint": "0.3.0",
57
+ "@weapp-vite/language-service": "0.0.0",
58
+ "execa": "^10.2.1"
59
+ },
60
+ "devDependencies": {
61
+ "eslint": "^10.14.0",
62
+ "typescript": "^6.0.3",
63
+ "vite-plus": "1.2.0",
64
+ "vitest": "^5.0.5"
65
+ },
66
+ "tsd": {
67
+ "compilerOptions": {
68
+ "module": "NodeNext",
69
+ "moduleResolution": "NodeNext",
70
+ "strict": true,
71
+ "skipLibCheck": false
72
+ }
73
+ },
74
+ "publishConfig": {
75
+ "access": "public",
76
+ "registry": "https://registry.npmjs.org"
77
+ },
78
+ "scripts": {
79
+ "build": "tsdown",
80
+ "test": "vitest run --config ./vitest.config.ts",
81
+ "test:types": "pnpm build && pnpm run test:types:check",
82
+ "test:types:check": "tsd --files \"test-d/**/*.test-d.ts\"",
83
+ "typecheck": "tsc -p tsconfig.json --noEmit",
84
+ "lint": "eslint .",
85
+ "lint:fix": "eslint . --fix"
86
+ }
6
87
  }