webanvil 0.0.6 → 0.0.7

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.
Files changed (63) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +490 -38
  3. package/bin/webanvil +6 -0
  4. package/bin/webanvil.cmd +2 -0
  5. package/dist/_chunks/commands.mjs +1867 -0
  6. package/dist/cli.d.mts +1 -0
  7. package/dist/cli.mjs +30 -0
  8. package/dist/index.d.mts +646 -0
  9. package/dist/index.mjs +5 -0
  10. package/package.json +96 -60
  11. package/bin/run +0 -3
  12. package/bin/run.cmd +0 -3
  13. package/lib/commands/build.d.ts +0 -3
  14. package/lib/commands/build.d.ts.map +0 -1
  15. package/lib/commands/build.js +0 -34
  16. package/lib/commands/serve.d.ts +0 -3
  17. package/lib/commands/serve.d.ts.map +0 -1
  18. package/lib/commands/serve.js +0 -44
  19. package/lib/commons/io/core/File.d.ts +0 -11
  20. package/lib/commons/io/core/File.d.ts.map +0 -1
  21. package/lib/commons/io/core/File.js +0 -23
  22. package/lib/commons/io/core/Path.d.ts +0 -30
  23. package/lib/commons/io/core/Path.d.ts.map +0 -1
  24. package/lib/commons/io/core/Path.js +0 -122
  25. package/lib/commons/io/sync/fs.d.ts +0 -11
  26. package/lib/commons/io/sync/fs.d.ts.map +0 -1
  27. package/lib/commons/io/sync/fs.js +0 -46
  28. package/lib/commons/io/sync/index.d.ts +0 -5
  29. package/lib/commons/io/sync/index.d.ts.map +0 -1
  30. package/lib/commons/io/sync/index.js +0 -9
  31. package/lib/commons/io/sync/path.d.ts +0 -4
  32. package/lib/commons/io/sync/path.d.ts.map +0 -1
  33. package/lib/commons/io/sync/path.js +0 -13
  34. package/lib/core/Configuration.d.ts +0 -37
  35. package/lib/core/Configuration.d.ts.map +0 -1
  36. package/lib/core/Configuration.js +0 -56
  37. package/lib/core/EventEmitter.d.ts +0 -14
  38. package/lib/core/EventEmitter.d.ts.map +0 -1
  39. package/lib/core/EventEmitter.js +0 -42
  40. package/lib/core/Page.d.ts +0 -14
  41. package/lib/core/Page.d.ts.map +0 -1
  42. package/lib/core/Page.js +0 -34
  43. package/lib/core/Plugin.d.ts +0 -13
  44. package/lib/core/Plugin.d.ts.map +0 -1
  45. package/lib/core/Plugin.js +0 -12
  46. package/lib/core/Renderer/Renderer.d.ts +0 -8
  47. package/lib/core/Renderer/Renderer.d.ts.map +0 -1
  48. package/lib/core/Renderer/Renderer.js +0 -9
  49. package/lib/core/Renderer/index.d.ts +0 -8
  50. package/lib/core/Renderer/index.d.ts.map +0 -1
  51. package/lib/core/Renderer/index.js +0 -18
  52. package/lib/index.d.ts +0 -1
  53. package/lib/index.d.ts.map +0 -1
  54. package/lib/index.js +0 -1
  55. package/lib/main.d.ts +0 -2
  56. package/lib/main.d.ts.map +0 -1
  57. package/lib/main.js +0 -36
  58. package/lib/plugins/outlinecss.d.ts +0 -4
  59. package/lib/plugins/outlinecss.d.ts.map +0 -1
  60. package/lib/plugins/outlinecss.js +0 -34
  61. package/lib/renderers/EJSRenderer.d.ts +0 -7
  62. package/lib/renderers/EJSRenderer.d.ts.map +0 -1
  63. package/lib/renderers/EJSRenderer.js +0 -34
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Mateusz Pietrzak
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.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mateusz Pietrzak
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,38 +1,490 @@
1
- <div align="center">
2
-
3
- [![license](https://img.shields.io/npm/l/webanvil.svg)](https://github.com/mzpkdev/webanvil/blob/master/LICENSE)
4
- [![npm version](https://img.shields.io/npm/v/webanvil.svg)](https://www.npmjs.com/package/webanvil)
5
- [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
- [![bundle size](https://img.shields.io/bundlephobia/min/webanvil)](https://bundlephobia.com/result?p=webanvil)
7
-
8
- </div>
9
- <br>
10
- <br>
11
-
12
- <p align="center">
13
- <strong>WebAnvil</strong>
14
- <p align="center">
15
- A zero configuration static site generator that just works.
16
- <br />
17
- <br />
18
- <a href="https://github.com/mzpkdev/webanvil/issues">Report a bug</a>
19
- &nbsp;&nbsp;·&nbsp;&nbsp;
20
- <a href="https://github.com/mzpkdev/webanvil/issues">Request a feature</a>
21
- </p>
22
- <br />
23
- <br />
24
-
25
- Table of Contents
26
- ------------------
27
-
28
- * [Getting started](#getting-started)
29
- * [How to install](#how-to-install)
30
-
31
- Getting started
32
- ----------------
33
-
34
- ### How to install
35
-
36
- ```shell
37
- npm install webanvil
38
- ```
1
+ <div align="center">
2
+ <img src=".github/assets/banner.svg" width="1012" alt="WebAnvil: build the web, forge the backend" />
3
+
4
+ <p>
5
+ <strong>WebAnvil</strong> · one CLI for building, testing, linting, formatting, and type-checking JavaScript and TypeScript projects
6
+ <br />
7
+ <br />
8
+ <a href="#getting-started"><strong>Get started »</strong></a>
9
+ <br />
10
+ <br />
11
+ <a href="https://github.com/mzpkdev/webanvil/issues">Report a bug</a>
12
+ &nbsp;&nbsp;·&nbsp;&nbsp;
13
+ <a href="https://github.com/mzpkdev/webanvil/issues">Request a feature</a>
14
+ </p>
15
+ </div>
16
+
17
+ Table of contents
18
+ -----------------
19
+
20
+ - [Why WebAnvil?](#why-webanvil)
21
+ - [What it includes](#what-it-includes)
22
+ - [Getting started](#getting-started)
23
+ - [Install](#install)
24
+ - [Everyday commands](#everyday-commands)
25
+ - [A web app](#a-web-app)
26
+ - [A Node project](#a-node-project)
27
+ - [Configuration](#configuration)
28
+ - [Tool selection](#tool-selection)
29
+ - [Native tool configuration](#native-tool-configuration)
30
+ - [Node declarations](#node-declarations)
31
+ - [Command-line options](#command-line-options)
32
+ - [Migration](#migration)
33
+ - [Command reference](#command-reference)
34
+
35
+ Why WebAnvil?
36
+ -------------
37
+
38
+ JavaScript projects usually need a builder, a development server, a test runner, a linter, a formatter, and a type checker. Each tool has its own command and configuration. That is workable, but it makes the project setup longer than it needs to be.
39
+
40
+ WebAnvil puts the common jobs behind `wa`. It uses Vite for web projects, Rolldown for Node builds, Vitest for tests, and Oxc for linting and formatting. You keep those tools, but package scripts and the first layer of configuration stay in one place.
41
+
42
+ ```sh
43
+ wa dev # develop a web app or watch a Node build
44
+ wa build # build the project
45
+ wa preview # serve the production web build
46
+ wa clean # remove tracked build output
47
+ wa check # check formatting, linting, and types
48
+ wa check --fix # format files and apply safe lint fixes before type checking
49
+ wa test # run tests, watch them, collect coverage, or open the UI
50
+ wa lint # lint files
51
+ wa format # format files
52
+ wa typecheck # type-check the project
53
+ ```
54
+
55
+ What it includes
56
+ ----------------
57
+
58
+ | Project job | WebAnvil command | Tool |
59
+ | -------------------------- | ---------------------------------- | -------------------------------- |
60
+ | Web builds and development | `wa build`, `wa dev`, `wa preview` | Vite |
61
+ | Node builds and watch mode | `wa build`, `wa dev` | Rolldown |
62
+ | Tracked output cleanup | `wa clean` | WebAnvil |
63
+ | Static checks | `wa check` | Oxfmt, Oxlint, TypeScript Native |
64
+ | Tests | `wa test` | Vitest |
65
+ | Linting | `wa lint` | Oxlint |
66
+ | Formatting | `wa format` | Oxfmt |
67
+ | Type checking | `wa typecheck` | TypeScript Native |
68
+
69
+ Getting started
70
+ ---------------
71
+
72
+ ### Install
73
+
74
+ Install WebAnvil as a development dependency:
75
+
76
+ ```sh
77
+ npm install --save-dev webanvil
78
+ ```
79
+
80
+ Your package manager remains responsible for dependencies, the lockfile, and
81
+ the installed tree. WebAnvil never installs or updates tools. When a supported
82
+ tool is declared directly by the active project, or by a workspace that contains
83
+ it, WebAnvil uses that installed version. Otherwise it uses the exact version
84
+ shipped with WebAnvil.
85
+
86
+ Add the scripts you want to `package.json`:
87
+
88
+ ```json
89
+ {
90
+ "scripts": {
91
+ "dev": "wa dev",
92
+ "build": "wa build",
93
+ "clean": "wa clean",
94
+ "check": "wa check",
95
+ "test": "wa test",
96
+ "lint": "wa lint",
97
+ "format": "wa format",
98
+ "typecheck": "wa typecheck"
99
+ }
100
+ }
101
+ ```
102
+
103
+ You can start without a config file. WebAnvil defaults to a Node project with `src/index.ts` as its entry and `dist` as its output directory.
104
+
105
+ ### Everyday commands
106
+
107
+ Run the commands through npm or directly with `wa`:
108
+
109
+ ```sh
110
+ npm run dev
111
+ npm run build
112
+ npm run clean
113
+ npm run check
114
+ npm run test
115
+ npm run lint
116
+ npm run format
117
+ npm run typecheck
118
+ ```
119
+
120
+ `wa check` checks formatting, linting, and types sequentially, stopping on the
121
+ first failure. It is read-only by default. Use `wa check --fix` to format files
122
+ and apply safe lint fixes before type checking. Tests stay separate under
123
+ `wa test`.
124
+
125
+ ### A web app
126
+
127
+ Set the build mode to `"web"` and point it at an HTML entry point. `wa dev` starts Vite's development server, `wa build` produces a production bundle, and `wa preview` serves that bundle locally.
128
+
129
+ ```ts
130
+ import { defineConfig } from "webanvil"
131
+
132
+ export default defineConfig({
133
+ build: {
134
+ mode: "web",
135
+ entry: "index.html",
136
+ outDir: "dist",
137
+ copy: [{ from: "assets/**", to: "assets" }]
138
+ }
139
+ })
140
+ ```
141
+
142
+ Pass framework plugins through your WebAnvil configuration:
143
+
144
+ ```ts
145
+ import react from "@vitejs/plugin-react"
146
+ import { defineConfig } from "webanvil"
147
+
148
+ export default defineConfig({
149
+ build: { mode: "web", entry: "index.html" },
150
+ plugins: [react()]
151
+ })
152
+ ```
153
+
154
+ ### A Node project
155
+
156
+ Node mode is the default. Declare the package's public roots with `entry` or
157
+ `entries`, then choose whether Rolldown should preserve or bundle the reachable
158
+ module graph:
159
+
160
+ ```ts
161
+ import { defineConfig } from "webanvil"
162
+
163
+ export default defineConfig({
164
+ build: {
165
+ mode: "node",
166
+ entries: {
167
+ ".": "src/index.ts",
168
+ "./feature": "src/internal/implementation.ts"
169
+ },
170
+ outDir: "dist",
171
+ bundle: true,
172
+ formats: ["esm", "cjs"],
173
+ declaration: true,
174
+ sourcemap: true,
175
+ platform: "node",
176
+ target: "es2022"
177
+ }
178
+ })
179
+ ```
180
+
181
+ Without `bundle`, Rolldown uses `preserveModules` and emits only modules
182
+ reachable from the public roots. It does not mirror the source tree, so tests,
183
+ examples, setup files, and other unreachable modules are omitted. With
184
+ `bundle`, those same roots become bundle entries. An explicit positional entry
185
+ overrides configured `entries`.
186
+
187
+ TypeScript paths, native Rolldown aliases and resolver plugins, and package
188
+ export conditions resolve before WebAnvil decides whether an import is a
189
+ dependency. Project-local results stay in the graph. Node built-ins and
190
+ installed packages remain external with their original portable specifiers,
191
+ while unresolved imports fail the build.
192
+
193
+ `platform` (`node`, `browser`, or `neutral`) is Node-only. `target` is one
194
+ syntax target or an array; CLI lists are comma-separated. Node defaults are
195
+ `platform: "node"` and `target: "node20"`. Web production forwards only an
196
+ explicit target; Vite config wins, and web dev does not apply it.
197
+
198
+ For Node builds, WebAnvil fills omitted output settings from the nearest
199
+ `package.json`: `import` and `require` export conditions enable ESM and CommonJS
200
+ respectively, while a top-level `types` field or `types` export condition enables
201
+ declarations. Explicit CLI options override `webanvil.config.*`, which overrides
202
+ package metadata, which overrides built-in defaults. Package metadata does not
203
+ affect web builds.
204
+
205
+ `wa dev` watches and rebuilds Node output with the same `build` configuration as
206
+ `wa build`: bundle mode, entries, formats, declarations, source maps,
207
+ minification, platform, target, plugins, static copies, stale-output cleanup, and
208
+ build metadata all stay in sync. It does not run or restart the server process.
209
+
210
+ Node output is transactional. WebAnvil generates every requested format before
211
+ writing, rejects filename or copy collisions, and replaces the previous output
212
+ only after the complete build succeeds. A failed one-shot build or watch cycle
213
+ rolls back to the last successful files and build metadata.
214
+
215
+ ### Node build plugins
216
+
217
+ Node builds use Rolldown. To use a plugin in both web and Node builds, wrap an
218
+ unplugin implementation with `definePlugin()`:
219
+
220
+ ```ts
221
+ import { defineConfig, definePlugin } from "webanvil"
222
+ import { createUnplugin } from "unplugin"
223
+
224
+ const replace = createUnplugin<{ from: string; to: string }>((options) => ({
225
+ name: "replace",
226
+ transform: (code) => code.replace(options.from, options.to)
227
+ }))
228
+
229
+ export default defineConfig({
230
+ plugins: [definePlugin(replace, { from: "development", to: "production" })]
231
+ })
232
+ ```
233
+
234
+ Plain Vite plugins work in effective web mode. Effective Node builds require
235
+ plugins created with `definePlugin()`; raw Vite and Rolldown plugins are rejected
236
+ during config validation after explicit CLI overrides are applied.
237
+
238
+ Configuration
239
+ -------------
240
+
241
+ Use `webanvil.config.ts` to keep WebAnvil orchestration and native tool settings
242
+ together:
243
+
244
+ ```ts
245
+ import { defineConfig } from "webanvil"
246
+
247
+ export default defineConfig({
248
+ build: {
249
+ mode: "web",
250
+ entry: "index.html",
251
+ outDir: "dist"
252
+ },
253
+ vite: {
254
+ base: "/app/"
255
+ },
256
+ test: {
257
+ globals: true,
258
+ environment: "jsdom",
259
+ include: ["test/**/*.test.ts"]
260
+ },
261
+ lint: {
262
+ rules: { "no-console": "deny" }
263
+ },
264
+ format: {
265
+ printWidth: 100,
266
+ semi: false
267
+ }
268
+ })
269
+ ```
270
+
271
+ ### Tool selection
272
+
273
+ WebAnvil selects compatible project and workspace declarations before its own
274
+ fallbacks. A transitive or merely hoisted package is not selected. Each command
275
+ preflights the engines it can dispatch before `webanvil.config.*` is loaded or
276
+ its plugins are evaluated, so a declared command engine that is missing, has
277
+ invalid package identity, or is outside the supported range fails first.
278
+
279
+ | Tool | Supported project/workspace versions | Exact WebAnvil fallback |
280
+ | -------------------------- | ------------------------------------ | ----------------------- |
281
+ | Vite | `>=8.1.5 <9` | `8.1.5` |
282
+ | Vitest | `>=4.1.10 <5` | `4.1.10` |
283
+ | Rolldown | `>=1.2.0 <2` | `1.2.0` |
284
+ | Oxlint | `>=1.75.0 <2` | `1.75.0` |
285
+ | Oxfmt | `>=0.60.0 <0.61` | `0.60.0` |
286
+ | TypeScript (declarations) | `>=5 <7` | `6.0.3` |
287
+ | TypeScript Native (`tsgo`) | `>=7.0.0-dev.20260707.2 <7.0.0` | `7.0.0-dev.20260707.2` |
288
+
289
+ When a tool is first used, the CLI reports its package, version, and source, for
290
+ example `Using rolldown 1.2.0 (project)` or
291
+ `Using rolldown 1.2.0 (webanvil)`.
292
+
293
+ The TypeScript compiler is selected only after configuration enables a
294
+ declaration build, but before Rolldown starts that build. It follows the same
295
+ direct project/workspace declaration and exact-fallback rules.
296
+
297
+ ### Native tool configuration
298
+
299
+ The `vite`, `test`, `rolldown`, `lint`, and `format` blocks use the owning
300
+ tool's exported TypeScript types. WebAnvil validates them as opaque native
301
+ objects and passes compatible upstream options through without duplicating
302
+ their schemas.
303
+
304
+ Precedence is:
305
+
306
+ 1. explicit CLI values for the current run;
307
+ 2. an existing native `vite.config.*`, `vitest.config.*`, `.oxlintrc.json`, or
308
+ `.oxfmtrc.json`;
309
+ 3. the matching native block in `webanvil.config.*`;
310
+ 4. WebAnvil defaults.
311
+
312
+ WebAnvil-owned `build`, `copy`, cross-engine `plugins`, and CLI behavior remain
313
+ orchestration settings. `rolldown.input` and per-format `rolldown.output`
314
+ options extend Node builds; WebAnvil still owns the input roots, output
315
+ directory, format, cleanup, and `preserveModules` strategy.
316
+
317
+ ```ts
318
+ import { defineConfig } from "webanvil"
319
+
320
+ export default defineConfig({
321
+ build: {
322
+ mode: "node",
323
+ entries: { ".": "src/index.ts", "./feature": "src/feature.ts" },
324
+ formats: ["esm", "cjs"]
325
+ },
326
+ rolldown: {
327
+ input: {
328
+ resolve: { conditionNames: ["source", "node", "import"] }
329
+ },
330
+ output: {
331
+ esm: {
332
+ entryFileNames: "[name].mjs",
333
+ chunkFileNames: "chunks/[name]-[hash].mjs"
334
+ },
335
+ cjs: {
336
+ entryFileNames: "[name].js",
337
+ chunkFileNames: "chunks/[name]-[hash].js"
338
+ }
339
+ }
340
+ }
341
+ })
342
+ ```
343
+
344
+ Native `entryFileNames`, `chunkFileNames`, and `assetFileNames` accept the same
345
+ strings or callbacks as Rolldown. WebAnvil records the actual emitted paths, so
346
+ stale-output removal, rollback, build metadata, and `wa clean` follow customized
347
+ names and source maps.
348
+
349
+ ### Node declarations
350
+
351
+ `build.declaration: true` uses `rolldown-plugin-dts` with its TypeScript
352
+ generator. Pass a native declaration options object to select the `"oxc"` or
353
+ `"tsgo"` generator and other plugin settings:
354
+
355
+ ```ts
356
+ import { defineConfig } from "webanvil"
357
+
358
+ export default defineConfig({
359
+ build: {
360
+ declaration: {
361
+ generator: "tsc",
362
+ sourcemap: true
363
+ }
364
+ }
365
+ })
366
+ ```
367
+
368
+ The TypeScript generator selects a compatible project/workspace TypeScript
369
+ declaration when present, otherwise WebAnvil's exact TypeScript fallback.
370
+ Project-local `ts-patch` and TypeScript emit transforms are honored when they
371
+ are directly declared and resolve to that same compiler. Emit transforms
372
+ require the `tsc` generator; Oxc and `tsgo` are explicit alternatives.
373
+
374
+ `rolldown-plugin-dts` owns declaration paths and imports. ESM-only builds attach
375
+ one declaration graph; CommonJS-only and dual-format builds use one
376
+ declaration-only ESM pass. Because the plugin initializes TypeScript in process,
377
+ one process cannot switch to a different compiler path or version after its
378
+ first TypeScript declaration build—run builds needing different compilers in
379
+ separate processes.
380
+
381
+ ### Command-line options
382
+
383
+ Command-line options override the config file. For example, this writes a build to `preview` without changing `webanvil.config.ts`:
384
+
385
+ ```sh
386
+ wa build --out-dir preview
387
+ ```
388
+
389
+ For Node builds and watchers, `--bundle` and `--no-bundle` are explicit
390
+ opposites. `--no-bundle` overrides `build.bundle: true` for that run and emits
391
+ the reachable module graph with Rolldown `preserveModules`.
392
+
393
+ Use `build.copy` for static files that should be copied unchanged after either a
394
+ web or Node build. Each mapping preserves the path beneath the source glob's
395
+ static base. For example, `assets/**` mapped to `assets` copies
396
+ `assets/images/logo.svg` to `dist/assets/images/logo.svg`. `--copy` accepts one
397
+ or more `source=destination` mappings and replaces configured mappings for that
398
+ run:
399
+
400
+ ```sh
401
+ wa build --copy "assets/**=assets" "src/templates/**=templates"
402
+ ```
403
+
404
+ Both paths are relative to the project root: `from` is a file path or glob and
405
+ `to` is an output directory. This is useful for Node runtime files such as Fastify email
406
+ or response templates: `{ from: "src/templates/**", to: "templates" }` makes
407
+ `src/templates/welcome.txt` available as `dist/templates/welcome.txt`.
408
+
409
+ Copy destinations must not resolve to the same file as generated output, another
410
+ mapping, or an untracked file already in the output directory. WebAnvil fails
411
+ instead of overwriting in each case.
412
+
413
+ Node watch mode re-expands copy globs on every rebuild. Changes and deletions to
414
+ currently matched files trigger rebuilds; newly matching files are included on
415
+ the next rebuild.
416
+
417
+ Web builds keep Vite's `publicDir` behavior unchanged. Do not use `copy` for
418
+ assets imported by application code; Vite continues to manage those assets.
419
+
420
+ ### Test modes
421
+
422
+ `wa test` runs once by default. Use `--watch` to rerun affected tests after a
423
+ change, `--coverage` to write V8 coverage reports, or `--ui` to start the
424
+ Vitest UI:
425
+
426
+ ```sh
427
+ wa test --watch
428
+ wa test --coverage
429
+ wa test --ui
430
+ wa test --ui --ui-port 51204
431
+ ```
432
+
433
+ These are run-specific modes; keep persistent Vitest configuration in
434
+ `vitest.config.*`. `--ui-port` selects a strict loopback port and requires
435
+ `--ui`.
436
+
437
+ ### Cleaning build output
438
+
439
+ `wa build` records the actual emitted and copied files in
440
+ `.webanvil/buildinfo.json`. Run `wa clean` to remove only those files across
441
+ every build target; source files and other untracked files stay in place. The
442
+ command leaves `.webanvil/` behind with an empty output list.
443
+
444
+ Migration
445
+ ---------
446
+
447
+ Start with WebAnvil without rewriting your project configuration. You do not need `webanvil.config.ts` before you can use the unified CLI, and you do not need to translate existing Vite, Vitest, or Oxc settings first.
448
+
449
+ Install WebAnvil, then replace the project scripts with the WebAnvil commands:
450
+
451
+ ```json
452
+ {
453
+ "scripts": {
454
+ "dev": "wa dev",
455
+ "build": "wa build",
456
+ "clean": "wa clean",
457
+ "check": "wa check",
458
+ "test": "wa test",
459
+ "lint": "wa lint",
460
+ "format": "wa format",
461
+ "typecheck": "wa typecheck"
462
+ }
463
+ }
464
+ ```
465
+
466
+ For a Node project that follows the defaults, this is enough. WebAnvil reads `src/index.ts`, writes to `dist`, and uses the project's TypeScript configuration when you run `wa typecheck`.
467
+
468
+ Your existing configuration stays in charge. A `vite.config.*` or
469
+ `vitest.config.*` takes precedence over the matching WebAnvil native block.
470
+ `.oxfmtrc.json` and `.oxlintrc.json` do the same for Oxc. Explicit CLI values
471
+ remain the final run-specific override.
472
+
473
+ That lets a project standardize on `wa` now and move settings into `webanvil.config.ts` later, one part at a time. Start with a build entry when it makes sense, then bring over test, lint, or format settings as you touch them.
474
+
475
+ Command reference
476
+ -----------------
477
+
478
+ | Command | Description | Options |
479
+ | ------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
480
+ | `wa build [entry]` | Builds with Vite in web mode or Rolldown in Node mode. | `--mode`, `--out-dir`, `--copy`, `--bundle`, `--no-bundle`, `--formats`, `--declaration`, `--sourcemap`, `--minify`, `--platform`, `--target` |
481
+ | `wa clean` | Removes files emitted by prior WebAnvil builds. | No options |
482
+ | `wa check` | Checks formatting, linting, and types, stopping on the first failure. | `--fix` |
483
+ | `wa dev [entry]` | Starts a Vite server or a full Node build watcher. | `--mode`, `--out-dir`, `--host`, `--port`, `--copy`, `--bundle`, `--no-bundle`, `--formats`, `--declaration`, `--sourcemap`, `--minify`, `--platform`, `--target` |
484
+ | `wa preview` | Serves a Vite production build. | `--out-dir`, `--host`, `--port`, `--open` |
485
+ | `wa test [filters...]` | Runs Vitest once, in watch mode, with coverage, or UI. | `--environment`, `--watch`, `--coverage`, `--ui`, `--ui-port` |
486
+ | `wa lint [paths...]` | Runs Oxlint and treats warnings as failures. | `--fix` |
487
+ | `wa format [paths...]` | Formats with Oxfmt. | `--check` |
488
+ | `wa typecheck [paths...]` | Type-checks with TypeScript Native. | No options |
489
+
490
+ Run `wa <command> --help` for the complete reference for a command.
package/bin/webanvil ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+
3
+ import("../dist/cli.mjs").catch((error) => {
4
+ console.error(error);
5
+ process.exit(1);
6
+ });
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ node "%~dp0\..\dist\cli.mjs" %*