@rtorcato/repo-tooling 3.2.3 → 3.2.4
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/dist/cli/generators/linting.js +11 -1
- package/dist/cli/generators/package-json.js +27 -0
- package/dist/cli/generators/testing.js +12 -1
- package/dist/cli/generators/tsconfig.js +6 -0
- package/package.json +1 -1
- package/tooling/eslint/base.mjs +8 -0
- package/tooling/typescript/tsconfig.base.json +6 -2
- package/tooling/typescript/tsconfig.next.json +8 -1
- package/tooling/typescript/tsconfig.react.json +7 -1
|
@@ -40,7 +40,17 @@ export async function generateBiomeConfig(targetDir) {
|
|
|
40
40
|
export async function generateESLintConfig(config, targetDir) {
|
|
41
41
|
const eslintConfigPath = path.join(targetDir, 'eslint.config.mjs');
|
|
42
42
|
const configType = config.linting.eslintConfig || 'base';
|
|
43
|
-
|
|
43
|
+
// eslint/nextjs is a fragment: it registers the @next/next plugin and its
|
|
44
|
+
// rules but sets no parser, so on its own it can't even parse .tsx ("Parsing
|
|
45
|
+
// error: Unexpected token <"). It has to be layered onto the base config,
|
|
46
|
+
// which is what brings typescript-eslint.
|
|
47
|
+
const eslintConfig = configType === 'nextjs'
|
|
48
|
+
? `import base from '@rtorcato/repo-tooling/eslint/base'
|
|
49
|
+
import nextjs from '@rtorcato/repo-tooling/eslint/nextjs'
|
|
50
|
+
|
|
51
|
+
export default [...base, ...nextjs]
|
|
52
|
+
`
|
|
53
|
+
: `import { default as config } from '@rtorcato/repo-tooling/eslint/${configType}'
|
|
44
54
|
|
|
45
55
|
export default config
|
|
46
56
|
`;
|
|
@@ -237,6 +237,24 @@ function getDependencies(config) {
|
|
|
237
237
|
if (config.linting.tool === 'eslint' || config.linting.tool === 'both') {
|
|
238
238
|
deps['eslint'] = '^9.0.0';
|
|
239
239
|
deps['prettier'] = '^3.0.0';
|
|
240
|
+
// Everything tooling/eslint/base.mjs imports. All optional peers of
|
|
241
|
+
// repo-tooling, so pnpm skips them and `eslint .` dies on the config
|
|
242
|
+
// import — the scaffold shipped a lint script that could never run.
|
|
243
|
+
deps['@eslint/js'] = '^9.0.0';
|
|
244
|
+
deps['@typescript-eslint/eslint-plugin'] = '^8.0.0';
|
|
245
|
+
deps['typescript-eslint'] = '^8.0.0';
|
|
246
|
+
deps['eslint-plugin-import'] = '^2.0.0';
|
|
247
|
+
deps['eslint-plugin-jest'] = '^29.0.0';
|
|
248
|
+
}
|
|
249
|
+
// The shipped prettier preset lists this in `plugins`, and the nextjs eslint
|
|
250
|
+
// preset imports the Next plugin. Both are only *optional* peers of
|
|
251
|
+
// repo-tooling, so pnpm skips them and the scaffold's first format/lint dies
|
|
252
|
+
// with ERR_MODULE_NOT_FOUND.
|
|
253
|
+
if (config.formatting.tool === 'prettier') {
|
|
254
|
+
deps['@ianvs/prettier-plugin-sort-imports'] = '^4.7.0';
|
|
255
|
+
}
|
|
256
|
+
if (config.linting.eslintConfig === 'nextjs') {
|
|
257
|
+
deps['@next/eslint-plugin-next'] = '^16.2.11';
|
|
240
258
|
}
|
|
241
259
|
// Testing frameworks
|
|
242
260
|
if (config.testing.framework === 'vitest') {
|
|
@@ -266,6 +284,10 @@ function getDependencies(config) {
|
|
|
266
284
|
}
|
|
267
285
|
else if (config.bundler === 'esbuild') {
|
|
268
286
|
deps['esbuild'] = '^0.25.0';
|
|
287
|
+
// The generated build.mjs imports this directly. It's only an *optional*
|
|
288
|
+
// peer of repo-tooling, so pnpm won't pull it in — without it here every
|
|
289
|
+
// esbuild scaffold fails its first `pnpm build` with ERR_MODULE_NOT_FOUND.
|
|
290
|
+
deps['esbuild-node-externals'] = '^1.18.0';
|
|
269
291
|
}
|
|
270
292
|
else if (config.bundler === 'rollup') {
|
|
271
293
|
deps['rollup'] = '^4.0.0';
|
|
@@ -278,6 +300,11 @@ function getDependencies(config) {
|
|
|
278
300
|
}
|
|
279
301
|
else if (config.bundler === 'vite') {
|
|
280
302
|
deps['vite'] = '^6.0.0';
|
|
303
|
+
// generateViteConfig emits `import react from '@vitejs/plugin-react'` for
|
|
304
|
+
// react-app, so the plugin has to be installed or `vite build` can't even
|
|
305
|
+
// load the config. Keep this condition in step with that one.
|
|
306
|
+
if (config.projectType === 'react-app')
|
|
307
|
+
deps['@vitejs/plugin-react'] = '^5.0.0';
|
|
281
308
|
}
|
|
282
309
|
// Tailwind CSS v4 — CSS-first, wired via the PostCSS plugin.
|
|
283
310
|
if (config.tailwind) {
|
|
@@ -16,10 +16,21 @@ export async function generateTestingConfigs(config, targetDir) {
|
|
|
16
16
|
}
|
|
17
17
|
export async function generateVitestConfig(config, targetDir) {
|
|
18
18
|
const vitestConfigPath = path.join(targetDir, 'vitest.config.ts');
|
|
19
|
+
// Vite reads `jsx` from tsconfig, and the next preset sets it to "preserve" so
|
|
20
|
+
// Next's own compiler handles the transform. Vitest has no such compiler, so
|
|
21
|
+
// .tsx tests fail to parse ("Unexpected token <") unless we opt back in here.
|
|
22
|
+
// `oxc` (not `esbuild`) is the Vite 8 spelling — vitest ^4 resolves Vite 8,
|
|
23
|
+
// and Vite 8 silently ignores the old `esbuild` key.
|
|
24
|
+
const jsxOverride = config.projectType === 'nextjs-app'
|
|
25
|
+
? ` // tsconfig sets jsx: "preserve" for Next's compiler; vitest needs a
|
|
26
|
+
// transform of its own or .tsx tests won't parse.
|
|
27
|
+
oxc: { jsx: { runtime: 'automatic' } },
|
|
28
|
+
`
|
|
29
|
+
: '';
|
|
19
30
|
const vitestConfig = `import { defineConfig } from 'vitest/config'
|
|
20
31
|
|
|
21
32
|
export default defineConfig({
|
|
22
|
-
test: {
|
|
33
|
+
${jsxOverride} test: {
|
|
23
34
|
globals: true,
|
|
24
35
|
environment: '${config.testing.environment === 'browser' ? 'jsdom' : 'node'}',
|
|
25
36
|
setupFiles: ['./vitest.setup.ts'],
|
|
@@ -19,6 +19,12 @@ export async function generateTSConfig(config, targetDir) {
|
|
|
19
19
|
tsconfig.compilerOptions.outDir = './dist';
|
|
20
20
|
tsconfig.compilerOptions.rootDir = './src';
|
|
21
21
|
}
|
|
22
|
+
// web-app is the only browser target that lands on the `base` preset, whose
|
|
23
|
+
// lib is ES2022 — so `document`/`window` don't typecheck. The react and next
|
|
24
|
+
// presets already add the DOM libs themselves.
|
|
25
|
+
if (config.projectType === 'web-app' && preset === 'base') {
|
|
26
|
+
tsconfig.compilerOptions.lib = ['ES2022', 'DOM', 'DOM.Iterable'];
|
|
27
|
+
}
|
|
22
28
|
if (config.projectType === 'nextjs-app') {
|
|
23
29
|
tsconfig.include = ['next-env.d.ts', 'src', 'app', 'pages', 'components', 'reset.d.ts'];
|
|
24
30
|
tsconfig.exclude.push('.next');
|
package/package.json
CHANGED
package/tooling/eslint/base.mjs
CHANGED
|
@@ -43,6 +43,14 @@ export default tseslint.config(
|
|
|
43
43
|
ignores: [
|
|
44
44
|
//
|
|
45
45
|
'**/*.config.js',
|
|
46
|
+
// Root-level TS config files are outside the tsconfig `include` of every
|
|
47
|
+
// app preset, and this config lints type-aware (parserOptions.project),
|
|
48
|
+
// so linting them fails with "file was not found in any of the provided
|
|
49
|
+
// project(s)". The .js forms were already ignored; these are the same
|
|
50
|
+
// thing (the scaffold emits vitest.config.ts / vitest.setup.ts).
|
|
51
|
+
'**/*.config.ts',
|
|
52
|
+
'**/*.config.mts',
|
|
53
|
+
'**/*.setup.ts',
|
|
46
54
|
'.turbo',
|
|
47
55
|
'dist',
|
|
48
56
|
'build',
|
|
@@ -9,8 +9,12 @@
|
|
|
9
9
|
// "moduleResolution": "node", // Prefer "bundler" if you're using Vite, esbuild, etc.
|
|
10
10
|
// "target": "esnext", //
|
|
11
11
|
"lib": ["ES2022"], // Specify library files to be included in the compilation
|
|
12
|
-
|
|
13
|
-
"
|
|
12
|
+
// ${configDir} for the same reason as paths/tsBuildInfoFile below: a bare
|
|
13
|
+
// "src" resolves against THIS file, i.e. inside node_modules, so every
|
|
14
|
+
// consumer that didn't redeclare rootDir got TS6059 "not under rootDir" the
|
|
15
|
+
// moment a file outside the preset's own directory entered the program.
|
|
16
|
+
"rootDir": "${configDir}/src",
|
|
17
|
+
"outDir": "${configDir}/dist",
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
// 🔍 JavaScript Support
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
"extends": "./tsconfig.base.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"jsx": "preserve", // Let Next.js handle JSX transformation
|
|
5
|
+
// The base pins rootDir to src/, but `include` below spans app/, pages/ and
|
|
6
|
+
// components/ — all siblings of src/ — so tsc raised TS6059 on any Next repo
|
|
7
|
+
// using the app router. These presets are noEmit, so rootDir buys nothing
|
|
8
|
+
// here beyond that trap; widen it to the project root.
|
|
9
|
+
"rootDir": "${configDir}",
|
|
5
10
|
"lib": ["DOM", "DOM.Iterable", "ESNext"], // Include DOM types for browser APIs
|
|
6
11
|
"module": "esnext", // Next.js expects ESNext modules
|
|
7
12
|
"moduleResolution": "bundler", // Modern module resolution for Next.js
|
|
8
13
|
"allowJs": true, // Allow JavaScript files
|
|
9
14
|
"esModuleInterop": true, // Interop for CommonJS/ESM
|
|
10
|
-
|
|
15
|
+
// No "tailwindcss" — see tsconfig.react.json; it broke TS2688 for every
|
|
16
|
+
// project without Tailwind installed.
|
|
17
|
+
"types": ["react", "vitest"],
|
|
11
18
|
"plugins": [ { "name": "next" } ], // Next.js plugin for TypeScript
|
|
12
19
|
// ${configDir} anchors paths to the consuming project (drops deprecated baseUrl)
|
|
13
20
|
"paths": {
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
"extends": "./tsconfig.base.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"jsx": "react-jsx", // Use the new JSX transform for React 17+
|
|
5
|
+
// Same TS6059 trap as the next preset: `include` below covers index.d.ts and
|
|
6
|
+
// types/ alongside src/, which a src-rooted rootDir can't contain.
|
|
7
|
+
"rootDir": "${configDir}",
|
|
5
8
|
"lib": ["DOM", "DOM.Iterable", "ESNext"],// Include DOM types for browser APIs
|
|
6
|
-
"
|
|
9
|
+
// No "tailwindcss": listing it here made tsc fail with TS2688 on every React
|
|
10
|
+
// project that doesn't install Tailwind. Tailwind v4 is CSS-first and ships
|
|
11
|
+
// no ambient types a project needs, so nothing is lost by dropping it.
|
|
12
|
+
"types": ["react", "react-dom", "vitest"],
|
|
7
13
|
// ${configDir} anchors paths to the consuming project (drops deprecated baseUrl)
|
|
8
14
|
"paths": {
|
|
9
15
|
"~/*": ["${configDir}/src/*"],
|