@ttsc/unplugin 0.28.2 → 0.28.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/README.md +71 -7
- package/lib/api.js +3 -0
- package/lib/api.js.map +1 -1
- package/lib/api.mjs +1 -0
- package/lib/api.mjs.map +1 -1
- package/lib/core/index.d.cts +17 -6
- package/lib/core/index.d.mts +17 -6
- package/lib/core/index.d.ts +17 -6
- package/lib/core/index.js +131 -18
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs +130 -19
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/transform.d.cts +116 -29
- package/lib/core/transform.d.mts +116 -29
- package/lib/core/transform.d.ts +116 -29
- package/lib/core/transform.js +1502 -222
- package/lib/core/transform.js.map +1 -1
- package/lib/core/transform.mjs +1503 -223
- package/lib/core/transform.mjs.map +1 -1
- package/lib/core/tsconfigPaths.d.cts +61 -0
- package/lib/core/tsconfigPaths.d.mts +61 -0
- package/lib/core/tsconfigPaths.d.ts +61 -0
- package/lib/core/tsconfigPaths.js +190 -7
- package/lib/core/tsconfigPaths.js.map +1 -1
- package/lib/core/tsconfigPaths.mjs +188 -8
- package/lib/core/tsconfigPaths.mjs.map +1 -1
- package/lib/next.d.cts +27 -10
- package/lib/next.d.mts +27 -10
- package/lib/next.d.ts +27 -10
- package/lib/next.js +229 -8
- package/lib/next.js.map +1 -1
- package/lib/next.mjs +229 -8
- package/lib/next.mjs.map +1 -1
- package/lib/turbopack.d.cts +5 -4
- package/lib/turbopack.d.mts +5 -4
- package/lib/turbopack.d.ts +5 -4
- package/lib/turbopack.js +13 -7
- package/lib/turbopack.js.map +1 -1
- package/lib/turbopack.mjs +14 -8
- package/lib/turbopack.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/index.ts +136 -18
- package/src/core/transform.ts +2070 -254
- package/src/core/tsconfigPaths.ts +254 -8
- package/src/next.ts +262 -10
- package/src/turbopack.ts +13 -9
package/README.md
CHANGED
|
@@ -118,11 +118,13 @@ const nextConfig = {
|
|
|
118
118
|
export default withTtsc(nextConfig);
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
`withTtsc` covers Next.js
|
|
121
|
+
`withTtsc` covers both of Next.js's bundlers. It injects the webpack plugin and wires the Turbopack loader rules, with the options you pass reaching both, so the same config works whether Next runs on Turbopack (the default in current majors) or on webpack. Your own `webpack` hook and `turbopack` block are preserved: unrelated rules and settings survive, and a rule you already wired for this loader by hand is left alone rather than registered twice.
|
|
122
|
+
|
|
123
|
+
That last part is decided by exact spelling. `withTtsc` declines to add its own rule when your glob is one it has measured against a real Turbopack build as naming every file with the extension — `*.ts`, `**/*.ts`, `{**/,}*.ts`, `*.tsx`, `**/*.tsx`, `*.{ts,tsx}`, `{*.ts,*.tsx}`, `**/*.{ts,tsx}`, `**/{*.ts,*.tsx}`, `**/**/*.{ts,tsx}`. Any other spelling keeps your rule and gains ours beside it, so a module may be transformed twice rather than not at all. The list is exact on purpose: treating an unmeasured glob as project-wide once left every module in a project with no `ttsc` rule at all, and a build that transforms twice is recoverable in a way a build that never transforms is not.
|
|
122
124
|
|
|
123
125
|
### Turbopack
|
|
124
126
|
|
|
125
|
-
Turbopack has no JS plugin API, but it runs webpack loaders through `turbopack.rules`, and a ttsc transform is exactly loader-shaped (TypeScript source in, transformed source out). `@ttsc/unplugin/turbopack` is that standalone loader:
|
|
127
|
+
Turbopack has no JS plugin API, but it runs webpack loaders through `turbopack.rules`, and a ttsc transform is exactly loader-shaped (TypeScript source in, transformed source out). `@ttsc/unplugin/turbopack` is that standalone loader. In a Next.js project `withTtsc` wires it for you; wire it directly when Turbopack runs outside Next, or when you want the rules under your own control:
|
|
126
128
|
|
|
127
129
|
```js
|
|
128
130
|
// next.config.mjs
|
|
@@ -138,7 +140,7 @@ const nextConfig = {
|
|
|
138
140
|
export default nextConfig;
|
|
139
141
|
```
|
|
140
142
|
|
|
141
|
-
Pass options through the rule's `options` object: `{ loader: "@ttsc/unplugin/turbopack", options: { project: "tsconfig.build.json" } }`. The loader keeps a per-worker compiler cache (Turbopack runs loaders in a worker pool) and returns the source unchanged for declaration files, `node_modules` paths, and transforms that produce no change.
|
|
143
|
+
Pass options through the rule's `options` object: `{ loader: "@ttsc/unplugin/turbopack", options: { project: "tsconfig.build.json" } }`. The loader keeps a per-worker compiler cache (Turbopack runs loaders in a worker pool) and returns the source unchanged for everything the adapters' shared filter excludes (declaration files, `node_modules` paths, non-TypeScript sources, and virtual ids) and for transforms that produce no change.
|
|
142
144
|
|
|
143
145
|
### Farm
|
|
144
146
|
|
|
@@ -165,6 +167,22 @@ await Bun.build({
|
|
|
165
167
|
});
|
|
166
168
|
```
|
|
167
169
|
|
|
170
|
+
For `bun run` and `bun test`, where there is no bundling step, register the same transform on Bun's module loader through `@ttsc/unplugin/bun-register`. Preload it once in `bunfig.toml`:
|
|
171
|
+
|
|
172
|
+
```toml
|
|
173
|
+
preload = ["@ttsc/unplugin/bun-register"]
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Or register it imperatively, optionally with options:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import register from "@ttsc/unplugin/bun-register";
|
|
180
|
+
|
|
181
|
+
register({ project: "tsconfig.build.json" });
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Importing the module registers it, so a bare `import "@ttsc/unplugin/bun-register"` is enough when the defaults are right. Registration is idempotent: a later explicit call updates the options rather than installing a second loader, because Bun uses the first matching `onLoad` hook and never falls through to an overlapping one.
|
|
185
|
+
|
|
168
186
|
Under `Bun.build`, the adapter yields to the next loader for declarations, `node_modules`, source that `ttsc` leaves unchanged, and entries supplied through `Bun.build({ files })`. In-memory entries remain with Bun because ttsc transforms filesystem-backed project inputs. Bun's runtime `onLoad` contract does not accept an undefined result, so `Bun.plugin()` explicitly passes excluded and unchanged filesystem files through with their original source. `Bun.build` clears the project generation through its `onStart` lifecycle on every build. The runtime API has no corresponding hook, so one setup is treated as one immutable module-loading session: restart the Bun process after changing source, tsconfig, or plugin inputs.
|
|
169
187
|
|
|
170
188
|
## Configuration
|
|
@@ -283,9 +301,15 @@ Supported entrypoints are:
|
|
|
283
301
|
- `@ttsc/unplugin/farm`
|
|
284
302
|
- `@ttsc/unplugin/next`
|
|
285
303
|
- `@ttsc/unplugin/bun`
|
|
304
|
+
- `@ttsc/unplugin/bun-register`
|
|
305
|
+
- `@ttsc/unplugin/api`
|
|
286
306
|
|
|
287
307
|
Each entrypoint supports ESM import and CJS require. In CommonJS configs, read the default export from `require("@ttsc/unplugin/vite").default`. `@ttsc/unplugin/turbopack` is not an unplugin factory but a standalone webpack loader; reference it by module name inside `turbopack.rules` instead of calling it.
|
|
288
308
|
|
|
309
|
+
`@ttsc/unplugin/bun-register` is the Bun **runtime** entry rather than a bundler adapter, covered under [Bun](#bun) above. `@ttsc/unplugin/api` exposes the transform core itself (`transformTtsc`, `resolveOptions`, the cache lifecycle) for hosts that are not unplugin-shaped; `@ttsc/metro` is built on it.
|
|
310
|
+
|
|
311
|
+
That entry point also exposes the project-membership rule — `readProjectMembershipPolicy`, `mergeMembershipPolicyOverlay`, `ITtscProjectMembershipPolicy`, `isProjectWalkPath` and the input-hash collectors — which decides which files can enter the compiled program and therefore which changes invalidate a cached compile. These exist so a host that keeps its own cache asks that question exactly the way the transform core asks it: `@ttsc/metro` folds them into Metro's static transformer key, and the two halves disagreeing about one project is the bug class they exist to prevent. They are shaped for that use rather than as a general-purpose configuration reader, and they move with the core rather than under a stability guarantee of their own. Build a host on them if you need it; pin your `@ttsc/unplugin` version if you do.
|
|
312
|
+
|
|
289
313
|
### Options
|
|
290
314
|
|
|
291
315
|
```ts
|
|
@@ -304,15 +328,55 @@ const options: TtscUnpluginOptions = {
|
|
|
304
328
|
- `compilerOptions`: temporary override layered on the selected project config.
|
|
305
329
|
- `plugins`: direct `ttsc` plugin list override, or `false` to disable plugins.
|
|
306
330
|
|
|
331
|
+
#### Path Aliases
|
|
332
|
+
|
|
333
|
+
Under Vite, the adapter reads the resolved `resolve.alias` and layers it onto the generated config, so an alias declared only in `vite.config.ts` still resolves during the compile. No other host's alias configuration is read: under Rollup, Rolldown, webpack, Rspack, esbuild, Farm, Turbopack and Bun, the compile resolves through the tsconfig's own `paths` alone. Declare an alias in `paths` when a module has to resolve for the compiler as well as for the bundler, which is what those hosts need anyway for `tsc` to type-check the same imports.
|
|
334
|
+
|
|
335
|
+
Not every Vite alias form can be forwarded, because a tsconfig `paths` map cannot express all of them:
|
|
336
|
+
|
|
337
|
+
| `resolve.alias` form | Forwarded |
|
|
338
|
+
| --- | --- |
|
|
339
|
+
| `{ "@": "/src" }`, or the array form with a string `find` | yes |
|
|
340
|
+
| array form with a `RegExp` `find`, such as `{ find: /^~/ }` | no — `paths` has no regular-expression form |
|
|
341
|
+
| a string `find` containing `*` | no — a `paths` key already reads `*` as its own wildcard |
|
|
342
|
+
|
|
343
|
+
In both unforwarded cases the compile resolves that specifier through the tsconfig's `paths` alone, so declare it there if `ttsc` must resolve through it — a prefix `RegExp` such as `/^~/` is written as a `"~/*"` entry. Reducing simple prefix patterns automatically is deliberately not attempted: distinguishing `/^~/` from `/^@app/`, which also matches `@apple`, needs enough of a regular-expression engine that a wrong reduction becomes likely, and a mistranslated alias resolves imports to the wrong file without saying so.
|
|
344
|
+
|
|
345
|
+
A `find` containing `*` is also reported once on stderr, naming the alias and the reason. A `RegExp` `find` is not, and the asymmetry is deliberate: Vite merges two `RegExp` aliases of its own into every resolved config, for `@vite/env` and `@vite/client`, so a report on that form would fire in every build of every project and name aliases you never wrote.
|
|
346
|
+
|
|
307
347
|
### Cache and Watch Invalidation
|
|
308
348
|
|
|
309
|
-
|
|
349
|
+
Editing a type that only a generated validator depends on invalidates the module, in watch mode, in webpack's filesystem cache and in Turbopack's `fileDependencies`, even though the bundler erased the type-only import from its own graph. The adapter registers each transformed file's reference closure, the global-scope files, the configs and the resolution candidates with the bundler, plus whatever the plugins themselves report. The [setup guide](https://ttsc.dev/docs/setup/unplugin) describes how that set is derived and proven.
|
|
350
|
+
|
|
351
|
+
One whole-project compile already contains every module's output, so the adapter compiles the project once and serves every module from that one result. Everything below is about when it may keep doing that.
|
|
352
|
+
|
|
353
|
+
#### When the generation is reused
|
|
354
|
+
|
|
355
|
+
A host with a build boundary opens a delivery pass there. The pass's first delivery proves the whole generation against the current filesystem once, and after that each module's first delivery in the pass is settled by the supplied source alone. `buildStart` repeats per rebuild under webpack, Rspack, Rollup, Rolldown, esbuild and `vite build --watch`, so a pass boundary means "each module is requested at most once from here", not "the compiled program is stale".
|
|
356
|
+
|
|
357
|
+
Hosts with no build boundary (Metro workers, the Turbopack loader, and a watching Vite dev server, whose one `buildStart` spans later HMR edits) validate each generation hit against the inputs that can affect the module being asked for: its reference closure, the global-scope files, the configs, the resolution candidates, and the plugin dependencies. Sibling modules share one proof of the closure rather than repeating it per module.
|
|
358
|
+
|
|
359
|
+
Project membership comes from the resolved configuration rather than from a list of directory names. `allowJs` and `resolveJsonModule` decide which file extensions can enter the program, so a bundle emitted beside your sources is not a membership change for a project that compiles no JavaScript. `outDir`, `declarationDir` and the plain entries of `exclude` name the directories the program does not contain, and those are not walked at all. Everywhere else, a directory takes part in membership only while it can hold a program input, so an output directory no configuration names still costs nothing as long as what it holds is not admissible, and the first source appearing in it is detected because the directory is walked and watched throughout. A project that does admit JavaScript should name its bundler's output directory in `exclude`, since otherwise an emitted `.js` there is a program input like any other. Emptying and recreating a directory the configuration names, which `emptyOutDir` and `output.clean` do on every build, costs nothing either.
|
|
360
|
+
|
|
361
|
+
#### When it is discarded
|
|
362
|
+
|
|
363
|
+
An input change or an explicit cache lifecycle reset permits a new generation. Opening a pass is not such a reset.
|
|
364
|
+
|
|
365
|
+
A compile that failed outright is retained for the rest of that pass, so its remaining modules replay the verdict instead of repeating an identical failing compile once per module, and the next pass attempts it again. A host with no pass boundary keeps evicting a failed compile on every delivery, so a transient toolchain failure never becomes permanent for a long-lived worker.
|
|
366
|
+
|
|
367
|
+
#### What this changes for you
|
|
368
|
+
|
|
369
|
+
A module the compiled program does not contain is left untransformed and reported once per pass, naming the file and the tsconfig it is missing from. This is not a build error: the file is simply not this project's to transform, and the usual cause is a bundle graph that reaches further than the tsconfig's `include`. Add it there if ttsc plugins should apply to it.
|
|
370
|
+
|
|
371
|
+
A file whose transform no plugin can contribute to is validated against the universal inputs and itself rather than its whole reference closure. Its diagnostics narrow with it, so a type error introduced in such a file surfaces at the next compile the build runs for another reason rather than at the edit. Run the compiler's own check beside the bundler when you want type errors at the edit.
|
|
372
|
+
|
|
373
|
+
A Bun runtime plugin registration is one process-scoped module-loading session, so restart the Bun process after changing source, tsconfig, or plugin inputs.
|
|
310
374
|
|
|
311
|
-
|
|
375
|
+
A dev server started without a watcher (`server.watch: null`, which is what `vitest --run` configures) takes the pass lifecycle instead of per-delivery validation. Nothing can deliver a change event to such a session, so per-delivery validation there buys incoherence rather than freshness: modules delivered before an edit and after it would come from two different compilations of one program.
|
|
312
376
|
|
|
313
|
-
|
|
377
|
+
Freshness proofs rest on filesystem timestamps, so two environments need care. A project on a network mount that accepts a watch and then reports nothing should be treated as one where notifications do not work. And a clock that jumps backwards, or a tree restored with stamps set into the future, defeats any stamp-based proof; a clock running at a constant offset does not, since it moves both sides of every comparison.
|
|
314
378
|
|
|
315
|
-
The
|
|
379
|
+
The [setup guide](https://ttsc.dev/docs/setup/unplugin) describes how these proofs are built.
|
|
316
380
|
|
|
317
381
|
## Sponsors
|
|
318
382
|
|
package/lib/api.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var index = require('./core/index.js');
|
|
4
4
|
var transform = require('./core/transform.js');
|
|
5
|
+
var tsconfigPaths = require('./core/tsconfigPaths.js');
|
|
5
6
|
var options = require('./core/options.js');
|
|
6
7
|
|
|
7
8
|
|
|
@@ -16,5 +17,7 @@ exports.createTtscTransformCache = transform.createTtscTransformCache;
|
|
|
16
17
|
exports.isProjectWalkPath = transform.isProjectWalkPath;
|
|
17
18
|
exports.resetTtscTransformCache = transform.resetTtscTransformCache;
|
|
18
19
|
exports.transformTtsc = transform.transformTtsc;
|
|
20
|
+
exports.mergeMembershipPolicyOverlay = tsconfigPaths.mergeMembershipPolicyOverlay;
|
|
21
|
+
exports.readProjectMembershipPolicy = tsconfigPaths.readProjectMembershipPolicy;
|
|
19
22
|
exports.resolveOptions = options.resolveOptions;
|
|
20
23
|
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/api.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { isTransformTarget, sourceFilePattern, default as unplugin } from './core/index.mjs';
|
|
2
2
|
export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, transformTtsc } from './core/transform.mjs';
|
|
3
|
+
export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy } from './core/tsconfigPaths.mjs';
|
|
3
4
|
export { resolveOptions } from './core/options.mjs';
|
|
4
5
|
//# sourceMappingURL=api.mjs.map
|
package/lib/api.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/lib/core/index.d.cts
CHANGED
|
@@ -3,21 +3,32 @@ import type { TtscUnpluginOptions } from "./options.cjs";
|
|
|
3
3
|
import { resolveOptions } from "./options.cjs";
|
|
4
4
|
import { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, transformTtsc } from "./transform.cjs";
|
|
5
5
|
/**
|
|
6
|
-
* Matches
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Matches the TypeScript source extensions the ttsc transform handles: `.ts`,
|
|
7
|
+
* `.tsx`, `.mts`, `.cts` and their `x` forms. JavaScript is deliberately not
|
|
8
|
+
* among them, so a `.js` module reaches no adapter's transform.
|
|
9
|
+
*
|
|
10
|
+
* Shared with the Bun adapter (`bun.ts`) and the standalone Turbopack loader
|
|
11
|
+
* (`turbopack.ts`) through {@link isTransformTarget}, so the filter is defined
|
|
12
|
+
* once and every adapter answers the same way.
|
|
9
13
|
*/
|
|
10
14
|
export declare const sourceFilePattern: RegExp;
|
|
11
15
|
declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
|
|
12
16
|
export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options.cjs";
|
|
13
17
|
export type { TtscTransformFilesystemOperations, TtscTransformHooks, TtscWatchInputEvidence, } from "./transform.cjs";
|
|
18
|
+
export type { ITtscProjectMembershipPolicy } from "./tsconfigPaths.cjs";
|
|
19
|
+
export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy, } from "./tsconfigPaths.cjs";
|
|
14
20
|
export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, resolveOptions, transformTtsc, unplugin, };
|
|
15
21
|
export default unplugin;
|
|
16
22
|
/**
|
|
17
|
-
* Returns `true` when the module id refers to a real TypeScript
|
|
18
|
-
*
|
|
23
|
+
* Returns `true` when the module id refers to a real TypeScript source file
|
|
24
|
+
* that should be processed by the ttsc transform.
|
|
25
|
+
*
|
|
26
|
+
* TypeScript only. {@link sourceFilePattern} deliberately excludes JavaScript,
|
|
27
|
+
* so a `.js` module reaches no adapter's transform, and this docstring used to
|
|
28
|
+
* say otherwise while the pattern it is built from said the truth
|
|
29
|
+
* (samchon/ttsc#1309).
|
|
19
30
|
*
|
|
20
|
-
*
|
|
31
|
+
* Also excluded: virtual modules (NUL prefix), `.d.ts` declaration files, and
|
|
21
32
|
* anything inside `node_modules`.
|
|
22
33
|
*/
|
|
23
34
|
export declare function isTransformTarget(id: string): boolean;
|
package/lib/core/index.d.mts
CHANGED
|
@@ -3,21 +3,32 @@ import type { TtscUnpluginOptions } from "./options.mjs";
|
|
|
3
3
|
import { resolveOptions } from "./options.mjs";
|
|
4
4
|
import { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, transformTtsc } from "./transform.mjs";
|
|
5
5
|
/**
|
|
6
|
-
* Matches
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Matches the TypeScript source extensions the ttsc transform handles: `.ts`,
|
|
7
|
+
* `.tsx`, `.mts`, `.cts` and their `x` forms. JavaScript is deliberately not
|
|
8
|
+
* among them, so a `.js` module reaches no adapter's transform.
|
|
9
|
+
*
|
|
10
|
+
* Shared with the Bun adapter (`bun.ts`) and the standalone Turbopack loader
|
|
11
|
+
* (`turbopack.ts`) through {@link isTransformTarget}, so the filter is defined
|
|
12
|
+
* once and every adapter answers the same way.
|
|
9
13
|
*/
|
|
10
14
|
export declare const sourceFilePattern: RegExp;
|
|
11
15
|
declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
|
|
12
16
|
export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options.mjs";
|
|
13
17
|
export type { TtscTransformFilesystemOperations, TtscTransformHooks, TtscWatchInputEvidence, } from "./transform.mjs";
|
|
18
|
+
export type { ITtscProjectMembershipPolicy } from "./tsconfigPaths.mjs";
|
|
19
|
+
export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy, } from "./tsconfigPaths.mjs";
|
|
14
20
|
export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, resolveOptions, transformTtsc, unplugin, };
|
|
15
21
|
export default unplugin;
|
|
16
22
|
/**
|
|
17
|
-
* Returns `true` when the module id refers to a real TypeScript
|
|
18
|
-
*
|
|
23
|
+
* Returns `true` when the module id refers to a real TypeScript source file
|
|
24
|
+
* that should be processed by the ttsc transform.
|
|
25
|
+
*
|
|
26
|
+
* TypeScript only. {@link sourceFilePattern} deliberately excludes JavaScript,
|
|
27
|
+
* so a `.js` module reaches no adapter's transform, and this docstring used to
|
|
28
|
+
* say otherwise while the pattern it is built from said the truth
|
|
29
|
+
* (samchon/ttsc#1309).
|
|
19
30
|
*
|
|
20
|
-
*
|
|
31
|
+
* Also excluded: virtual modules (NUL prefix), `.d.ts` declaration files, and
|
|
21
32
|
* anything inside `node_modules`.
|
|
22
33
|
*/
|
|
23
34
|
export declare function isTransformTarget(id: string): boolean;
|
package/lib/core/index.d.ts
CHANGED
|
@@ -3,21 +3,32 @@ import type { TtscUnpluginOptions } from "./options";
|
|
|
3
3
|
import { resolveOptions } from "./options";
|
|
4
4
|
import { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, transformTtsc } from "./transform";
|
|
5
5
|
/**
|
|
6
|
-
* Matches
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Matches the TypeScript source extensions the ttsc transform handles: `.ts`,
|
|
7
|
+
* `.tsx`, `.mts`, `.cts` and their `x` forms. JavaScript is deliberately not
|
|
8
|
+
* among them, so a `.js` module reaches no adapter's transform.
|
|
9
|
+
*
|
|
10
|
+
* Shared with the Bun adapter (`bun.ts`) and the standalone Turbopack loader
|
|
11
|
+
* (`turbopack.ts`) through {@link isTransformTarget}, so the filter is defined
|
|
12
|
+
* once and every adapter answers the same way.
|
|
9
13
|
*/
|
|
10
14
|
export declare const sourceFilePattern: RegExp;
|
|
11
15
|
declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
|
|
12
16
|
export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options";
|
|
13
17
|
export type { TtscTransformFilesystemOperations, TtscTransformHooks, TtscWatchInputEvidence, } from "./transform";
|
|
18
|
+
export type { ITtscProjectMembershipPolicy } from "./tsconfigPaths";
|
|
19
|
+
export { mergeMembershipPolicyOverlay, readProjectMembershipPolicy, } from "./tsconfigPaths";
|
|
14
20
|
export { beginTtscTransformBuild, collectExternalInputHashes, collectProjectInputHashes, createTtscTransformCache, isProjectWalkPath, resetTtscTransformCache, resolveOptions, transformTtsc, unplugin, };
|
|
15
21
|
export default unplugin;
|
|
16
22
|
/**
|
|
17
|
-
* Returns `true` when the module id refers to a real TypeScript
|
|
18
|
-
*
|
|
23
|
+
* Returns `true` when the module id refers to a real TypeScript source file
|
|
24
|
+
* that should be processed by the ttsc transform.
|
|
25
|
+
*
|
|
26
|
+
* TypeScript only. {@link sourceFilePattern} deliberately excludes JavaScript,
|
|
27
|
+
* so a `.js` module reaches no adapter's transform, and this docstring used to
|
|
28
|
+
* say otherwise while the pattern it is built from said the truth
|
|
29
|
+
* (samchon/ttsc#1309).
|
|
19
30
|
*
|
|
20
|
-
*
|
|
31
|
+
* Also excluded: virtual modules (NUL prefix), `.d.ts` declaration files, and
|
|
21
32
|
* anything inside `node_modules`.
|
|
22
33
|
*/
|
|
23
34
|
export declare function isTransformTarget(id: string): boolean;
|
package/lib/core/index.js
CHANGED
|
@@ -8,12 +8,17 @@ var unplugin$1 = require('unplugin');
|
|
|
8
8
|
var options = require('./options.js');
|
|
9
9
|
var transform = require('./transform.js');
|
|
10
10
|
var viteServe = require('./viteServe.js');
|
|
11
|
+
var tsconfigPaths = require('./tsconfigPaths.js');
|
|
11
12
|
|
|
12
13
|
const name = "ttsc-unplugin";
|
|
13
14
|
/**
|
|
14
|
-
* Matches
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Matches the TypeScript source extensions the ttsc transform handles: `.ts`,
|
|
16
|
+
* `.tsx`, `.mts`, `.cts` and their `x` forms. JavaScript is deliberately not
|
|
17
|
+
* among them, so a `.js` module reaches no adapter's transform.
|
|
18
|
+
*
|
|
19
|
+
* Shared with the Bun adapter (`bun.ts`) and the standalone Turbopack loader
|
|
20
|
+
* (`turbopack.ts`) through {@link isTransformTarget}, so the filter is defined
|
|
21
|
+
* once and every adapter answers the same way.
|
|
17
22
|
*/
|
|
18
23
|
const sourceFilePattern = /\.[cm]?tsx?$/;
|
|
19
24
|
/** Matches any path segment that is a `node_modules` directory (cross-platform). */
|
|
@@ -27,13 +32,15 @@ const virtualModulePattern = /\0/;
|
|
|
27
32
|
* Unplugin factory that wires the ttsc transform pipeline into any supported
|
|
28
33
|
* bundler (Vite, Rollup, Rolldown, webpack, Rspack, esbuild, Farm).
|
|
29
34
|
*
|
|
30
|
-
* The factory resolves raw options once, creates
|
|
31
|
-
* and captures Vite alias configuration via the
|
|
32
|
-
* that path aliases are forwarded to the
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* The factory resolves raw options once, creates one transform cache for the
|
|
36
|
+
* whole plugin instance, and captures Vite alias configuration via the
|
|
37
|
+
* `vite.configResolved` hook so that path aliases are forwarded to the
|
|
38
|
+
* generated tsconfig overlay. A host with a real `buildStart` opens a delivery
|
|
39
|
+
* pass there and keeps its generation across passes; a watching Vite
|
|
40
|
+
* development server keeps persistent validation instead, because its one
|
|
41
|
+
* `buildStart` spans later HMR edits and so cannot mark a pass, while a dev
|
|
42
|
+
* server configured without a watcher takes the pass lifecycle with them,
|
|
43
|
+
* having declared it will observe no edit at all.
|
|
37
44
|
*/
|
|
38
45
|
const unpluginFactory = (rawOptions = {}) => {
|
|
39
46
|
const options$1 = options.resolveOptions(rawOptions);
|
|
@@ -42,6 +49,17 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
42
49
|
let aliases;
|
|
43
50
|
let viteCommand;
|
|
44
51
|
let viteWatching = true;
|
|
52
|
+
// Whether a build-mode session is driven by Rollup's watcher. `build.watch`
|
|
53
|
+
// is `null` for an ordinary build and an object under `--watch`, which is the
|
|
54
|
+
// axis the disposal boundary actually turns on: only a watching build repeats
|
|
55
|
+
// its build phase, and only a watching build ends at `closeWatcher`.
|
|
56
|
+
let viteBuildWatching = false;
|
|
57
|
+
// A restart can start the replacement plugin container before closing the
|
|
58
|
+
// old one, and Vite calls buildEnd even for a container that never started.
|
|
59
|
+
// Track the stable per-container PluginContext identity so that unstarted
|
|
60
|
+
// old containers cannot dispose a replacement's freshly initialized cache.
|
|
61
|
+
let viteBuildOwners = new WeakSet();
|
|
62
|
+
let viteBuildLifecycles = 0;
|
|
45
63
|
return {
|
|
46
64
|
name,
|
|
47
65
|
enforce: "pre",
|
|
@@ -63,6 +81,13 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
63
81
|
// (samchon/ttsc#1246).
|
|
64
82
|
viteWatching =
|
|
65
83
|
config.server?.watch !== null;
|
|
84
|
+
// Read on the same principle as the line above, from the half of the
|
|
85
|
+
// config that governs a build rather than a server. The comparison is
|
|
86
|
+
// loose where the server's is strict because the two defaults differ:
|
|
87
|
+
// `server.watch` is an object unless explicitly `null`, while
|
|
88
|
+
// `build.watch` is absent or `null` unless `--watch` supplies one.
|
|
89
|
+
viteBuildWatching =
|
|
90
|
+
config.build?.watch != null;
|
|
66
91
|
},
|
|
67
92
|
// Vite serve funnels every transform-context `addWatchFile()` into the
|
|
68
93
|
// module's added-import graph (`_addedImports`), which import-analysis
|
|
@@ -73,13 +98,90 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
73
98
|
configureServer(server) {
|
|
74
99
|
missingInputs.attach(server);
|
|
75
100
|
},
|
|
76
|
-
// Vite calls buildEnd when the dev server
|
|
77
|
-
//
|
|
101
|
+
// Vite calls buildEnd when the dev server closes, and Rollup calls it at
|
|
102
|
+
// the end of every build phase; drop every poller and, once the last
|
|
103
|
+
// overlapping container has closed, every generation-owned filesystem
|
|
104
|
+
// tracker as well.
|
|
105
|
+
//
|
|
106
|
+
// Disposing here is right wherever the end of a build phase is also the
|
|
107
|
+
// end of the session: a dev server, and an ordinary one-shot build. It is
|
|
108
|
+
// wrong for a watching build, whose watcher repeats build phases, so it
|
|
109
|
+
// means "this pass ended" there — measured as
|
|
110
|
+
// `buildStart -> buildEnd -> ... -> buildStart -> buildEnd` across
|
|
111
|
+
// `vite build --watch` rebuilds. Disposing on that repeat discarded the
|
|
112
|
+
// generation once per rebuild independently of the `buildStart` clear, so
|
|
113
|
+
// fixing one of the two sites alone left this host recompiling the whole
|
|
114
|
+
// project per edit (samchon/ttsc#1301). The watching build hands its
|
|
115
|
+
// teardown to `closeWatcher` below instead.
|
|
78
116
|
buildEnd() {
|
|
79
117
|
missingInputs.dispose();
|
|
118
|
+
if (viteBuildOwners.delete(this)) {
|
|
119
|
+
viteBuildLifecycles -= 1;
|
|
120
|
+
}
|
|
121
|
+
if (viteBuildLifecycles === 0 &&
|
|
122
|
+
(viteCommand === "serve" || !viteBuildWatching)) {
|
|
123
|
+
transform.resetTtscTransformCache(transformCache);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
// The watching build's real teardown, and the only hook in a
|
|
127
|
+
// `vite build --watch` trace that fires exactly once: buildEnd,
|
|
128
|
+
// writeBundle and closeBundle all repeat per rebuild there. A generation
|
|
129
|
+
// retained across passes owns directory watchers, so this is where they
|
|
130
|
+
// are released. Vite's dev server drives no Rollup watcher and an
|
|
131
|
+
// ordinary build closes its bundle instead, so neither reaches here;
|
|
132
|
+
// a host that fired both would simply reset twice, which is idempotent.
|
|
133
|
+
//
|
|
134
|
+
// The container bookkeeping is cleared with the cache, and the owner set
|
|
135
|
+
// is replaced rather than merely zeroed alongside it. A watcher closed
|
|
136
|
+
// mid-rebuild leaves a container still registered, and its later
|
|
137
|
+
// `buildEnd` would then decrement a counter that is already zero and
|
|
138
|
+
// strand it below zero, after which the disposal above could never fire
|
|
139
|
+
// again for this plugin instance.
|
|
140
|
+
closeWatcher() {
|
|
141
|
+
viteBuildOwners = new WeakSet();
|
|
142
|
+
viteBuildLifecycles = 0;
|
|
143
|
+
transform.resetTtscTransformCache(transformCache);
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
// Rollup and Rolldown carry none of the Vite block's hooks, so before this
|
|
147
|
+
// they had no disposal site at all. They get both halves of the same
|
|
148
|
+
// boundary: a watching session ends at `closeWatcher`, and a one-shot build
|
|
149
|
+
// ends when its build phase does. `this.meta.watchMode` separates the two
|
|
150
|
+
// there, the way `build.watch` does for Vite, so a one-shot build is not
|
|
151
|
+
// left without a site the way `vite build` was (samchon/ttsc#1301).
|
|
152
|
+
// unplugin merges each of these blocks only into its own adapter, so the
|
|
153
|
+
// Vite adapter never receives them.
|
|
154
|
+
//
|
|
155
|
+
// A `buildEnd` at the top level instead of inside a block would be a
|
|
156
|
+
// regression rather than a shorthand: unplugin forwards a top-level one to
|
|
157
|
+
// esbuild's `onEnd` and to webpack's and Rspack's `hooks.emit`, each of
|
|
158
|
+
// which repeats per rebuild, so those hosts would start discarding a valid
|
|
159
|
+
// generation on every edit, which is samchon/ttsc#1300 again.
|
|
160
|
+
rollup: {
|
|
161
|
+
buildEnd() {
|
|
162
|
+
if (this.meta?.watchMode !== true) {
|
|
163
|
+
transform.resetTtscTransformCache(transformCache);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
closeWatcher() {
|
|
167
|
+
transform.resetTtscTransformCache(transformCache);
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
rolldown: {
|
|
171
|
+
buildEnd() {
|
|
172
|
+
if (this.meta?.watchMode !== true) {
|
|
173
|
+
transform.resetTtscTransformCache(transformCache);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
closeWatcher() {
|
|
177
|
+
transform.resetTtscTransformCache(transformCache);
|
|
80
178
|
},
|
|
81
179
|
},
|
|
82
180
|
buildStart() {
|
|
181
|
+
if (viteCommand !== undefined && !viteBuildOwners.has(this)) {
|
|
182
|
+
viteBuildOwners.add(this);
|
|
183
|
+
viteBuildLifecycles += 1;
|
|
184
|
+
}
|
|
83
185
|
// Persistent validation exists for a session that spans edits it can
|
|
84
186
|
// observe, and a dev server told to open no watcher is not one:
|
|
85
187
|
// `server.watch: null` leaves Vite with no change channel at all, so no
|
|
@@ -87,14 +189,18 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
87
189
|
// no client is hot-updated. Validating each delivery there does not buy
|
|
88
190
|
// freshness, it buys incoherence — modules delivered before an edit and
|
|
89
191
|
// after it would come from two different compilations of one program —
|
|
90
|
-
// while costing a full derived-input proof per delivered module. The
|
|
91
|
-
//
|
|
92
|
-
//
|
|
192
|
+
// while costing a full derived-input proof per delivered module. The pass
|
|
193
|
+
// lifecycle settles each module's first delivery against the generation
|
|
194
|
+
// the session started from, exactly as a build does, and still
|
|
93
195
|
// revalidates a module this session already delivered. A one-shot suite
|
|
94
196
|
// configures precisely this server (`vitest --run` sets `server.watch =
|
|
95
197
|
// null`) and is the workload behind samchon/ttsc#970
|
|
96
198
|
// (samchon/ttsc#1260). The neighbouring watch-registration decision reads
|
|
97
199
|
// the same two properties for the same reason.
|
|
200
|
+
//
|
|
201
|
+
// Opening a pass no longer discards the generation, so the `else` branch
|
|
202
|
+
// is what every host with a repeating `buildStart` takes without paying a
|
|
203
|
+
// whole-project transform per rebuild (samchon/ttsc#1300).
|
|
98
204
|
if (viteCommand === "serve" && viteWatching) {
|
|
99
205
|
transform.resetTtscTransformCache(transformCache);
|
|
100
206
|
}
|
|
@@ -160,10 +266,15 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
160
266
|
};
|
|
161
267
|
const unplugin = unplugin$1.createUnplugin(unpluginFactory);
|
|
162
268
|
/**
|
|
163
|
-
* Returns `true` when the module id refers to a real TypeScript
|
|
164
|
-
*
|
|
269
|
+
* Returns `true` when the module id refers to a real TypeScript source file
|
|
270
|
+
* that should be processed by the ttsc transform.
|
|
271
|
+
*
|
|
272
|
+
* TypeScript only. {@link sourceFilePattern} deliberately excludes JavaScript,
|
|
273
|
+
* so a `.js` module reaches no adapter's transform, and this docstring used to
|
|
274
|
+
* say otherwise while the pattern it is built from said the truth
|
|
275
|
+
* (samchon/ttsc#1309).
|
|
165
276
|
*
|
|
166
|
-
*
|
|
277
|
+
* Also excluded: virtual modules (NUL prefix), `.d.ts` declaration files, and
|
|
167
278
|
* anything inside `node_modules`.
|
|
168
279
|
*/
|
|
169
280
|
function isTransformTarget(id) {
|
|
@@ -181,6 +292,8 @@ exports.createTtscTransformCache = transform.createTtscTransformCache;
|
|
|
181
292
|
exports.isProjectWalkPath = transform.isProjectWalkPath;
|
|
182
293
|
exports.resetTtscTransformCache = transform.resetTtscTransformCache;
|
|
183
294
|
exports.transformTtsc = transform.transformTtsc;
|
|
295
|
+
exports.mergeMembershipPolicyOverlay = tsconfigPaths.mergeMembershipPolicyOverlay;
|
|
296
|
+
exports.readProjectMembershipPolicy = tsconfigPaths.readProjectMembershipPolicy;
|
|
184
297
|
exports.default = unplugin;
|
|
185
298
|
exports.isTransformTarget = isTransformTarget;
|
|
186
299
|
exports.sourceFilePattern = sourceFilePattern;
|
package/lib/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","createViteServeMissingInputWatch","resetTtscTransformCache","beginTtscTransformBuild","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","createViteServeMissingInputWatch","resetTtscTransformCache","beginTtscTransformBuild","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":"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"}
|