@multiplatform.one/config 7.4.1 → 7.5.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/README.md +27 -0
- package/lib/vitest.js +56 -15
- package/lint.d.ts +19 -0
- package/lint.mjs +778 -0
- package/oxlint.d.ts +12 -0
- package/oxlint.mjs +183 -0
- package/package.json +16 -3
- package/pin-react-require.cjs +42 -0
- package/src/lint.spec.ts +52 -0
- package/src/oxlint.spec.ts +61 -0
- package/src/vitest.spec.ts +77 -2
- package/src/vitest.ts +131 -14
- package/types/vitest.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -55,3 +55,30 @@ Extend from the tsconfig presets:
|
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Available presets: `base.json`, `build.json`, `app.json`.
|
|
58
|
+
|
|
59
|
+
### Oxlint
|
|
60
|
+
|
|
61
|
+
Convention rules travel with the package. Consuming apps add one line:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"jsPlugins": ["@multiplatform.one/config/oxlint"]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Then enable `mpo-conventions/no-hex-literals` on the globs you want (mpo's
|
|
70
|
+
own `oxlintrc.json` turns it on for `features/**`). Palette modules
|
|
71
|
+
(`themes/base.ts`, `themes/accent.ts`, `*palette*`) are exempt.
|
|
72
|
+
|
|
73
|
+
### Lint (node-script checks)
|
|
74
|
+
|
|
75
|
+
CSS-in-apps, features-twin, silent token no-ops, and the LC-65 size-recipe
|
|
76
|
+
pilot run through `runConventionChecks({ roots })`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { runConventionChecks } from "@multiplatform.one/config/lint";
|
|
80
|
+
|
|
81
|
+
runConventionChecks({
|
|
82
|
+
roots: { root: process.cwd() },
|
|
83
|
+
});
|
|
84
|
+
```
|
package/lib/vitest.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
+
import Module from "node:module";
|
|
2
|
+
import fs from "node:fs";
|
|
1
3
|
import path from "node:path";
|
|
2
4
|
import { tamaguiPlugin } from "@tamagui/vite-plugin";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
3
6
|
import react from "@vitejs/plugin-react";
|
|
4
7
|
|
|
5
8
|
//#region src/vitest.ts
|
|
9
|
+
const pinReactRequireSetup = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../pin-react-require.cjs");
|
|
10
|
+
/**
|
|
11
|
+
* CJS `require('react')` does not go through Vite aliases. `use-sync-external-store`
|
|
12
|
+
* is a valid Node import, so Vitest leaves it external even when we ask to inline
|
|
13
|
+
* it, and Node then loads the hoisted root copy — a different inode than the
|
|
14
|
+
* `.pnpm` copy Vite binds. Patching Module._resolveFilename in the vitest
|
|
15
|
+
* process (config eval + workers that re-load this factory) makes that
|
|
16
|
+
* require land on the same physical copy as the aliases.
|
|
17
|
+
*/
|
|
18
|
+
function pinNodeReactRequire(reactDir, reactDomDir, schedulerDir) {
|
|
19
|
+
const ctor = Module;
|
|
20
|
+
if (ctor._mpoOneReact) return;
|
|
21
|
+
ctor._mpoOneReact = true;
|
|
22
|
+
const orig = ctor._resolveFilename;
|
|
23
|
+
ctor._resolveFilename = function pinned(request, parent, isMain, options) {
|
|
24
|
+
const next = request === "react" ? reactDir : request.startsWith("react/") ? path.join(reactDir, request.slice(6)) : request === "react-dom" ? reactDomDir : request.startsWith("react-dom/") ? path.join(reactDomDir, request.slice(10)) : request === "scheduler" ? schedulerDir : null;
|
|
25
|
+
if (next) try {
|
|
26
|
+
return orig.call(this, next, parent, isMain, options);
|
|
27
|
+
} catch {}
|
|
28
|
+
return orig.call(this, request, parent, isMain, options);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
6
31
|
/**
|
|
7
32
|
* Creates a shared Vitest configuration for multiplatform.one packages.
|
|
8
33
|
*
|
|
@@ -49,18 +74,31 @@ function createVitestConfig(options = {}) {
|
|
|
49
74
|
resolveAliases["react-native-svg"] = "@tamagui/react-native-svg";
|
|
50
75
|
}
|
|
51
76
|
if (dedupeReact) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
77
|
+
const onePhysicalCopy = (pkg) => {
|
|
78
|
+
for (const base of [path.resolve(process.cwd(), "node_modules"), rootNodeModules]) try {
|
|
79
|
+
return fs.realpathSync(path.resolve(base, pkg));
|
|
80
|
+
} catch {}
|
|
81
|
+
return path.resolve(rootNodeModules, pkg);
|
|
82
|
+
};
|
|
83
|
+
const reactDir = onePhysicalCopy("react");
|
|
84
|
+
const reactDomDir = onePhysicalCopy("react-dom");
|
|
85
|
+
resolveAliases.react = reactDir;
|
|
86
|
+
resolveAliases["react-dom"] = reactDomDir;
|
|
87
|
+
resolveAliases["react-dom/client"] = path.join(reactDomDir, "client");
|
|
88
|
+
resolveAliases["react-dom/server"] = path.join(reactDomDir, "server");
|
|
89
|
+
resolveAliases["react/jsx-runtime"] = path.join(reactDir, "jsx-runtime");
|
|
90
|
+
resolveAliases["react/jsx-dev-runtime"] = path.join(reactDir, "jsx-dev-runtime");
|
|
91
|
+
const schedulerDir = onePhysicalCopy("scheduler");
|
|
92
|
+
resolveAliases.scheduler = schedulerDir;
|
|
93
|
+
process.env.MPO_VITEST_REACT = reactDir;
|
|
94
|
+
process.env.MPO_VITEST_REACT_DOM = reactDomDir;
|
|
95
|
+
process.env.MPO_VITEST_SCHEDULER = schedulerDir;
|
|
96
|
+
pinNodeReactRequire(reactDir, reactDomDir, schedulerDir);
|
|
59
97
|
}
|
|
60
98
|
const testConfig = {
|
|
61
99
|
environment,
|
|
62
100
|
globals: true,
|
|
63
|
-
setupFiles,
|
|
101
|
+
setupFiles: dedupeReact ? [pinReactRequireSetup, ...setupFiles] : setupFiles,
|
|
64
102
|
testTimeout,
|
|
65
103
|
coverage: {
|
|
66
104
|
provider: "v8",
|
|
@@ -88,9 +126,11 @@ function createVitestConfig(options = {}) {
|
|
|
88
126
|
"one",
|
|
89
127
|
/@tamagui\//,
|
|
90
128
|
"tamagui",
|
|
129
|
+
/@tanstack\//,
|
|
130
|
+
"use-sync-external-store",
|
|
91
131
|
...inlineDeps
|
|
92
132
|
],
|
|
93
|
-
...externalDeps.length > 0 ? { external: externalDeps } : {},
|
|
133
|
+
...externalDeps.length > 0 ? { external: [pinReactRequireSetup, ...externalDeps] } : { external: [pinReactRequireSetup] },
|
|
94
134
|
interopDefault: true
|
|
95
135
|
} }
|
|
96
136
|
};
|
|
@@ -121,11 +161,7 @@ function createVitestConfig(options = {}) {
|
|
|
121
161
|
...aliases
|
|
122
162
|
},
|
|
123
163
|
conditions,
|
|
124
|
-
dedupe:
|
|
125
|
-
"react",
|
|
126
|
-
"react-dom",
|
|
127
|
-
"scheduler"
|
|
128
|
-
] : []
|
|
164
|
+
dedupe: []
|
|
129
165
|
},
|
|
130
166
|
define: {
|
|
131
167
|
__DEV__: true,
|
|
@@ -133,7 +169,12 @@ function createVitestConfig(options = {}) {
|
|
|
133
169
|
process: JSON.stringify({
|
|
134
170
|
env: {
|
|
135
171
|
NODE_ENV: "test",
|
|
136
|
-
NODE_DEBUG: false
|
|
172
|
+
NODE_DEBUG: false,
|
|
173
|
+
...dedupeReact ? {
|
|
174
|
+
MPO_VITEST_REACT: process.env.MPO_VITEST_REACT,
|
|
175
|
+
MPO_VITEST_REACT_DOM: process.env.MPO_VITEST_REACT_DOM,
|
|
176
|
+
MPO_VITEST_SCHEDULER: process.env.MPO_VITEST_SCHEDULER
|
|
177
|
+
} : {}
|
|
137
178
|
},
|
|
138
179
|
platform: process.platform,
|
|
139
180
|
version: process.version,
|
package/lint.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type ConventionRoots = {
|
|
2
|
+
root?: string;
|
|
3
|
+
apps?: string;
|
|
4
|
+
features?: string;
|
|
5
|
+
public?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type RunConventionChecksOptions = {
|
|
9
|
+
roots?: ConventionRoots;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function resolveRoots(roots?: ConventionRoots): {
|
|
13
|
+
root: string;
|
|
14
|
+
apps: string;
|
|
15
|
+
features: string;
|
|
16
|
+
public: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function runConventionChecks(options?: RunConventionChecksOptions): number;
|