@evertondgn/solid-tooling 0.5.0 → 0.6.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 +193 -634
- package/app-env.d.ts +7 -0
- package/dist/architecture-plugin.mjs +1 -1
- package/dist/backend-plugin.mjs +139 -4
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +42 -0
- package/dist/{constants-Jqvtbvxu.mjs → constants-BZJm7ouk.mjs} +1 -1
- package/dist/css-filename-CEHQd2gz.mjs +40 -0
- package/dist/css-filename.mjs +1 -40
- package/dist/fmt-9dlUYOMk.mjs +34 -0
- package/dist/fmt.mjs +1 -34
- package/dist/i18n-generate.d.mts +1 -0
- package/dist/i18n-generate.mjs +23 -0
- package/dist/i18nPlugin-CS7Gob6R.mjs +109 -0
- package/dist/knip.d.mts +2 -1
- package/dist/knip.mjs +7 -2
- package/dist/{lint-UTfyg7AR.mjs → lint-ehdtTKfw.mjs} +33 -86
- package/dist/lint.mjs +1 -1
- package/dist/playwright-teardown.mjs +1 -1
- package/dist/playwright.d.mts +2 -1
- package/dist/playwright.mjs +4 -3
- package/dist/prepareMessages-BXmY6Ko2.mjs +222 -0
- package/dist/project-plugin.mjs +2 -2
- package/dist/protocol-DSNNUYja.mjs +18 -0
- package/dist/publication/read-llms-index.d.mts +12 -0
- package/dist/publication/read-llms-index.mjs +1 -0
- package/dist/publication-CRUTOB0B.mjs +885 -0
- package/dist/readLlmsIndex-Gj4iTxAk.mjs +27 -0
- package/dist/stylelint.mjs +2 -2
- package/dist/test-locale--tuH0Np5.mjs +3 -0
- package/dist/types-DHu2Z_ot.d.mts +49 -0
- package/dist/vite.d.mts +33 -7
- package/dist/vite.mjs +415 -88
- package/dist/vitest-BjLr7iLf.mjs +362 -0
- package/dist/vitest.d.mts +3 -7
- package/dist/vitest.mjs +1 -129
- package/lefthook.yml +3 -1
- package/node-env.d.ts +1 -0
- package/package.json +32 -39
- package/tsconfig.app.json +4 -9
- package/virtual-modules.d.ts +90 -0
package/README.md
CHANGED
|
@@ -1,74 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Stylelint configs, the Vite+ application config, the commitlint config and the
|
|
5
|
-
Git hooks for SolidJS 2 applications built with
|
|
6
|
-
[Vite+](https://viteplus.dev/guide/).
|
|
7
|
-
|
|
8
|
-
The package contains the lint, format, TypeScript, test, build, dead code, CSS
|
|
9
|
-
lint, commit message and Git hook setup of
|
|
10
|
-
[boilerplate_solidjs](https://github.com/everton-dgn/boilerplate_solidjs), a
|
|
11
|
-
SolidJS application template. Applications created from it install the package
|
|
12
|
-
instead of copying the files, so a rule change reaches them through a version
|
|
13
|
-
update.
|
|
14
|
-
|
|
15
|
-
## Requirements
|
|
16
|
-
|
|
17
|
-
The application installs three packages next to this one:
|
|
18
|
-
|
|
19
|
-
| Package | Why |
|
|
20
|
-
| ---------------------- | ----------------------------------------------------------- |
|
|
21
|
-
| `vite-plus` | Runs lint and format, and provides the Oxlint plugin API |
|
|
22
|
-
| `@inlang/paraglide-js` | The preset registers its lint plugin, resolved from the app |
|
|
23
|
-
| `typescript` | The preset turns on type-aware linting and type checking |
|
|
1
|
+
[](https://www.npmjs.com/package/@evertondgn/solid-tooling)
|
|
2
|
+
[](https://github.com/everton-dgn/solidjs_base/actions/workflows/ci.yml)
|
|
3
|
+
[](https://github.com/everton-dgn/solidjs_base/blob/main/LICENSE)
|
|
24
4
|
|
|
25
|
-
|
|
26
|
-
exact versions the package is tested with. Install the versions listed in its
|
|
27
|
-
`peerDependencies`. `typescript` is not a peer dependency: the package is tested
|
|
28
|
-
with the version in its `devDependencies`.
|
|
29
|
-
|
|
30
|
-
`eslint-plugin-solid`, `stylelint` and `stylelint-use-nesting` come with the
|
|
31
|
-
package, so the application does not declare them.
|
|
32
|
-
|
|
33
|
-
Some entries need tools the application already runs:
|
|
34
|
-
|
|
35
|
-
| Entry | The application installs |
|
|
36
|
-
| ---------------- | ------------------------------------------------------------------------------- |
|
|
37
|
-
| `./vitest` | `@vitest/browser-playwright`, `@vitest/coverage-v8`, `happy-dom`, `playwright` |
|
|
38
|
-
| `./playwright` | `@playwright/test`, an optional peer dependency pinned like the others |
|
|
39
|
-
| `./knip` | `knip` and `filesystem-routing`, optional peer dependencies pinned the same way |
|
|
40
|
-
| `./commitlint` | `@commitlint/cli`, an optional peer dependency pinned the same way |
|
|
41
|
-
| `./lefthook.yml` | `lefthook`, an optional peer dependency pinned the same way |
|
|
5
|
+
# @evertondgn/solid-tooling
|
|
42
6
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
root `package.json`, and the Knip plugin of `unplugin-icons` only turns on with
|
|
49
|
-
a direct dependency.
|
|
7
|
+
<picture>
|
|
8
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/hero-dark.webp" />
|
|
9
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/hero-light.webp" />
|
|
10
|
+
<img src="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/hero-light.webp" alt="Solid Base for SolidJS 2 and Vite+. Shared tooling and runtime beneath the SolidJS mark: languages, theme, server protection, SEO, assets and development tools. Install solid-tooling for development and solid-runtime for application features." width="800" />
|
|
11
|
+
</picture>
|
|
50
12
|
|
|
51
|
-
|
|
13
|
+
| Available package | Role |
|
|
14
|
+
| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
|
|
15
|
+
| [`@evertondgn/solid-tooling`](https://github.com/everton-dgn/solidjs_base/blob/main/packages/solid-tooling/README.md) | Shared config, tools, catalog generation, icons and fonts |
|
|
16
|
+
| [`@evertondgn/solid-runtime`](https://github.com/everton-dgn/solidjs_base/blob/main/packages/solid-runtime/README.md), `0.1.0` | Optional locale and theme behavior, middleware, error protection, env, SEO and sitemap |
|
|
52
17
|
|
|
53
|
-
|
|
54
|
-
|
|
18
|
+
Solid Base supplies lint rules, application config, test setups and Git hooks
|
|
19
|
+
for SolidJS 2 with [Vite+](https://viteplus.dev/guide/) as one versioned
|
|
20
|
+
dependency, so you stop maintaining the same tooling in every Solid app. In an
|
|
21
|
+
application that already uses Vite+:
|
|
55
22
|
|
|
56
23
|
```bash
|
|
57
24
|
vp add -D @evertondgn/solid-tooling
|
|
58
25
|
```
|
|
59
26
|
|
|
60
|
-
|
|
61
|
-
|
|
27
|
+
Built for applications that follow the
|
|
28
|
+
[boilerplate_solidjs](https://github.com/everton-dgn/boilerplate_solidjs)
|
|
29
|
+
layout. SolidJS 2 is still a release candidate, and the package is tested with
|
|
30
|
+
it. Start with lint and formatting, and adopt the full application config when
|
|
31
|
+
you are ready.
|
|
62
32
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
Install the exact Vite+ version listed in the package's `peerDependencies`. The
|
|
36
|
+
package supplies its build, test, type-check and hook tools. Applications keep
|
|
37
|
+
their own direct imports and the Vite+ overrides; see the
|
|
38
|
+
[dependency requirements](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/limits.md#requirements).
|
|
39
|
+
An application with translations also installs the required version of
|
|
40
|
+
`@inlang/paraglide-js` and its message-format plugin.
|
|
41
|
+
|
|
42
|
+
## Quick start
|
|
67
43
|
|
|
68
|
-
|
|
44
|
+
Add `fmt` and `lint` to your existing Vite+ config. The example shows only those
|
|
45
|
+
settings; keep your plugins and other options:
|
|
69
46
|
|
|
70
47
|
```ts
|
|
71
|
-
// vite.config.ts
|
|
72
48
|
import { fmt } from '@evertondgn/solid-tooling/fmt'
|
|
73
49
|
import { lint } from '@evertondgn/solid-tooling/lint'
|
|
74
50
|
import { defineConfig } from 'vite-plus'
|
|
@@ -76,8 +52,9 @@ import { defineConfig } from 'vite-plus'
|
|
|
76
52
|
export default defineConfig({ fmt, lint })
|
|
77
53
|
```
|
|
78
54
|
|
|
55
|
+
In `tsconfig.json`:
|
|
56
|
+
|
|
79
57
|
```json
|
|
80
|
-
// tsconfig.json
|
|
81
58
|
{
|
|
82
59
|
"extends": "@evertondgn/solid-tooling/tsconfig.base.json",
|
|
83
60
|
"compilerOptions": {
|
|
@@ -87,83 +64,70 @@ export default defineConfig({ fmt, lint })
|
|
|
87
64
|
}
|
|
88
65
|
```
|
|
89
66
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
## Tests
|
|
93
|
-
|
|
94
|
-
`solidTest` returns the `test` block of `vite.config.ts`, with three Vitest
|
|
95
|
-
projects:
|
|
67
|
+
Check your code and format your files:
|
|
96
68
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
| `browser` | `src/**/*.browser.test.{ts,tsx}` | Chromium through Playwright, with the CSS loaded |
|
|
69
|
+
```bash
|
|
70
|
+
vp check
|
|
71
|
+
vp fmt
|
|
72
|
+
```
|
|
102
73
|
|
|
103
|
-
|
|
104
|
-
builds its own Vite config calls it directly:
|
|
74
|
+
To see a rule of the package fire, create `src/helpers/export-list.ts`:
|
|
105
75
|
|
|
106
76
|
```ts
|
|
107
|
-
|
|
108
|
-
import { solidTest } from '@evertondgn/solid-tooling/vitest'
|
|
109
|
-
import solid from '@solidjs/vite-plugin'
|
|
110
|
-
import { defineConfig } from 'vite-plus'
|
|
77
|
+
const example = 1
|
|
111
78
|
|
|
112
|
-
export
|
|
113
|
-
test: solidTest({
|
|
114
|
-
root: import.meta.dirname,
|
|
115
|
-
plugins: () => [solid({ serverFunctions: true })]
|
|
116
|
-
})
|
|
117
|
-
})
|
|
79
|
+
export { example }
|
|
118
80
|
```
|
|
119
81
|
|
|
120
|
-
`
|
|
121
|
-
projects need to compile components: Solid, routes, icons and i18n. The preset
|
|
122
|
-
calls it once per project, because each project starts its own Vite server and a
|
|
123
|
-
plugin instance keeps the state of one server. The preset also sets the coverage
|
|
124
|
-
thresholds, the reporters and the workers on CI, passes `BASE_URL_TEST`, `HOST`
|
|
125
|
-
and `PORT` to the tests when they are set, and resets the Paraglide locale
|
|
126
|
-
before each browser test.
|
|
82
|
+
Run `vp lint`. The preset reports the export list:
|
|
127
83
|
|
|
128
|
-
|
|
129
|
-
the
|
|
130
|
-
|
|
131
|
-
virtual module of `@solidjs/vite-plugin`: pass it in the `ignoreDependencies` of
|
|
132
|
-
[`defineKnipConfig`](#knip).
|
|
84
|
+
```text
|
|
85
|
+
src/helpers/export-list.ts:3:1: error project(no-export-list): Export on the declaration itself (export function, export const, export type) instead of using export { ... }. An export list is only allowed in a re-export with from.
|
|
86
|
+
```
|
|
133
87
|
|
|
134
|
-
|
|
88
|
+
## Why
|
|
135
89
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
90
|
+
Applications copied from a starter carry its tooling with them, and every fix to
|
|
91
|
+
the base has to be repeated by hand in each copy. With this package, the fix
|
|
92
|
+
arrives when you update a dependency.
|
|
139
93
|
|
|
140
|
-
|
|
141
|
-
|
|
94
|
+
<picture>
|
|
95
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/before-after-dark.webp" />
|
|
96
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/before-after-light.webp" />
|
|
97
|
+
<img src="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/before-after-light.webp" alt="About 86 percent fewer lines across five configuration areas, from 945 to 136: Vite 427 to 59, Playwright 173 to 17, Knip 129 to 40, TypeScript 45 to 9, and Stylelint 171 to an 11-line script. Each bar shows the fraction retained in the app." width="800" />
|
|
98
|
+
</picture>
|
|
99
|
+
|
|
100
|
+
Measured on the original starter and the same application using this package.
|
|
101
|
+
Compare the
|
|
102
|
+
[original config](https://github.com/everton-dgn/boilerplate_solidjs/blob/61454937472d0faa1b4fab985fd7c5da968aa9a6/vite.config.ts)
|
|
103
|
+
with the
|
|
104
|
+
[application config](https://github.com/everton-dgn/solidjs_base/blob/main/apps/boilerplate/vite.config.ts),
|
|
105
|
+
or read the
|
|
106
|
+
[full comparison](https://github.com/everton-dgn/solidjs_base/blob/main/README.md#before-and-after).
|
|
142
107
|
|
|
143
|
-
|
|
144
|
-
for the fixture routes, `production` with `TEST_PRODUCTION_ROUTES=true`), starts
|
|
145
|
-
the preview, and checks the server log for private markers when the suite ends.
|
|
146
|
-
`TEST_PREBUILT=true` reuses an existing production build.
|
|
108
|
+
## What you get
|
|
147
109
|
|
|
148
|
-
|
|
|
149
|
-
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
|
|
|
110
|
+
| Area | Entry | Guide |
|
|
111
|
+
| ------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| Oxlint preset and project rules | `./lint` | [Lint](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/lint.md) |
|
|
113
|
+
| Oxfmt settings | `./fmt` | [Formatting](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/typescript-and-format.md#formatter) |
|
|
114
|
+
| TypeScript configs | `./tsconfig.base.json`, `./tsconfig.app.json` | [TypeScript](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/typescript-and-format.md#typescript-base) |
|
|
115
|
+
| Whole application config | `./vite` | [Application config](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/app-config.md) |
|
|
116
|
+
| Vitest and Playwright | `./vitest`, `./playwright` | [Testing](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/testing.md) |
|
|
117
|
+
| Unused code and CSS policy | `./knip`, `./stylelint` | [Knip and CSS](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/knip-and-css.md) |
|
|
118
|
+
| Commit messages and Git hooks | `./commitlint`, `./lefthook.yml` | [Commits and hooks](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/commits-and-hooks.md) |
|
|
153
119
|
|
|
154
|
-
|
|
155
|
-
`
|
|
156
|
-
|
|
120
|
+
Your application keeps its pages, components, translations, theme, `App`,
|
|
121
|
+
`Document`, entries and middleware. The
|
|
122
|
+
[entry-point reference](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/README.md#entry-points)
|
|
123
|
+
also lists the plugins and test setup exports.
|
|
157
124
|
|
|
158
|
-
##
|
|
125
|
+
## Your application config in one call
|
|
159
126
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
static files, the build, CSS, server and preview blocks, the `vp run` tasks, and
|
|
163
|
-
`lint`, `fmt` and `test` from the presets above.
|
|
127
|
+
With the application dependencies installed, `defineSolidApp()` supplies the
|
|
128
|
+
plugins, build settings, tasks, lint, format and three Vitest projects:
|
|
164
129
|
|
|
165
130
|
```ts
|
|
166
|
-
// vite.config.ts
|
|
167
131
|
import { defineSolidApp } from '@evertondgn/solid-tooling/vite'
|
|
168
132
|
|
|
169
133
|
import { SECURITY_HEADERS } from './src/middleware/securityHeaders/constants.ts'
|
|
@@ -171,530 +135,125 @@ import { SECURITY_HEADERS } from './src/middleware/securityHeaders/constants.ts'
|
|
|
171
135
|
export default defineSolidApp({
|
|
172
136
|
root: import.meta.dirname,
|
|
173
137
|
middleware: './src/middleware/index.ts',
|
|
174
|
-
securityHeaders: SECURITY_HEADERS
|
|
175
|
-
staticPaths: ['/favicon/**']
|
|
138
|
+
securityHeaders: SECURITY_HEADERS
|
|
176
139
|
})
|
|
177
140
|
```
|
|
178
141
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
|
185
|
-
|
|
|
186
|
-
|
|
|
187
|
-
|
|
|
188
|
-
| `
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
`
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
preview (`target: 'app'`), and once for each test project with a Vite server
|
|
230
|
-
(`target: 'test'`). Every load of the config calls it again, so a build also
|
|
231
|
-
calls it for the two test projects, whose plugins Vite does not use; keep side
|
|
232
|
-
effects out of it. It never runs while Vite+ only reads the config. Return new
|
|
233
|
-
plugin instances on each call. The `plugins` go before the fixed ones, and the
|
|
234
|
-
`nitroModules` go to Nitro; the `test` target ignores them. One call returns
|
|
235
|
-
both, so a value that a plugin and a module share, such as a build id, stays the
|
|
236
|
-
same.
|
|
142
|
+
You keep your middleware and header values. SSR uses Nitro with the Vercel
|
|
143
|
+
preset. Its plugins are package dependencies pinned to the tested versions. The
|
|
144
|
+
`knip`, `tsc`, `playwright`, `lefthook` and `commitlint` tasks run the
|
|
145
|
+
package-owned binaries, including with an isolated installation.
|
|
146
|
+
|
|
147
|
+
| Feature | Selection |
|
|
148
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
149
|
+
| Client-only build | Set `ssr: false` and omit SSR options such as `middleware` and `securityHeaders`; the build has no Nitro or server bundle |
|
|
150
|
+
| Publication headers | Set `seo.markdown`, `seo.llms`, `seo.llmsFull` and `seo.sitemap` independently; static artifacts come from compiled tooling |
|
|
151
|
+
| Translations | `project.inlang/settings.json` enables the generation task and browser test setup; the lint plugin loads only where Paraglide resolves |
|
|
152
|
+
|
|
153
|
+
See
|
|
154
|
+
[all options and extension points](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/app-config.md)
|
|
155
|
+
and the
|
|
156
|
+
[known limits](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/limits.md#known-limits).
|
|
157
|
+
|
|
158
|
+
## Optional application fonts
|
|
159
|
+
|
|
160
|
+
Pass a data-only `fonts` array to `defineSolidApp` to generate external
|
|
161
|
+
`@font-face` CSS and matching preloads for application-owned files. SSR uses
|
|
162
|
+
`FontLinks` from `@evertondgn/solid-runtime/fonts/font-links` in the Document
|
|
163
|
+
head; client-only applications receive both links in `index.html`. Without
|
|
164
|
+
`fonts`, nothing is generated. Typography tokens stay in the app. See the
|
|
165
|
+
[font API and migration examples](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/fonts.md).
|
|
166
|
+
|
|
167
|
+
## Optional SEO configuration
|
|
168
|
+
|
|
169
|
+
For SSR,
|
|
170
|
+
`seo: { robots: { groups, sitemapPaths, cacheControl }, sitemap: true }`
|
|
171
|
+
configures the runtime robots route using serializable data. `originEnv`
|
|
172
|
+
defaults to `VITE_SITE_URL`; the value must be an HTTP(S) origin without a path,
|
|
173
|
+
query, fragment or credentials. The preset validates it when SEO is enabled or
|
|
174
|
+
the runtime origin entry is imported. No SEO means no required origin.
|
|
175
|
+
|
|
176
|
+
Pass `site` directly to the runtime `createSeo` primitive. A meta/JSON-LD-only
|
|
177
|
+
application can omit `seo`, provide its own `site.url` and omit robots entirely.
|
|
178
|
+
Client-only applications omit both the option and runtime SEO imports. There are
|
|
179
|
+
no `siteModule`, `sourcesModule` or `editorialModule` path options.
|
|
180
|
+
`seo.sitemap` controls only the static `/sitemap.xml` and `/sitemaps/pages/**`
|
|
181
|
+
header rules. Install the runtime factory in explicit application route files,
|
|
182
|
+
and list the root in `robots.sitemapPaths` to advertise it. To remove sitemap,
|
|
183
|
+
remove its routes and server binding, omit its array metadata, omit
|
|
184
|
+
`sitemapPaths`, and omit or disable `seo.sitemap`. Robots can stay enabled. The
|
|
185
|
+
preset does not discover executable source registries or install routes. See the
|
|
186
|
+
[runtime SEO API](../solid-runtime/README.md#optional-seo) for factories, the
|
|
187
|
+
one-line route and examples with and without translations.
|
|
188
|
+
|
|
189
|
+
## Optional environment validation
|
|
190
|
+
|
|
191
|
+
An SSR application can add `env.ts` with the preset's optional validators:
|
|
237
192
|
|
|
238
193
|
```ts
|
|
239
|
-
|
|
240
|
-
root: import.meta.dirname,
|
|
241
|
-
securityHeaders: SECURITY_HEADERS,
|
|
242
|
-
async extend() {
|
|
243
|
-
const { i18nPlugin } = await import('./tooling/i18n/i18nPlugin/index.ts')
|
|
244
|
-
return { plugins: [i18nPlugin()] }
|
|
245
|
-
}
|
|
246
|
-
})
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
### Tasks
|
|
194
|
+
import { serverEnv } from '@evertondgn/solid-runtime/env'
|
|
250
195
|
|
|
251
|
-
|
|
252
|
-
| ------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
253
|
-
| `i18n-generate` | `bun tooling/i18n/generate.ts` |
|
|
254
|
-
| `lint-css` | `bun tooling/css/check.ts` |
|
|
255
|
-
| `dead-code-project` | `knip-bun --config tooling/knip.ts`, then again with `--strict` |
|
|
256
|
-
| `lint-project` | `vp lint`, after `lint-css` |
|
|
257
|
-
| `check-project` | `vp fmt --check && vp lint`, after `lint-css` |
|
|
258
|
-
| `typecheck-node` | `tsc --project tsconfig.node.json` |
|
|
259
|
-
| `test-tooling` | `node --test` over `tooling/**/__tests__` except `tooling/release/`, three workers on CI, with no cache |
|
|
196
|
+
const env = { server: { ...serverEnv } }
|
|
260
197
|
|
|
261
|
-
|
|
262
|
-
one of them replaces the task through `tasks`. Knip reads task commands only
|
|
263
|
-
from a `run.tasks` block written in `vite.config.ts`, so it does not see these:
|
|
264
|
-
list the scripts they run as Knip entries.
|
|
265
|
-
|
|
266
|
-
With `workspace`, the cache inputs read `bun.lock`, `bunfig.toml` and the
|
|
267
|
-
`inputs` from the workspace root, and `lint-css`, `dead-code-project` and
|
|
268
|
-
`typecheck-node` depend on the tasks in `dependsOn`:
|
|
269
|
-
|
|
270
|
-
```ts
|
|
271
|
-
workspace: {
|
|
272
|
-
dependsOn: ['@evertondgn/solid-tooling#build'],
|
|
273
|
-
inputs: ['packages/solid-tooling/dist/**']
|
|
274
|
-
}
|
|
198
|
+
export default env
|
|
275
199
|
```
|
|
276
200
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
as production entries, and in `src/tests/fixtures/routes/` and
|
|
323
|
-
`src/tests/fixtures/e2e/routes/`, as test entries. The `filesystem-routing`
|
|
324
|
-
plugin of Knip is turned off, because it takes every file of `src/routes/` as
|
|
325
|
-
an entry and would hide unused helpers next to the routes.
|
|
326
|
-
- `src/**/*.{ts,tsx}` and `tooling/**/*.ts` as the project, with the tests out
|
|
327
|
-
of the production files.
|
|
328
|
-
|
|
329
|
-
The config turns on `treatConfigHintsAsErrors`, and Knip reports an entry or a
|
|
330
|
-
project pattern without files as a configuration hint. So each default above
|
|
331
|
-
enters only when the application has the file or the folder.
|
|
332
|
-
|
|
333
|
-
| Option | Default | Use |
|
|
334
|
-
| -------------------- | ----------------- | -------------------------------------------------------------- |
|
|
335
|
-
| `root` | required | The application folder |
|
|
336
|
-
| `configFile` | `tooling/knip.ts` | Path of the config file, relative to `root` |
|
|
337
|
-
| `entry` | none | More entries, such as a public API that only test fixtures use |
|
|
338
|
-
| `solidPluginImport` | `'lazy'` | `'static'` when `vite.config.ts` imports `solid()` statically |
|
|
339
|
-
| `ignoreBinaries` | none | Passed to Knip as is |
|
|
340
|
-
| `ignoreDependencies` | none | Passed to Knip as is |
|
|
341
|
-
| `ignoreIssues` | none | Passed to Knip, merged with the entry for `configFile` |
|
|
342
|
-
| `exclude` | none | Issue types to leave out, such as `catalogReferences` |
|
|
343
|
-
|
|
344
|
-
Knip adds the file given to `--config` to the entries in production mode, and
|
|
345
|
-
`--strict` only accepts `dependencies` there, so it reports this package as an
|
|
346
|
-
unlisted dependency of the config file. The config ignores `unlisted` issues in
|
|
347
|
-
`configFile` only: an import of this package from `src/` is still reported. An
|
|
348
|
-
application that keeps the config somewhere else passes its path in
|
|
349
|
-
`configFile`.
|
|
350
|
-
|
|
351
|
-
Nothing that depends on the application is a default. An ignore that matches
|
|
352
|
-
nothing is a configuration hint too, so `server-only` and the binaries of the
|
|
353
|
-
scripts are options. For a key without an option, wrap the function:
|
|
354
|
-
|
|
355
|
-
```ts
|
|
356
|
-
const configure = defineKnipConfig({ root })
|
|
357
|
-
|
|
358
|
-
export default async function configureKnip() {
|
|
359
|
-
return { ...(await configure()), ignoreUnresolved: ['virtual:example'] }
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## CSS lint
|
|
364
|
-
|
|
365
|
-
`checkCss(root)` lints `src/**/*.css` with Stylelint and the CSS policy of the
|
|
366
|
-
boilerplate, and checks the name of every CSS file in `src/` as
|
|
367
|
-
`project/css-filename` does for imports: `styles.module.css`, or `camelCase.css`
|
|
368
|
-
inside `src/theme/`. It returns the report and whether anything failed:
|
|
369
|
-
|
|
370
|
-
```ts
|
|
371
|
-
// tooling/css/check.ts
|
|
372
|
-
import path from 'node:path'
|
|
373
|
-
import process from 'node:process'
|
|
374
|
-
|
|
375
|
-
import { checkCss } from '@evertondgn/solid-tooling/stylelint'
|
|
376
|
-
|
|
377
|
-
const { report, hasErrors } = await checkCss(
|
|
378
|
-
path.resolve(import.meta.dirname, '../..')
|
|
379
|
-
)
|
|
380
|
-
|
|
381
|
-
process.stdout.write(report)
|
|
382
|
-
if (hasErrors) process.exitCode = 1
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
`defineStylelintConfig(root)` returns the Stylelint config that `checkCss` uses.
|
|
386
|
-
The policy:
|
|
387
|
-
|
|
388
|
-
- Classes use snake_case, nesting goes at most two levels deep, and adjacent
|
|
389
|
-
state selectors and media queries are nested (`stylelint-use-nesting`).
|
|
390
|
-
- Unknown or invalid properties, values, units, selectors, at-rules and media
|
|
391
|
-
features are errors, as are deprecated and unmatchable selectors.
|
|
392
|
-
- Outside `src/theme/`, colors, gradients, radii, shadows, font sizes and
|
|
393
|
-
weights and `z-index` come from tokens with `var()`, from the matching token
|
|
394
|
-
family. Literal colors, color functions and system colors are errors.
|
|
395
|
-
- Inside `src/theme/`, the token rules are off, so the theme can define the
|
|
396
|
-
values with `oklch()`, `oklab()`, `color-mix()`, `light-dark()` and system
|
|
397
|
-
colors. Hex, named colors and the `rgb()`, `hsl()`, `hwb()`, `lab()`, `lch()`
|
|
398
|
-
and `color()` functions are still errors there.
|
|
399
|
-
- `var()` and animation names resolve against `src/theme/tokens/**/*.css` and
|
|
400
|
-
`src/theme/class/animation.css`. Stylelint stops the whole run when a
|
|
401
|
-
reference matches no file, so each one is passed only when it exists.
|
|
402
|
-
- An exception needs a `stylelint-disable` comment with the reason after `--`.
|
|
403
|
-
|
|
404
|
-
`stylelint` and `stylelint-use-nesting` are dependencies of this package. The
|
|
405
|
-
config passes the plugin by a path resolved from the package, because Stylelint
|
|
406
|
-
looks up a plugin name from the application and its working directory, where it
|
|
407
|
-
is not installed.
|
|
408
|
-
|
|
409
|
-
## Commit messages and Git hooks
|
|
410
|
-
|
|
411
|
-
`./commitlint` is the commitlint config: the Conventional Commits rules of
|
|
412
|
-
`@commitlint/config-conventional`, with the header limited to 100 characters, a
|
|
413
|
-
blank line required before the footer, and a warning for body and footer lines
|
|
414
|
-
over 100 characters. The application installs `@commitlint/cli` and points its
|
|
415
|
-
config to the package:
|
|
416
|
-
|
|
417
|
-
```json
|
|
418
|
-
// .commitlintrc
|
|
419
|
-
{ "extends": ["@evertondgn/solid-tooling/commitlint"] }
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
`./lefthook.yml` holds the Git hooks. The application installs `lefthook`,
|
|
423
|
-
allows its install script and extends the file from its own `.lefthook.yml`:
|
|
424
|
-
|
|
425
|
-
```json
|
|
426
|
-
// package.json
|
|
427
|
-
{ "trustedDependencies": ["lefthook"] }
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
```yaml
|
|
431
|
-
# .lefthook.yml
|
|
432
|
-
extends:
|
|
433
|
-
- node_modules/@evertondgn/solid-tooling/lefthook.yml
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
| Hook | Jobs |
|
|
437
|
-
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
438
|
-
| `commit-msg` | `commitlint` on the message |
|
|
439
|
-
| `pre-commit` | `check:fix` on the staged files, which are staged again after the fix, and `scan:secrets --staged` when `kingfisher` is installed. Skipped in merge and rebase |
|
|
440
|
-
| `pre-push` | `check:ci`, `typecheck:node` and `test:ci` in order, then `test:tooling` and `dead-code` together. The first failure stops the rest |
|
|
441
|
-
|
|
442
|
-
The jobs call `package.json` scripts by name, so the application defines
|
|
443
|
-
`check:fix`, `scan:secrets`, `check:ci`, `typecheck:node`, `test:ci`,
|
|
444
|
-
`test:tooling` and `dead-code`.
|
|
445
|
-
|
|
446
|
-
Lefthook applies the files in `extends` over `.lefthook.yml`, so:
|
|
447
|
-
|
|
448
|
-
- A job added in `.lefthook.yml` runs before the shared jobs of the same hook.
|
|
449
|
-
- A job declared there with the name of a shared job does not change it.
|
|
450
|
-
- To change or skip a shared job, declare a job with the same name in
|
|
451
|
-
`lefthook-local.yml`, which Lefthook applies last, also inside a group. The
|
|
452
|
-
rest keeps its order, and new jobs in that file run after the shared ones.
|
|
453
|
-
Commit the file to change the job for everyone, or keep it out of Git to
|
|
454
|
-
change it on one machine.
|
|
455
|
-
|
|
456
|
-
Create `.lefthook.yml` before the first install. Without it, the install script
|
|
457
|
-
of Lefthook writes a `lefthook.yml` of its own, which Lefthook reads first.
|
|
458
|
-
|
|
459
|
-
## Project layout the preset expects
|
|
460
|
-
|
|
461
|
-
The rules match file paths relative to the folder where lint runs, so run it
|
|
462
|
-
from the application root. They know these locations:
|
|
463
|
-
|
|
464
|
-
| Path | Meaning |
|
|
465
|
-
| --------------------------------------------- | -------------------------------------------------------- |
|
|
466
|
-
| `src/` | Application code. The `@/` alias points here |
|
|
467
|
-
| `src/routes/` | Pages. Each page may have a `seo.ts` module |
|
|
468
|
-
| `src/components/{atoms,molecules,organisms}/` | UI layers |
|
|
469
|
-
| `src/primitives/` | Shared primitives |
|
|
470
|
-
| `src/infra/server/` | Backend adapters and server error handling |
|
|
471
|
-
| `src/theme/` | Global CSS |
|
|
472
|
-
| `src/tests/pages/<Page>/` | End-to-end tests, one folder per page |
|
|
473
|
-
| `paraglide/` | Generated i18n modules. The `@paraglide/` alias |
|
|
474
|
-
| `tooling/` | Project scripts and their tests, written for `node:test` |
|
|
475
|
-
|
|
476
|
-
An application with another layout can still use the preset, but it has to
|
|
477
|
-
override the rules that do not fit. See
|
|
478
|
-
[Changing the preset](#changing-the-preset).
|
|
479
|
-
|
|
480
|
-
## What the lint preset turns on
|
|
481
|
-
|
|
482
|
-
- Oxlint plugins: `import`, `jsx-a11y`, `node`, `oxc`, `promise`, `typescript`,
|
|
483
|
-
`unicorn` and `vitest`.
|
|
484
|
-
- JavaScript plugins: `solid`, `paraglide`, `vite-plus` and the three plugins of
|
|
485
|
-
this package (`project`, `backend`, `architecture`).
|
|
486
|
-
- Type-aware rules and type checking (`typeAware`, `typeCheck`).
|
|
487
|
-
- Warnings fail the run (`denyWarnings`), and an unused disable directive is an
|
|
488
|
-
error.
|
|
489
|
-
|
|
490
|
-
Every rule is listed by name in the preset. No Oxlint category is enabled, so an
|
|
491
|
-
Oxlint update does not add rules on its own.
|
|
492
|
-
|
|
493
|
-
### Rules of this package
|
|
494
|
-
|
|
495
|
-
| Rule | What it enforces |
|
|
496
|
-
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
497
|
-
| `project/css-modules-import` | A CSS Module is imported as the default binding `S` |
|
|
498
|
-
| `project/css-filename` | A CSS file imported from `src/` is named `styles.module.css`, or `camelCase.css` inside `src/theme/` |
|
|
499
|
-
| `project/test-filename` | A test file sits in `__tests__` next to its module and is named after it, plus the environment: `Button/__tests__/Button.dom.test.tsx` |
|
|
500
|
-
| `project/no-export-list` | Exports sit on the declaration. `export { a, b }` is only allowed with `from` |
|
|
501
|
-
| `project/seo-module` | A route `seo.ts` exports only `seo`. It has no relative value import, no value import from `src/routes/`, no computed `import()` and no `import.meta.glob` |
|
|
502
|
-
| `backend/static-solid-imports` | No `import()` of `@solidjs/web` or its subpaths |
|
|
503
|
-
| `backend/static-render-integrity-imports` | No `import()` of the `renderIntegrity` module |
|
|
504
|
-
| `architecture/layer-imports` | Lower layers do not import upper ones, and production code does not import tests or `tooling/` |
|
|
505
|
-
|
|
506
|
-
These rules read import specifiers as text. They resolve relative paths and the
|
|
507
|
-
`@/`, `@paraglide/` and `/src/` prefixes. An `import()` with a computed path and
|
|
508
|
-
any other alias are not checked, except in `seo.ts`, where a computed `import()`
|
|
509
|
-
is an error.
|
|
510
|
-
|
|
511
|
-
`architecture/layer-imports` checks these directions:
|
|
512
|
-
|
|
513
|
-
- The base layer (`src/@types`, `constants`, `helpers`, `data`, `infra`,
|
|
514
|
-
`theme`, `i18n` and `paraglide/`) does not import primitives, components,
|
|
515
|
-
routes or entry files.
|
|
516
|
-
- `src/primitives` does not import components, routes or entry files.
|
|
517
|
-
- Atoms do not import molecules or organisms, and molecules do not import
|
|
518
|
-
organisms.
|
|
519
|
-
- No production file imports a test or `tooling/`.
|
|
520
|
-
|
|
521
|
-
The entry files are `App`, `Document`, `entry-server`, `entry-client`, `router`
|
|
522
|
-
and `middleware`, at the root of `src/`.
|
|
523
|
-
|
|
524
|
-
`project/test-filename` accepts these names:
|
|
525
|
-
|
|
526
|
-
- `Name.<environment>.test.ts(x)` in `src/`, where the environment is `node`,
|
|
527
|
-
`dom`, `browser` or `e2e`.
|
|
528
|
-
- `Name.test-d.ts(x)` in `src/`, for type tests.
|
|
529
|
-
- `Name.test.ts` in `tooling/`.
|
|
530
|
-
|
|
531
|
-
`Name` is the folder that holds `__tests__`. A qualifier may follow it:
|
|
532
|
-
`Button.focus.dom.test.tsx`. End-to-end tests are the exception: they live in
|
|
533
|
-
`src/tests/pages/<Page>/` and are named after the page.
|
|
534
|
-
|
|
535
|
-
### Backend restrictions
|
|
536
|
-
|
|
537
|
-
Inside `src/`, the preset also restricts what code can reach:
|
|
538
|
-
|
|
539
|
-
- `console` is not allowed. `src/infra/server/logServerFailure/index.ts` is the
|
|
540
|
-
only module that may call `console.error`.
|
|
541
|
-
- `fetch`, `XMLHttpRequest`, `WebSocket` and `EventSource` are not allowed.
|
|
542
|
-
`src/infra/server/requestJson/index.ts` is the only module that may call
|
|
543
|
-
`fetch`.
|
|
544
|
-
- The Node transports (`http`, `https`, `http2`, `net`, `tls`, `undici`) cannot
|
|
545
|
-
be imported.
|
|
546
|
-
- `markSafeError` and `SAFE_ERROR` can only be imported in
|
|
547
|
-
`src/infra/server/publicErrors/index.ts`.
|
|
548
|
-
- `configureServerErrors` from `@solidjs/web`, the
|
|
549
|
-
`@solidjs/web/server-functions` subpath and `observeRenderFailures` from the
|
|
550
|
-
application's `renderIntegrity` module can only be imported in
|
|
551
|
-
`src/infra/server/configureServerErrors/index.ts`.
|
|
552
|
-
- A relative import goes up at most three levels. Use `@/` beyond that.
|
|
553
|
-
|
|
554
|
-
Test files and `.d.ts` files are exempt from all of these except the relative
|
|
555
|
-
import limit.
|
|
556
|
-
|
|
557
|
-
## Changing the preset
|
|
558
|
-
|
|
559
|
-
`lint` and `fmt` are plain objects. Spread them and replace what the application
|
|
560
|
-
needs:
|
|
561
|
-
|
|
562
|
-
```ts
|
|
563
|
-
// vite.config.ts
|
|
564
|
-
import { fmt } from '@evertondgn/solid-tooling/fmt'
|
|
565
|
-
import { lint } from '@evertondgn/solid-tooling/lint'
|
|
566
|
-
import { defineConfig } from 'vite-plus'
|
|
567
|
-
|
|
568
|
-
export default defineConfig({
|
|
569
|
-
fmt,
|
|
570
|
-
lint: {
|
|
571
|
-
...lint,
|
|
572
|
-
ignorePatterns: [...(lint.ignorePatterns ?? []), 'generated/**'],
|
|
573
|
-
rules: { ...lint.rules, 'eslint/max-params': 'off' }
|
|
574
|
-
}
|
|
575
|
-
})
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
Do not replace `lint.jsPlugins`. It registers the JavaScript plugins listed
|
|
579
|
-
above, and a rule whose plugin is missing from it fails to resolve.
|
|
580
|
-
|
|
581
|
-
To turn a rule off for some files only, add an entry to `lint.overrides` and
|
|
582
|
-
keep the existing ones:
|
|
583
|
-
|
|
584
|
-
```ts
|
|
585
|
-
overrides: [
|
|
586
|
-
...(lint.overrides ?? []),
|
|
587
|
-
{
|
|
588
|
-
files: ['src/tests/pages/Checkout/**'],
|
|
589
|
-
rules: { 'project/test-filename': 'off' }
|
|
590
|
-
}
|
|
591
|
-
]
|
|
592
|
-
```
|
|
593
|
-
|
|
594
|
-
## Entry points
|
|
595
|
-
|
|
596
|
-
| Entry | Content |
|
|
597
|
-
| ------------------------ | ------------------------------------------------------------------------- |
|
|
598
|
-
| `./lint` | `lint`: the lint preset, with the plugins below registered |
|
|
599
|
-
| `./fmt` | `fmt`: the formatter config |
|
|
600
|
-
| `./tsconfig.base.json` | Compiler options, without application paths |
|
|
601
|
-
| `./tsconfig.app.json` | The base plus the `types` and `include` of the boilerplate layout |
|
|
602
|
-
| `./vite` | `defineSolidApp(options)`, the whole `vite.config.ts` of an application |
|
|
603
|
-
| `./vitest` | `solidTest(options)`, the `test` block of `vite.config.ts` |
|
|
604
|
-
| `./playwright` | `definePlaywrightConfig(options)`, the Playwright config |
|
|
605
|
-
| `./vitest-setup/browser` | Setup file of the browser project, loaded by `./vitest` |
|
|
606
|
-
| `./playwright-teardown` | Server log check, loaded by `./playwright` |
|
|
607
|
-
| `./project-plugin` | The `project` rules |
|
|
608
|
-
| `./backend-plugin` | The `backend` rules |
|
|
609
|
-
| `./architecture-plugin` | The `architecture` rule |
|
|
610
|
-
| `./solid-plugin` | Re-export of `eslint-plugin-solid` |
|
|
611
|
-
| `./css-filename` | `cssFilenameError(path)`, the CSS naming check, for a script outside lint |
|
|
612
|
-
| `./knip` | `defineKnipConfig(options)`, the Knip config |
|
|
613
|
-
| `./stylelint` | `checkCss(root)` and `defineStylelintConfig(root)`, the CSS lint |
|
|
614
|
-
| `./commitlint` | The commitlint config |
|
|
615
|
-
| `./lefthook.yml` | The Git hooks, extended from the application's `.lefthook.yml` |
|
|
616
|
-
|
|
617
|
-
An application imports `./vite`, which brings `./lint`, `./fmt` and `./vitest`
|
|
618
|
-
along, `./playwright`, `./knip`, `./stylelint` and one of the TypeScript
|
|
619
|
-
configs, and extends `./commitlint` and `./lefthook.yml`. An application that
|
|
620
|
-
only lints imports `./lint` and `./fmt`. The plugin entries exist because Oxlint
|
|
621
|
-
loads plugins by specifier, from the application; the setup and teardown entries
|
|
622
|
-
are loaded by the test presets.
|
|
623
|
-
|
|
624
|
-
## Formatter
|
|
625
|
-
|
|
626
|
-
`fmt` sets 80 columns, single quotes, no semicolons, no trailing commas, wrapped
|
|
627
|
-
prose in Markdown and sorted imports. It ignores `public/`, `src/assets/`,
|
|
628
|
-
generated route types, SVG and lock files.
|
|
629
|
-
|
|
630
|
-
## TypeScript base
|
|
631
|
-
|
|
632
|
-
`tsconfig.base.json` targets ES2024 with bundler resolution, keeps JSX for the
|
|
633
|
-
Solid compiler (`jsxImportSource: @solidjs/web`), emits nothing and turns on the
|
|
634
|
-
unused code and unchecked index checks. It has no `paths`, `include` or `types`.
|
|
635
|
-
|
|
636
|
-
`tsconfig.app.json` extends the base with the `types` of a boilerplate
|
|
637
|
-
application and an `include` resolved from the application folder with
|
|
638
|
-
`${configDir}`, which needs TypeScript 5.5 or later. Each entry of `types` comes
|
|
639
|
-
from a package the application installs:
|
|
640
|
-
|
|
641
|
-
| Entry of `types` | Package |
|
|
642
|
-
| --------------------------------------- | --------------------------- |
|
|
643
|
-
| `node` | `@types/node` |
|
|
644
|
-
| `vite/client` | `vite` |
|
|
645
|
-
| `vite-plus/test/globals` | `vite-plus` |
|
|
646
|
-
| `@testing-library/jest-dom/vitest` | `@testing-library/jest-dom` |
|
|
647
|
-
| `@solidjs/vite-plugin/boundary-modules` | `@solidjs/vite-plugin` |
|
|
648
|
-
| `@solidjs/vite-plugin/virtual-modules` | `@solidjs/vite-plugin` |
|
|
649
|
-
|
|
650
|
-
The application still declares its `paths`:
|
|
651
|
-
|
|
652
|
-
```json
|
|
653
|
-
{
|
|
654
|
-
"extends": "@evertondgn/solid-tooling/tsconfig.app.json",
|
|
655
|
-
"compilerOptions": {
|
|
656
|
-
"paths": { "@/*": ["./src/*"], "@paraglide/*": ["./paraglide/*"] }
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
Playwright reads the `tsconfig.json` of the test files with its own loader,
|
|
662
|
-
which does not expand `${configDir}`, so paths declared in the package would
|
|
663
|
-
break the `@/` imports of the end-to-end tests.
|
|
664
|
-
|
|
665
|
-
## Known limits
|
|
666
|
-
|
|
667
|
-
- The package ships compiled JavaScript. Node refuses to run TypeScript from
|
|
668
|
-
`node_modules`, and Vite+ loads `vite.config.ts` in Node.
|
|
669
|
-
- `project/test-filename` has no options. Test folders without a module, such as
|
|
670
|
-
the page tests in `src/tests/pages/`, are listed inside the package with the
|
|
671
|
-
names used in boilerplate_solidjs. For any other folder of that kind, turn the
|
|
672
|
-
rule off in `lint.overrides`, as shown in
|
|
673
|
-
[Changing the preset](#changing-the-preset).
|
|
674
|
-
- The Paraglide plugin is always registered, so `@inlang/paraglide-js` has to be
|
|
675
|
-
installed even in an application without translations.
|
|
676
|
-
- Some rule messages point to `docs/architecture.md` and `AGENTS.md`. Those
|
|
677
|
-
files belong to the application created from boilerplate_solidjs.
|
|
678
|
-
- The test presets expect the boilerplate layout: tests named by suffix
|
|
679
|
-
(`.node.test`, `.dom.test`, `.browser.test`, `.e2e.test`), page tests in
|
|
680
|
-
`src/tests/pages/`, Paraglide output in `paraglide/` and `.env.test` at the
|
|
681
|
-
root.
|
|
682
|
-
- The Knip and CSS configs expect the same layout: pages in `src/routes/`,
|
|
683
|
-
fixture routes in `src/tests/fixtures/` and the theme in `src/theme/`.
|
|
684
|
-
- The Knip config ignores every unlisted dependency in its own file, not only
|
|
685
|
-
this package.
|
|
686
|
-
- `./vite` expects the same layout: its tasks run scripts in `tooling/`, and the
|
|
687
|
-
Markdown rules need the locale prefix of the Paraglide `urlPatterns` in every
|
|
688
|
-
URL. Nitro always uses the `vercel` preset. The plugin packages are pinned, so
|
|
689
|
-
a new version of Solid, Nitro, the router or the icons plugin needs a package
|
|
690
|
-
version tested with it.
|
|
691
|
-
|
|
692
|
-
## Versions
|
|
201
|
+
`HOST`, `PORT` and `BASE_URL_TEST` are optional; `PORT` produces a number.
|
|
202
|
+
Declare the runtime package in `dependencies` and keep the tooling in
|
|
203
|
+
`devDependencies`: Knip treats `env.ts` as production code. Extend `server` and
|
|
204
|
+
`client` with the application's own Standard Schema validators. The runtime
|
|
205
|
+
supplies Valibot for its fragment; declare a validator library in the
|
|
206
|
+
application only when its own code imports it. The optional SEO configuration
|
|
207
|
+
validates `VITE_SITE_URL` separately. An application without `env.ts` keeps
|
|
208
|
+
working, including client-only applications with no site URL.
|
|
209
|
+
|
|
210
|
+
The Solid plugin generates inferred types and rejects server env imports in the
|
|
211
|
+
client graph. The server virtual module bundles the fragment and validator; env
|
|
212
|
+
validation adds neither to the client. See the
|
|
213
|
+
[environment guide](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/app-config.md#optional-environment-validation)
|
|
214
|
+
for extension examples, boot validation and type generation.
|
|
215
|
+
|
|
216
|
+
## How it is verified
|
|
217
|
+
|
|
218
|
+
<picture>
|
|
219
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/verified-dark.webp" />
|
|
220
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/verified-light.webp" />
|
|
221
|
+
<img src="https://raw.githubusercontent.com/everton-dgn/solidjs_base/main/docs/assets/readme/verified-light.webp" alt="At this revision: 775 runtime and 394 application Vitest tests, 1169 combined; 164 fixture E2E cases and 155 production E2E cases, 319 enumerated. Installed tarballs check exports and builds with both Bun linkers. Release workflows use npm trusted publishing." width="800" />
|
|
222
|
+
</picture>
|
|
223
|
+
|
|
224
|
+
Package changes run against the complete boilerplate and the runtime package in
|
|
225
|
+
CI, with more than 1,000 Vitest tests and more than 300 end-to-end tests. Before
|
|
226
|
+
each release, the tarball test installs the packed package in a separate
|
|
227
|
+
application outside the workspace and checks its exports and lint rules.
|
|
228
|
+
|
|
229
|
+
The workflow publishes to npm with signed provenance through trusted publishing,
|
|
230
|
+
without a stored npm token. See the
|
|
231
|
+
[CI coverage](https://github.com/everton-dgn/solidjs_base/blob/main/docs/development.md#ci)
|
|
232
|
+
and the
|
|
233
|
+
[release process](https://github.com/everton-dgn/solidjs_base/blob/main/docs/releasing.md).
|
|
234
|
+
|
|
235
|
+
## Reference
|
|
236
|
+
|
|
237
|
+
- [Lint rules and customization](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/lint.md)
|
|
238
|
+
- [Application config, plugins and tasks](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/app-config.md)
|
|
239
|
+
- [Vitest and Playwright](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/testing.md)
|
|
240
|
+
- [Knip and CSS](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/knip-and-css.md)
|
|
241
|
+
- [Commit messages and Git hooks](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/commits-and-hooks.md)
|
|
242
|
+
- [TypeScript and formatting](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/typescript-and-format.md)
|
|
243
|
+
- [Requirements, limits and versions](https://github.com/everton-dgn/solidjs_base/blob/main/docs/tooling/limits.md)
|
|
244
|
+
|
|
245
|
+
## Versions and license
|
|
693
246
|
|
|
694
247
|
The package follows semantic versioning. Below 1.0.0, a breaking change raises
|
|
695
|
-
the minor version.
|
|
696
|
-
[changelog](https://github.com/everton-dgn/solidjs_base/blob/main/packages/solid-tooling/CHANGELOG.md)
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
248
|
+
the minor version. Read the
|
|
249
|
+
[changelog](https://github.com/everton-dgn/solidjs_base/blob/main/packages/solid-tooling/CHANGELOG.md)
|
|
250
|
+
for each release.
|
|
251
|
+
|
|
252
|
+
[MIT](https://github.com/everton-dgn/solidjs_base/blob/main/LICENSE)
|
|
253
|
+
|
|
254
|
+
Publication is compiled into the preset and uses one build identity for the SSR
|
|
255
|
+
and artifact manifests. It no longer needs an application `extend` callback.
|
|
256
|
+
`publication/read-llms-index` exposes the compiled index reader for artifact
|
|
257
|
+
checks in Node. See
|
|
258
|
+
[ADR 0034](../../docs/ADRs/0034-runtime-markdown-publication.md) for independent
|
|
259
|
+
feature options, defaults, disabled-resource behavior and scale.
|