@animus-ui/unplugin 0.1.25 → 0.1.27
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 +12 -3
- package/dist/{core-BqEruPuj.cjs → core-B-uObifz.cjs} +220 -33
- package/dist/{core-CP2SnWlP.mjs → core-vnpaY35A.mjs} +222 -35
- package/dist/core.d.ts +13 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/esbuild.cjs +1 -1
- package/dist/esbuild.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/rollup.cjs +1 -1
- package/dist/rollup.mjs +1 -1
- package/dist/rspack.cjs +1 -1
- package/dist/rspack.mjs +1 -1
- package/dist/webpack.cjs +1 -1
- package/dist/webpack.mjs +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -88,9 +88,18 @@ Options are the shared driver core (`system`, `exclude`, `strict`, `mode`,
|
|
|
88
88
|
default, the dev-signal define, engine dev diagnostics — never process
|
|
89
89
|
lifecycle. When absent, the bundler's own command oracle applies (webpack/
|
|
90
90
|
rspack `compiler.options.mode`, rollup watch mode), else `production`
|
|
91
|
-
(esbuild exposes no signal). `exclude` patterns are glob-aware
|
|
92
|
-
|
|
93
|
-
`.animus`
|
|
91
|
+
(esbuild exposes no signal). `exclude` patterns are glob-aware; a list
|
|
92
|
+
REPLACES the `dist`, `.test.` and `.spec.` defaults, while `node_modules`,
|
|
93
|
+
`.next` and `.animus` always apply. Wherever the bundler writes is
|
|
94
|
+
always excluded too: its output directories (every Vite environment's,
|
|
95
|
+
each output's `dir`, webpack's `output.path` up to its first `[…]`
|
|
96
|
+
placeholder) and its output files by exact name (`outfile`,
|
|
97
|
+
`output.file`). webpack, rspack, esbuild and Vite name them before
|
|
98
|
+
analysis. Rollup and Rolldown name them only after analysis, so a watch
|
|
99
|
+
excludes them from its second build on, and a build that has already
|
|
100
|
+
analysed one reports it (an output file as earlier output; a file inside
|
|
101
|
+
an output directory as earlier output or a source beside the output),
|
|
102
|
+
naming what to add to `exclude`; under `strict` that build fails.
|
|
94
103
|
|
|
95
104
|
The full consumer contract — module-id families, the define contract,
|
|
96
105
|
artifact set, platform matrix — lives in the
|
|
@@ -19,7 +19,7 @@ function hasRequiredSystem(options) {
|
|
|
19
19
|
}
|
|
20
20
|
function resolveHostOptions(raw, cwd = process.cwd()) {
|
|
21
21
|
const options = raw ?? {};
|
|
22
|
-
(0, _animus_ui_extract_pipeline.
|
|
22
|
+
(0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
|
|
23
23
|
(0, _animus_ui_extract_pipeline.assertKnownOptionKeys)(options, ["watch"]);
|
|
24
24
|
if (!hasRequiredSystem(options)) throw new _animus_ui_extract_pipeline.AnimusConfigError("Missing required option `system` — pass `system: \"./src/ds.ts\"` to the Animus plugin.");
|
|
25
25
|
const root = options.root ? (0, node_path.resolve)(cwd, options.root) : cwd;
|
|
@@ -52,6 +52,11 @@ function createHostState() {
|
|
|
52
52
|
pipeline: null,
|
|
53
53
|
mode: null,
|
|
54
54
|
cssText: "",
|
|
55
|
+
served: {
|
|
56
|
+
listed: /* @__PURE__ */ new Set(),
|
|
57
|
+
dropped: /* @__PURE__ */ new Map()
|
|
58
|
+
},
|
|
59
|
+
analyzedFiles: [],
|
|
55
60
|
systemPropsJs: "",
|
|
56
61
|
kitRedirects: /* @__PURE__ */ new Map(),
|
|
57
62
|
kitSideEffects: /* @__PURE__ */ new Map(),
|
|
@@ -59,7 +64,8 @@ function createHostState() {
|
|
|
59
64
|
externalPackageDirs: [],
|
|
60
65
|
watchPaths: [],
|
|
61
66
|
transformFile: null,
|
|
62
|
-
sessionDir: null
|
|
67
|
+
sessionDir: null,
|
|
68
|
+
key: null
|
|
63
69
|
};
|
|
64
70
|
}
|
|
65
71
|
function shouldClaimTransform(filePath, state) {
|
|
@@ -81,7 +87,7 @@ async function drivePipeline(state, run, removeDir) {
|
|
|
81
87
|
try {
|
|
82
88
|
await attempt;
|
|
83
89
|
} catch (error) {
|
|
84
|
-
if (!state.sessionDir) state.sessionDir = (0, _animus_ui_extract_session.getSessionArtifactDir)();
|
|
90
|
+
if (!state.sessionDir && state.key !== null) state.sessionDir = (0, _animus_ui_extract_session.getSessionArtifactDir)(state.key);
|
|
85
91
|
disposeSessionDir(state, removeDir);
|
|
86
92
|
throw error;
|
|
87
93
|
}
|
|
@@ -98,8 +104,20 @@ function substituteDevDefine(code, isDev) {
|
|
|
98
104
|
}
|
|
99
105
|
function transformWithEngine(code, id, ctx) {
|
|
100
106
|
const filename = (0, node_path.relative)(ctx.rootDir, (0, node_path.resolve)(id)).split("\\").join("/");
|
|
107
|
+
const drop = ctx.served?.dropped.get(filename);
|
|
108
|
+
if (drop !== void 0) throw new Error((0, _animus_ui_extract_pipeline.droppedExtensionMessage)(drop));
|
|
101
109
|
const result = ctx.transformFile(code, filename, ctx.manifestJson);
|
|
102
|
-
|
|
110
|
+
if (result.hasComponents) return result.code;
|
|
111
|
+
if (ctx.served?.listed.has(filename)) throw new Error(`[animus] the analysis extracted components from ${filename}, but its transform found none`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/** What a manifest's transform serves, parsed once per run. */
|
|
115
|
+
function manifestServedFiles(manifestJson) {
|
|
116
|
+
if (manifestJson === null) return {
|
|
117
|
+
listed: /* @__PURE__ */ new Set(),
|
|
118
|
+
dropped: /* @__PURE__ */ new Map()
|
|
119
|
+
};
|
|
120
|
+
return (0, _animus_ui_extract_pipeline.servedFiles)(JSON.parse(manifestJson));
|
|
103
121
|
}
|
|
104
122
|
/** Whether esbuild's `external` option names `specifier`: exactly, as the
|
|
105
123
|
* package a subpath belongs to, or through a `*` wildcard. */
|
|
@@ -118,13 +136,52 @@ function moduleFilePath(id) {
|
|
|
118
136
|
function canResolve(context) {
|
|
119
137
|
return "resolve" in context;
|
|
120
138
|
}
|
|
139
|
+
/** Whether a hook context names the environment it builds (Vite). */
|
|
140
|
+
function hasEnvironment(context) {
|
|
141
|
+
return "environment" in context;
|
|
142
|
+
}
|
|
121
143
|
/** Marks the esbuild resolve that `esbuild.setup` makes for itself. */
|
|
122
144
|
const KIT_SOURCE_RESOLVE = "animus:kit-source-resolve";
|
|
145
|
+
/** Rules as comparable text: a RegExp by its source and flags, a function
|
|
146
|
+
* by its text. */
|
|
147
|
+
function ruleText(rules) {
|
|
148
|
+
return JSON.stringify(rules ?? null, (_key, value) => value instanceof RegExp ? `/${value.source}/${value.flags}` : value instanceof Function ? String(value) : value);
|
|
149
|
+
}
|
|
150
|
+
/** Whether `module.defaultRules` is webpack's own default list: the list
|
|
151
|
+
* webpack's defaults give the compiler's experiments, unchanged. Throws
|
|
152
|
+
* where webpack's option API is not available. */
|
|
153
|
+
function defaultRulesAreWebpacks(compiler) {
|
|
154
|
+
const config = compiler.webpack?.config;
|
|
155
|
+
if (config === void 0) throw new Error("webpack's option defaults are not available");
|
|
156
|
+
const { css, asyncWebAssembly, syncWebAssembly } = compiler.options.experiments ?? {};
|
|
157
|
+
const fresh = config.getNormalizedWebpackOptions({ experiments: {
|
|
158
|
+
css,
|
|
159
|
+
asyncWebAssembly,
|
|
160
|
+
syncWebAssembly
|
|
161
|
+
} });
|
|
162
|
+
config.applyWebpackOptionsDefaults(fresh);
|
|
163
|
+
return ruleText(fresh.module?.defaultRules) === ruleText(compiler.options.module?.defaultRules);
|
|
164
|
+
}
|
|
165
|
+
/** Whether every webpack JavaScript parser keeps the default wrapped
|
|
166
|
+
* context, `/.*\/` and recursive. */
|
|
167
|
+
function wrappedContextDefaults(parser) {
|
|
168
|
+
return Object.entries(parser ?? {}).filter(([type]) => type === "javascript" || type.startsWith("javascript/")).every(([, options]) => (options?.wrappedContextRegExp === void 0 || options.wrappedContextRegExp.source === ".*" && options.wrappedContextRegExp.flags === "") && options?.wrappedContextRecursive !== false);
|
|
169
|
+
}
|
|
170
|
+
function hasPluginResolve(context) {
|
|
171
|
+
return "resolve" in context;
|
|
172
|
+
}
|
|
173
|
+
/** The bundler's resolution through a Rollup-family plugin context (Rollup,
|
|
174
|
+
* Rolldown, Vite); none where the context cannot resolve. */
|
|
175
|
+
function pluginResolver(context) {
|
|
176
|
+
if (!hasPluginResolve(context)) return null;
|
|
177
|
+
return async (specifier, importer) => (await context.resolve(specifier, importer, { skipSelf: true }))?.id ?? null;
|
|
178
|
+
}
|
|
123
179
|
const PLUGIN_NAME = "animus-host";
|
|
124
180
|
const ESBUILD_WATCH_HINT = "If this is an esbuild watch or serve context, pass watch: true to the Animus esbuild plugin.";
|
|
125
181
|
const unpluginFactory = (rawOptions, meta) => {
|
|
126
182
|
const { root, options, watch } = resolveHostOptions(rawOptions);
|
|
127
183
|
const state = createHostState();
|
|
184
|
+
const buildId = (0, _animus_ui_extract_session.createBuildId)();
|
|
128
185
|
let activeSession = null;
|
|
129
186
|
let modeOracle = null;
|
|
130
187
|
/** Whether the host is watching, where an error-level diagnostic reports
|
|
@@ -137,6 +194,23 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
137
194
|
/** The bundler's export conditions, in its order, for the system loader;
|
|
138
195
|
* Rollup exposes none. */
|
|
139
196
|
let hostConditions = [];
|
|
197
|
+
/** The bundler's extension order, as its resolved configuration holds
|
|
198
|
+
* it; the built-in policy for a host none is read from (Rolldown). */
|
|
199
|
+
let hostExtensions = _animus_ui_extract_pipeline.BUILT_IN_EXTENSION_POLICY;
|
|
200
|
+
let hostAssets = (0, _animus_ui_extract_pipeline.builtInAssetClassification)("noHost");
|
|
201
|
+
/** How the bundler expands computed loads (spec §6.3); none where its
|
|
202
|
+
* expansion is not reproduced. */
|
|
203
|
+
let hostLoadExpander;
|
|
204
|
+
/** The bundler's own resolution, which package discovery asks first
|
|
205
|
+
* (spec §2.2 A4); none where the host exposes no resolver. */
|
|
206
|
+
let hostResolver = null;
|
|
207
|
+
/** What Rollup and Rolldown named at render, which they name only after
|
|
208
|
+
* analysis: this process's later builds exclude it. */
|
|
209
|
+
let learnedOutputTargets = (0, _animus_ui_extract_pipeline.noOutputTargets)();
|
|
210
|
+
/** Where the bundler writes, which discovery excludes whatever the
|
|
211
|
+
* user's `exclude` list: read when a run starts, after the bundler
|
|
212
|
+
* applied its defaults. */
|
|
213
|
+
let hostOutputTargets = () => learnedOutputTargets;
|
|
140
214
|
/** Hooks can fire before buildStart (webpack's make taps run
|
|
141
215
|
* concurrently), so joiners await this before awaiting the pipeline. */
|
|
142
216
|
let signalPipelineStarted;
|
|
@@ -150,6 +224,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
150
224
|
const unbundledComputedImports = meta.framework === "rollup" || meta.framework === "rolldown" || meta.framework === "esbuild" || meta.framework === "vite";
|
|
151
225
|
async function startPipeline() {
|
|
152
226
|
signalPipelineStarted();
|
|
227
|
+
if (activeSession !== null && (meta.framework === "webpack" || meta.framework === "rspack")) {
|
|
228
|
+
disposeSessionDir(state);
|
|
229
|
+
releaseClaim();
|
|
230
|
+
}
|
|
153
231
|
try {
|
|
154
232
|
await runClaimedPipeline();
|
|
155
233
|
} catch (error) {
|
|
@@ -169,35 +247,75 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
169
247
|
const session = new _animus_ui_extract_session.ExtractionSession({
|
|
170
248
|
...options,
|
|
171
249
|
mode
|
|
172
|
-
}, {
|
|
250
|
+
}, {
|
|
251
|
+
unbundledComputedImports,
|
|
252
|
+
build: buildId
|
|
253
|
+
});
|
|
173
254
|
activeSession = session;
|
|
174
255
|
session.development = watching();
|
|
175
256
|
session.driverLabel = "animus-unplugin";
|
|
176
257
|
session.rootDir = root;
|
|
177
258
|
session.conditions = hostConditions;
|
|
178
|
-
session.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
259
|
+
session.extensionPolicy = hostExtensions;
|
|
260
|
+
session.assetClassification = hostAssets;
|
|
261
|
+
session.loadExpander = hostLoadExpander;
|
|
262
|
+
session.hostResolve = hostResolver;
|
|
263
|
+
session.delivery = {
|
|
264
|
+
...session.delivery,
|
|
265
|
+
systemPropsModuleId: _animus_ui_extract_session.TURBOPACK_SYSTEM_PROPS_ID
|
|
266
|
+
};
|
|
267
|
+
session.structuralExclude = (0, _animus_ui_extract_pipeline.outputExclusions)(root, hostOutputTargets());
|
|
268
|
+
session.aliasesFromTsconfig = true;
|
|
269
|
+
state.key = session.key;
|
|
270
|
+
try {
|
|
271
|
+
await session.runFullPipeline();
|
|
272
|
+
} catch (error) {
|
|
273
|
+
const plan = session.watchPlan();
|
|
274
|
+
state.watchPaths = [...plan.files, ...plan.missing];
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
state.sessionDir = (0, _animus_ui_extract_session.getSessionArtifactDir)(session.key);
|
|
278
|
+
const analyzed = (0, _animus_ui_extract_session.getAnalyzedHashes)(session.key);
|
|
185
279
|
if (!analyzed || analyzed.size === 0) throw new Error(`[animus] discovery found zero source files under ${root} — check the plugin's \`root\` and \`exclude\` options`);
|
|
186
|
-
state.cssText = (0, _animus_ui_extract_session.getSharedCss)();
|
|
187
|
-
state.
|
|
280
|
+
state.cssText = (0, _animus_ui_extract_session.getSharedCss)(session.key);
|
|
281
|
+
state.served = manifestServedFiles((0, _animus_ui_extract_session.getManifestJson)(session.key));
|
|
282
|
+
state.systemPropsJs = (0, _animus_ui_extract_session.getSharedSystemProps)(session.key);
|
|
188
283
|
state.kitRedirects = new Map(session.externalSourceEntries);
|
|
189
284
|
state.kitSideEffects = new Map(session.externalSourceSideEffects);
|
|
190
285
|
state.redirectTargets = new Set(state.kitRedirects.values());
|
|
191
286
|
state.externalPackageDirs = [...session.externalPackageDirs];
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
287
|
+
state.analyzedFiles = [...analyzed.keys()].map((key) => (0, node_path.resolve)(root, key));
|
|
288
|
+
const plan = session.watchPlan();
|
|
289
|
+
state.watchPaths = [.../* @__PURE__ */ new Set([
|
|
290
|
+
...state.analyzedFiles,
|
|
291
|
+
...plan.files,
|
|
292
|
+
...plan.missing
|
|
293
|
+
])];
|
|
294
|
+
state.transformFile = (0, _animus_ui_extract_session.engineApi)(session.key).transformFile;
|
|
199
295
|
});
|
|
200
296
|
}
|
|
297
|
+
/** The Rollup family's environment builds: a Vite buildApp can build
|
|
298
|
+
* environments in parallel on one plugin instance, sharing one pipeline
|
|
299
|
+
* and one Session. webpack-like hosts run one compile at a time and are
|
|
300
|
+
* not tracked. */
|
|
301
|
+
const builds = new _animus_ui_extract_session.EnvironmentBuilds();
|
|
302
|
+
const tracksEnvironments = meta.framework === "rollup" || meta.framework === "rolldown" || meta.framework === "vite";
|
|
303
|
+
function environmentOf(context) {
|
|
304
|
+
return hasEnvironment(context) ? context.environment : builds.single;
|
|
305
|
+
}
|
|
306
|
+
/** Opens this hook's environment build once no build under its name is
|
|
307
|
+
* open; whether another environment's build is open, whose pipeline this
|
|
308
|
+
* build shares. */
|
|
309
|
+
async function openEnvironmentBuild(context) {
|
|
310
|
+
if (!tracksEnvironments) return false;
|
|
311
|
+
return builds.open(environmentOf(context));
|
|
312
|
+
}
|
|
313
|
+
/** Ends this hook's environment build; whether none is left open. Only
|
|
314
|
+
* the build that opened an entry ends it. */
|
|
315
|
+
function closeEnvironmentBuild(context) {
|
|
316
|
+
if (!tracksEnvironments) return true;
|
|
317
|
+
return builds.end(environmentOf(context));
|
|
318
|
+
}
|
|
201
319
|
async function joinPipeline() {
|
|
202
320
|
await pipelineStarted;
|
|
203
321
|
await state.pipeline;
|
|
@@ -236,6 +354,17 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
236
354
|
source: bytes
|
|
237
355
|
});
|
|
238
356
|
}
|
|
357
|
+
/** Rollup and Rolldown name their output only at render, after
|
|
358
|
+
* analysis: this process's later builds exclude it, and an analysis that
|
|
359
|
+
* already read a file there is reported, failing a build under `strict`. */
|
|
360
|
+
function checkOwnOutput(context, output) {
|
|
361
|
+
const targets = (0, _animus_ui_extract_pipeline.rollupOutputTargets)(output);
|
|
362
|
+
learnedOutputTargets = (0, _animus_ui_extract_pipeline.mergeOutputTargets)([learnedOutputTargets, targets]);
|
|
363
|
+
const message = (0, _animus_ui_extract_pipeline.analysedOutputs)(root, targets, state.analyzedFiles);
|
|
364
|
+
if (message === null) return;
|
|
365
|
+
if (options.strict && !watching()) context.error(message);
|
|
366
|
+
context.warn(message);
|
|
367
|
+
}
|
|
239
368
|
/** Analysis is a filesystem walk, so watch mode misses edits to
|
|
240
369
|
* analyzed-but-unimported files. esbuild has no watch-file seam. */
|
|
241
370
|
function registerWatchTargets(context) {
|
|
@@ -248,8 +377,13 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
248
377
|
name: PLUGIN_NAME,
|
|
249
378
|
enforce: "pre",
|
|
250
379
|
async buildStart() {
|
|
251
|
-
|
|
252
|
-
|
|
380
|
+
if (rollupLike) hostResolver = pluginResolver(this);
|
|
381
|
+
try {
|
|
382
|
+
if (await openEnvironmentBuild(this)) await joinPipeline();
|
|
383
|
+
else await startPipeline();
|
|
384
|
+
} finally {
|
|
385
|
+
registerWatchTargets(this);
|
|
386
|
+
}
|
|
253
387
|
},
|
|
254
388
|
async resolveId(id, importer) {
|
|
255
389
|
const virtual = resolveAnimusId(id);
|
|
@@ -309,12 +443,14 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
309
443
|
await joinPipeline();
|
|
310
444
|
const filePath = moduleFilePath(id);
|
|
311
445
|
let output = code;
|
|
312
|
-
|
|
313
|
-
|
|
446
|
+
const key = state.key;
|
|
447
|
+
if (key !== null && (0, _animus_ui_extract_pipeline.isEngineTransformExtension)(filePath)) {
|
|
448
|
+
const transformFile = state.transformFile ?? (0, _animus_ui_extract_session.engineApi)(key).transformFile;
|
|
314
449
|
const transformed = transformWithEngine(output, filePath, {
|
|
315
450
|
rootDir: root,
|
|
316
|
-
manifestJson: (0, _animus_ui_extract_session.getManifestJson)() ?? "",
|
|
317
|
-
transformFile
|
|
451
|
+
manifestJson: (0, _animus_ui_extract_session.getManifestJson)(key) ?? "",
|
|
452
|
+
transformFile,
|
|
453
|
+
served: state.served
|
|
318
454
|
});
|
|
319
455
|
if (transformed !== null) output = transformed;
|
|
320
456
|
}
|
|
@@ -331,18 +467,39 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
331
467
|
try {
|
|
332
468
|
emitCssAsset(this);
|
|
333
469
|
} finally {
|
|
334
|
-
|
|
335
|
-
|
|
470
|
+
if (closeEnvironmentBuild(this)) {
|
|
471
|
+
disposeSessionDir(state);
|
|
472
|
+
releaseClaim();
|
|
473
|
+
}
|
|
336
474
|
}
|
|
337
475
|
},
|
|
338
476
|
vite: { configResolved(config) {
|
|
477
|
+
hostExtensions = (0, _animus_ui_extract_pipeline.viteExtensionPolicy)(config.resolve.extensions);
|
|
478
|
+
hostAssets = (0, _animus_ui_extract_pipeline.viteAssetClassification)(config.assetsInclude);
|
|
479
|
+
hostLoadExpander = (0, _animus_ui_extract_pipeline.viteHostExpander)(config);
|
|
480
|
+
hostOutputTargets = () => (0, _animus_ui_extract_pipeline.viteOutputTargets)(config);
|
|
339
481
|
const serving = config.command === "serve" || Boolean(config.build.watch);
|
|
340
482
|
watching = () => serving;
|
|
341
483
|
} },
|
|
342
|
-
rollup: {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
484
|
+
rollup: {
|
|
485
|
+
async buildStart(inputOptions) {
|
|
486
|
+
hostExtensions = (0, _animus_ui_extract_pipeline.rollupExtensionPolicy)((inputOptions?.plugins ?? []).some((plugin) => plugin?.name === "node-resolve"));
|
|
487
|
+
hostAssets = (0, _animus_ui_extract_pipeline.builtInAssetClassification)("hostOptionUnreadable", "rollup");
|
|
488
|
+
modeOracle = this.meta?.watchMode ? "development" : "production";
|
|
489
|
+
hostResolver = pluginResolver(this);
|
|
490
|
+
try {
|
|
491
|
+
if (await openEnvironmentBuild(this)) await joinPipeline();
|
|
492
|
+
else await startPipeline();
|
|
493
|
+
} finally {
|
|
494
|
+
registerWatchTargets(this);
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
renderStart(outputOptions) {
|
|
498
|
+
checkOwnOutput(this, outputOptions);
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
rolldown: { renderStart(outputOptions) {
|
|
502
|
+
checkOwnOutput(this, outputOptions);
|
|
346
503
|
} },
|
|
347
504
|
webpack(compiler) {
|
|
348
505
|
wireWebpackLike(compiler);
|
|
@@ -396,7 +553,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
396
553
|
},
|
|
397
554
|
config(buildOptions) {
|
|
398
555
|
esbuildOptions = buildOptions;
|
|
556
|
+
hostOutputTargets = () => (0, _animus_ui_extract_pipeline.esbuildOutputTargets)(buildOptions);
|
|
399
557
|
hostConditions = buildOptions.conditions ?? [];
|
|
558
|
+
hostExtensions = (0, _animus_ui_extract_pipeline.esbuildExtensionPolicy)(buildOptions.resolveExtensions);
|
|
559
|
+
hostAssets = (0, _animus_ui_extract_pipeline.esbuildAssetClassification)(buildOptions.loader);
|
|
400
560
|
watching = () => watch;
|
|
401
561
|
buildOptions.define = {
|
|
402
562
|
...buildOptions.define,
|
|
@@ -448,7 +608,30 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
448
608
|
function wireWebpackLike(compiler) {
|
|
449
609
|
modeOracle = compiler.options.mode === "development" ? "development" : "production";
|
|
450
610
|
hostConditions = (compiler.options.resolve?.conditionNames ?? []).filter((name) => name !== "...");
|
|
611
|
+
hostExtensions = (0, _animus_ui_extract_pipeline.webpackExtensionPolicy)(meta.framework, compiler.options.resolve ?? {}, compiler.webpack?.version ?? compiler.rspack?.rspackVersion);
|
|
612
|
+
hostAssets = (0, _animus_ui_extract_pipeline.builtInAssetClassification)("hostOptionUnreadable", `${meta.framework === "rspack" ? "rspack" : "webpack"} rules not modelled`);
|
|
451
613
|
watching = () => compiler.watchMode === true;
|
|
614
|
+
hostOutputTargets = () => (0, _animus_ui_extract_pipeline.webpackOutputTargets)(compiler.options.output?.path);
|
|
615
|
+
const resolverFactory = compiler.resolverFactory;
|
|
616
|
+
hostLoadExpander = meta.framework === "webpack" && resolverFactory !== void 0 ? (0, _animus_ui_extract_pipeline.webpackHostExpander)({
|
|
617
|
+
resolveReading: (category) => {
|
|
618
|
+
const read = resolverFactory.get("normal", { dependencyType: category }).options;
|
|
619
|
+
const context = resolverFactory.get("context", { dependencyType: category }).options;
|
|
620
|
+
return {
|
|
621
|
+
extensions: [...read.extensions],
|
|
622
|
+
mainFiles: [...read.mainFiles],
|
|
623
|
+
modules: read.modules,
|
|
624
|
+
fullySpecified: read.fullySpecified === true,
|
|
625
|
+
enforceExtension: read.enforceExtension === true,
|
|
626
|
+
aliasNames: [read, context].flatMap((resolver) => [...resolver.alias ?? [], ...resolver.fallback ?? []].map((entry) => entry.name))
|
|
627
|
+
};
|
|
628
|
+
},
|
|
629
|
+
options: () => ({
|
|
630
|
+
rules: compiler.options.module?.rules ?? [],
|
|
631
|
+
defaultRulesAreWebpacks: defaultRulesAreWebpacks(compiler),
|
|
632
|
+
wrappedDefaults: wrappedContextDefaults(compiler.options.module?.parser)
|
|
633
|
+
})
|
|
634
|
+
}) : void 0;
|
|
452
635
|
const DefinePlugin = compiler.webpack?.DefinePlugin ?? compiler.rspack?.DefinePlugin;
|
|
453
636
|
if (!DefinePlugin) throw new Error("[animus] compiler exposes no DefinePlugin — cannot supply the __ANIMUS_DEV__ dev-signal define");
|
|
454
637
|
new DefinePlugin({ __ANIMUS_DEV__: JSON.stringify(effectiveMode() === "development") }).apply(compiler);
|
|
@@ -460,6 +643,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
460
643
|
disposeSessionDir(state);
|
|
461
644
|
releaseClaim();
|
|
462
645
|
});
|
|
646
|
+
compiler.hooks.watchClose?.tap(PLUGIN_NAME, () => {
|
|
647
|
+
disposeSessionDir(state);
|
|
648
|
+
releaseClaim();
|
|
649
|
+
});
|
|
463
650
|
}
|
|
464
651
|
};
|
|
465
652
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnimusConfigError, DiagnosticFailure, ENGINE_TRANSFORM_EXTENSIONS, assertKnownOptionKeys,
|
|
2
|
-
import { ANIMUS_CSS_MODULE_ID, ExtractionSession, SESSION_ASSETS_DIR, TURBOPACK_SYSTEM_PROPS_ID, collectSessionAssets, engineApi, getAnalyzedHashes, getManifestJson, getSessionArtifactDir, getSharedCss, getSharedSystemProps } from "@animus-ui/extract/session";
|
|
1
|
+
import { AnimusConfigError, BUILT_IN_EXTENSION_POLICY, DiagnosticFailure, ENGINE_TRANSFORM_EXTENSIONS, analysedOutputs, assertKnownOptionKeys, assertSupportedEngine, builtInAssetClassification, droppedExtensionMessage, esbuildAssetClassification, esbuildExtensionPolicy, esbuildOutputTargets, isEngineTransformExtension, isPathWithinRoot, keepsKitSourceEffects, mergeOutputTargets, noOutputTargets, outputExclusions, resolveMode, rollupExtensionPolicy, rollupOutputTargets, servedFiles, viteAssetClassification, viteExtensionPolicy, viteHostExpander, viteOutputTargets, webpackExtensionPolicy, webpackHostExpander, webpackOutputTargets } from "@animus-ui/extract/pipeline";
|
|
2
|
+
import { ANIMUS_CSS_MODULE_ID, EnvironmentBuilds, ExtractionSession, SESSION_ASSETS_DIR, TURBOPACK_SYSTEM_PROPS_ID, collectSessionAssets, createBuildId, engineApi, getAnalyzedHashes, getManifestJson, getSessionArtifactDir, getSharedCss, getSharedSystemProps } from "@animus-ui/extract/session";
|
|
3
3
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { dirname, join, relative, resolve } from "node:path";
|
|
5
5
|
//#region src/options.ts
|
|
@@ -19,7 +19,7 @@ function hasRequiredSystem(options) {
|
|
|
19
19
|
}
|
|
20
20
|
function resolveHostOptions(raw, cwd = process.cwd()) {
|
|
21
21
|
const options = raw ?? {};
|
|
22
|
-
|
|
22
|
+
assertSupportedEngine(options.engine);
|
|
23
23
|
assertKnownOptionKeys(options, ["watch"]);
|
|
24
24
|
if (!hasRequiredSystem(options)) throw new AnimusConfigError("Missing required option `system` — pass `system: \"./src/ds.ts\"` to the Animus plugin.");
|
|
25
25
|
const root = options.root ? resolve(cwd, options.root) : cwd;
|
|
@@ -52,6 +52,11 @@ function createHostState() {
|
|
|
52
52
|
pipeline: null,
|
|
53
53
|
mode: null,
|
|
54
54
|
cssText: "",
|
|
55
|
+
served: {
|
|
56
|
+
listed: /* @__PURE__ */ new Set(),
|
|
57
|
+
dropped: /* @__PURE__ */ new Map()
|
|
58
|
+
},
|
|
59
|
+
analyzedFiles: [],
|
|
55
60
|
systemPropsJs: "",
|
|
56
61
|
kitRedirects: /* @__PURE__ */ new Map(),
|
|
57
62
|
kitSideEffects: /* @__PURE__ */ new Map(),
|
|
@@ -59,7 +64,8 @@ function createHostState() {
|
|
|
59
64
|
externalPackageDirs: [],
|
|
60
65
|
watchPaths: [],
|
|
61
66
|
transformFile: null,
|
|
62
|
-
sessionDir: null
|
|
67
|
+
sessionDir: null,
|
|
68
|
+
key: null
|
|
63
69
|
};
|
|
64
70
|
}
|
|
65
71
|
function shouldClaimTransform(filePath, state) {
|
|
@@ -81,7 +87,7 @@ async function drivePipeline(state, run, removeDir) {
|
|
|
81
87
|
try {
|
|
82
88
|
await attempt;
|
|
83
89
|
} catch (error) {
|
|
84
|
-
if (!state.sessionDir) state.sessionDir = getSessionArtifactDir();
|
|
90
|
+
if (!state.sessionDir && state.key !== null) state.sessionDir = getSessionArtifactDir(state.key);
|
|
85
91
|
disposeSessionDir(state, removeDir);
|
|
86
92
|
throw error;
|
|
87
93
|
}
|
|
@@ -98,8 +104,20 @@ function substituteDevDefine(code, isDev) {
|
|
|
98
104
|
}
|
|
99
105
|
function transformWithEngine(code, id, ctx) {
|
|
100
106
|
const filename = relative(ctx.rootDir, resolve(id)).split("\\").join("/");
|
|
107
|
+
const drop = ctx.served?.dropped.get(filename);
|
|
108
|
+
if (drop !== void 0) throw new Error(droppedExtensionMessage(drop));
|
|
101
109
|
const result = ctx.transformFile(code, filename, ctx.manifestJson);
|
|
102
|
-
|
|
110
|
+
if (result.hasComponents) return result.code;
|
|
111
|
+
if (ctx.served?.listed.has(filename)) throw new Error(`[animus] the analysis extracted components from ${filename}, but its transform found none`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/** What a manifest's transform serves, parsed once per run. */
|
|
115
|
+
function manifestServedFiles(manifestJson) {
|
|
116
|
+
if (manifestJson === null) return {
|
|
117
|
+
listed: /* @__PURE__ */ new Set(),
|
|
118
|
+
dropped: /* @__PURE__ */ new Map()
|
|
119
|
+
};
|
|
120
|
+
return servedFiles(JSON.parse(manifestJson));
|
|
103
121
|
}
|
|
104
122
|
/** Whether esbuild's `external` option names `specifier`: exactly, as the
|
|
105
123
|
* package a subpath belongs to, or through a `*` wildcard. */
|
|
@@ -118,13 +136,52 @@ function moduleFilePath(id) {
|
|
|
118
136
|
function canResolve(context) {
|
|
119
137
|
return "resolve" in context;
|
|
120
138
|
}
|
|
139
|
+
/** Whether a hook context names the environment it builds (Vite). */
|
|
140
|
+
function hasEnvironment(context) {
|
|
141
|
+
return "environment" in context;
|
|
142
|
+
}
|
|
121
143
|
/** Marks the esbuild resolve that `esbuild.setup` makes for itself. */
|
|
122
144
|
const KIT_SOURCE_RESOLVE = "animus:kit-source-resolve";
|
|
145
|
+
/** Rules as comparable text: a RegExp by its source and flags, a function
|
|
146
|
+
* by its text. */
|
|
147
|
+
function ruleText(rules) {
|
|
148
|
+
return JSON.stringify(rules ?? null, (_key, value) => value instanceof RegExp ? `/${value.source}/${value.flags}` : value instanceof Function ? String(value) : value);
|
|
149
|
+
}
|
|
150
|
+
/** Whether `module.defaultRules` is webpack's own default list: the list
|
|
151
|
+
* webpack's defaults give the compiler's experiments, unchanged. Throws
|
|
152
|
+
* where webpack's option API is not available. */
|
|
153
|
+
function defaultRulesAreWebpacks(compiler) {
|
|
154
|
+
const config = compiler.webpack?.config;
|
|
155
|
+
if (config === void 0) throw new Error("webpack's option defaults are not available");
|
|
156
|
+
const { css, asyncWebAssembly, syncWebAssembly } = compiler.options.experiments ?? {};
|
|
157
|
+
const fresh = config.getNormalizedWebpackOptions({ experiments: {
|
|
158
|
+
css,
|
|
159
|
+
asyncWebAssembly,
|
|
160
|
+
syncWebAssembly
|
|
161
|
+
} });
|
|
162
|
+
config.applyWebpackOptionsDefaults(fresh);
|
|
163
|
+
return ruleText(fresh.module?.defaultRules) === ruleText(compiler.options.module?.defaultRules);
|
|
164
|
+
}
|
|
165
|
+
/** Whether every webpack JavaScript parser keeps the default wrapped
|
|
166
|
+
* context, `/.*\/` and recursive. */
|
|
167
|
+
function wrappedContextDefaults(parser) {
|
|
168
|
+
return Object.entries(parser ?? {}).filter(([type]) => type === "javascript" || type.startsWith("javascript/")).every(([, options]) => (options?.wrappedContextRegExp === void 0 || options.wrappedContextRegExp.source === ".*" && options.wrappedContextRegExp.flags === "") && options?.wrappedContextRecursive !== false);
|
|
169
|
+
}
|
|
170
|
+
function hasPluginResolve(context) {
|
|
171
|
+
return "resolve" in context;
|
|
172
|
+
}
|
|
173
|
+
/** The bundler's resolution through a Rollup-family plugin context (Rollup,
|
|
174
|
+
* Rolldown, Vite); none where the context cannot resolve. */
|
|
175
|
+
function pluginResolver(context) {
|
|
176
|
+
if (!hasPluginResolve(context)) return null;
|
|
177
|
+
return async (specifier, importer) => (await context.resolve(specifier, importer, { skipSelf: true }))?.id ?? null;
|
|
178
|
+
}
|
|
123
179
|
const PLUGIN_NAME = "animus-host";
|
|
124
180
|
const ESBUILD_WATCH_HINT = "If this is an esbuild watch or serve context, pass watch: true to the Animus esbuild plugin.";
|
|
125
181
|
const unpluginFactory = (rawOptions, meta) => {
|
|
126
182
|
const { root, options, watch } = resolveHostOptions(rawOptions);
|
|
127
183
|
const state = createHostState();
|
|
184
|
+
const buildId = createBuildId();
|
|
128
185
|
let activeSession = null;
|
|
129
186
|
let modeOracle = null;
|
|
130
187
|
/** Whether the host is watching, where an error-level diagnostic reports
|
|
@@ -137,6 +194,23 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
137
194
|
/** The bundler's export conditions, in its order, for the system loader;
|
|
138
195
|
* Rollup exposes none. */
|
|
139
196
|
let hostConditions = [];
|
|
197
|
+
/** The bundler's extension order, as its resolved configuration holds
|
|
198
|
+
* it; the built-in policy for a host none is read from (Rolldown). */
|
|
199
|
+
let hostExtensions = BUILT_IN_EXTENSION_POLICY;
|
|
200
|
+
let hostAssets = builtInAssetClassification("noHost");
|
|
201
|
+
/** How the bundler expands computed loads (spec §6.3); none where its
|
|
202
|
+
* expansion is not reproduced. */
|
|
203
|
+
let hostLoadExpander;
|
|
204
|
+
/** The bundler's own resolution, which package discovery asks first
|
|
205
|
+
* (spec §2.2 A4); none where the host exposes no resolver. */
|
|
206
|
+
let hostResolver = null;
|
|
207
|
+
/** What Rollup and Rolldown named at render, which they name only after
|
|
208
|
+
* analysis: this process's later builds exclude it. */
|
|
209
|
+
let learnedOutputTargets = noOutputTargets();
|
|
210
|
+
/** Where the bundler writes, which discovery excludes whatever the
|
|
211
|
+
* user's `exclude` list: read when a run starts, after the bundler
|
|
212
|
+
* applied its defaults. */
|
|
213
|
+
let hostOutputTargets = () => learnedOutputTargets;
|
|
140
214
|
/** Hooks can fire before buildStart (webpack's make taps run
|
|
141
215
|
* concurrently), so joiners await this before awaiting the pipeline. */
|
|
142
216
|
let signalPipelineStarted;
|
|
@@ -150,6 +224,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
150
224
|
const unbundledComputedImports = meta.framework === "rollup" || meta.framework === "rolldown" || meta.framework === "esbuild" || meta.framework === "vite";
|
|
151
225
|
async function startPipeline() {
|
|
152
226
|
signalPipelineStarted();
|
|
227
|
+
if (activeSession !== null && (meta.framework === "webpack" || meta.framework === "rspack")) {
|
|
228
|
+
disposeSessionDir(state);
|
|
229
|
+
releaseClaim();
|
|
230
|
+
}
|
|
153
231
|
try {
|
|
154
232
|
await runClaimedPipeline();
|
|
155
233
|
} catch (error) {
|
|
@@ -169,35 +247,75 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
169
247
|
const session = new ExtractionSession({
|
|
170
248
|
...options,
|
|
171
249
|
mode
|
|
172
|
-
}, {
|
|
250
|
+
}, {
|
|
251
|
+
unbundledComputedImports,
|
|
252
|
+
build: buildId
|
|
253
|
+
});
|
|
173
254
|
activeSession = session;
|
|
174
255
|
session.development = watching();
|
|
175
256
|
session.driverLabel = "animus-unplugin";
|
|
176
257
|
session.rootDir = root;
|
|
177
258
|
session.conditions = hostConditions;
|
|
178
|
-
session.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
259
|
+
session.extensionPolicy = hostExtensions;
|
|
260
|
+
session.assetClassification = hostAssets;
|
|
261
|
+
session.loadExpander = hostLoadExpander;
|
|
262
|
+
session.hostResolve = hostResolver;
|
|
263
|
+
session.delivery = {
|
|
264
|
+
...session.delivery,
|
|
265
|
+
systemPropsModuleId: TURBOPACK_SYSTEM_PROPS_ID
|
|
266
|
+
};
|
|
267
|
+
session.structuralExclude = outputExclusions(root, hostOutputTargets());
|
|
268
|
+
session.aliasesFromTsconfig = true;
|
|
269
|
+
state.key = session.key;
|
|
270
|
+
try {
|
|
271
|
+
await session.runFullPipeline();
|
|
272
|
+
} catch (error) {
|
|
273
|
+
const plan = session.watchPlan();
|
|
274
|
+
state.watchPaths = [...plan.files, ...plan.missing];
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
state.sessionDir = getSessionArtifactDir(session.key);
|
|
278
|
+
const analyzed = getAnalyzedHashes(session.key);
|
|
185
279
|
if (!analyzed || analyzed.size === 0) throw new Error(`[animus] discovery found zero source files under ${root} — check the plugin's \`root\` and \`exclude\` options`);
|
|
186
|
-
state.cssText = getSharedCss();
|
|
187
|
-
state.
|
|
280
|
+
state.cssText = getSharedCss(session.key);
|
|
281
|
+
state.served = manifestServedFiles(getManifestJson(session.key));
|
|
282
|
+
state.systemPropsJs = getSharedSystemProps(session.key);
|
|
188
283
|
state.kitRedirects = new Map(session.externalSourceEntries);
|
|
189
284
|
state.kitSideEffects = new Map(session.externalSourceSideEffects);
|
|
190
285
|
state.redirectTargets = new Set(state.kitRedirects.values());
|
|
191
286
|
state.externalPackageDirs = [...session.externalPackageDirs];
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
287
|
+
state.analyzedFiles = [...analyzed.keys()].map((key) => resolve(root, key));
|
|
288
|
+
const plan = session.watchPlan();
|
|
289
|
+
state.watchPaths = [.../* @__PURE__ */ new Set([
|
|
290
|
+
...state.analyzedFiles,
|
|
291
|
+
...plan.files,
|
|
292
|
+
...plan.missing
|
|
293
|
+
])];
|
|
294
|
+
state.transformFile = engineApi(session.key).transformFile;
|
|
199
295
|
});
|
|
200
296
|
}
|
|
297
|
+
/** The Rollup family's environment builds: a Vite buildApp can build
|
|
298
|
+
* environments in parallel on one plugin instance, sharing one pipeline
|
|
299
|
+
* and one Session. webpack-like hosts run one compile at a time and are
|
|
300
|
+
* not tracked. */
|
|
301
|
+
const builds = new EnvironmentBuilds();
|
|
302
|
+
const tracksEnvironments = meta.framework === "rollup" || meta.framework === "rolldown" || meta.framework === "vite";
|
|
303
|
+
function environmentOf(context) {
|
|
304
|
+
return hasEnvironment(context) ? context.environment : builds.single;
|
|
305
|
+
}
|
|
306
|
+
/** Opens this hook's environment build once no build under its name is
|
|
307
|
+
* open; whether another environment's build is open, whose pipeline this
|
|
308
|
+
* build shares. */
|
|
309
|
+
async function openEnvironmentBuild(context) {
|
|
310
|
+
if (!tracksEnvironments) return false;
|
|
311
|
+
return builds.open(environmentOf(context));
|
|
312
|
+
}
|
|
313
|
+
/** Ends this hook's environment build; whether none is left open. Only
|
|
314
|
+
* the build that opened an entry ends it. */
|
|
315
|
+
function closeEnvironmentBuild(context) {
|
|
316
|
+
if (!tracksEnvironments) return true;
|
|
317
|
+
return builds.end(environmentOf(context));
|
|
318
|
+
}
|
|
201
319
|
async function joinPipeline() {
|
|
202
320
|
await pipelineStarted;
|
|
203
321
|
await state.pipeline;
|
|
@@ -236,6 +354,17 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
236
354
|
source: bytes
|
|
237
355
|
});
|
|
238
356
|
}
|
|
357
|
+
/** Rollup and Rolldown name their output only at render, after
|
|
358
|
+
* analysis: this process's later builds exclude it, and an analysis that
|
|
359
|
+
* already read a file there is reported, failing a build under `strict`. */
|
|
360
|
+
function checkOwnOutput(context, output) {
|
|
361
|
+
const targets = rollupOutputTargets(output);
|
|
362
|
+
learnedOutputTargets = mergeOutputTargets([learnedOutputTargets, targets]);
|
|
363
|
+
const message = analysedOutputs(root, targets, state.analyzedFiles);
|
|
364
|
+
if (message === null) return;
|
|
365
|
+
if (options.strict && !watching()) context.error(message);
|
|
366
|
+
context.warn(message);
|
|
367
|
+
}
|
|
239
368
|
/** Analysis is a filesystem walk, so watch mode misses edits to
|
|
240
369
|
* analyzed-but-unimported files. esbuild has no watch-file seam. */
|
|
241
370
|
function registerWatchTargets(context) {
|
|
@@ -248,8 +377,13 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
248
377
|
name: PLUGIN_NAME,
|
|
249
378
|
enforce: "pre",
|
|
250
379
|
async buildStart() {
|
|
251
|
-
|
|
252
|
-
|
|
380
|
+
if (rollupLike) hostResolver = pluginResolver(this);
|
|
381
|
+
try {
|
|
382
|
+
if (await openEnvironmentBuild(this)) await joinPipeline();
|
|
383
|
+
else await startPipeline();
|
|
384
|
+
} finally {
|
|
385
|
+
registerWatchTargets(this);
|
|
386
|
+
}
|
|
253
387
|
},
|
|
254
388
|
async resolveId(id, importer) {
|
|
255
389
|
const virtual = resolveAnimusId(id);
|
|
@@ -309,12 +443,14 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
309
443
|
await joinPipeline();
|
|
310
444
|
const filePath = moduleFilePath(id);
|
|
311
445
|
let output = code;
|
|
312
|
-
|
|
313
|
-
|
|
446
|
+
const key = state.key;
|
|
447
|
+
if (key !== null && isEngineTransformExtension(filePath)) {
|
|
448
|
+
const transformFile = state.transformFile ?? engineApi(key).transformFile;
|
|
314
449
|
const transformed = transformWithEngine(output, filePath, {
|
|
315
450
|
rootDir: root,
|
|
316
|
-
manifestJson: getManifestJson() ?? "",
|
|
317
|
-
transformFile
|
|
451
|
+
manifestJson: getManifestJson(key) ?? "",
|
|
452
|
+
transformFile,
|
|
453
|
+
served: state.served
|
|
318
454
|
});
|
|
319
455
|
if (transformed !== null) output = transformed;
|
|
320
456
|
}
|
|
@@ -331,18 +467,39 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
331
467
|
try {
|
|
332
468
|
emitCssAsset(this);
|
|
333
469
|
} finally {
|
|
334
|
-
|
|
335
|
-
|
|
470
|
+
if (closeEnvironmentBuild(this)) {
|
|
471
|
+
disposeSessionDir(state);
|
|
472
|
+
releaseClaim();
|
|
473
|
+
}
|
|
336
474
|
}
|
|
337
475
|
},
|
|
338
476
|
vite: { configResolved(config) {
|
|
477
|
+
hostExtensions = viteExtensionPolicy(config.resolve.extensions);
|
|
478
|
+
hostAssets = viteAssetClassification(config.assetsInclude);
|
|
479
|
+
hostLoadExpander = viteHostExpander(config);
|
|
480
|
+
hostOutputTargets = () => viteOutputTargets(config);
|
|
339
481
|
const serving = config.command === "serve" || Boolean(config.build.watch);
|
|
340
482
|
watching = () => serving;
|
|
341
483
|
} },
|
|
342
|
-
rollup: {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
484
|
+
rollup: {
|
|
485
|
+
async buildStart(inputOptions) {
|
|
486
|
+
hostExtensions = rollupExtensionPolicy((inputOptions?.plugins ?? []).some((plugin) => plugin?.name === "node-resolve"));
|
|
487
|
+
hostAssets = builtInAssetClassification("hostOptionUnreadable", "rollup");
|
|
488
|
+
modeOracle = this.meta?.watchMode ? "development" : "production";
|
|
489
|
+
hostResolver = pluginResolver(this);
|
|
490
|
+
try {
|
|
491
|
+
if (await openEnvironmentBuild(this)) await joinPipeline();
|
|
492
|
+
else await startPipeline();
|
|
493
|
+
} finally {
|
|
494
|
+
registerWatchTargets(this);
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
renderStart(outputOptions) {
|
|
498
|
+
checkOwnOutput(this, outputOptions);
|
|
499
|
+
}
|
|
500
|
+
},
|
|
501
|
+
rolldown: { renderStart(outputOptions) {
|
|
502
|
+
checkOwnOutput(this, outputOptions);
|
|
346
503
|
} },
|
|
347
504
|
webpack(compiler) {
|
|
348
505
|
wireWebpackLike(compiler);
|
|
@@ -396,7 +553,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
396
553
|
},
|
|
397
554
|
config(buildOptions) {
|
|
398
555
|
esbuildOptions = buildOptions;
|
|
556
|
+
hostOutputTargets = () => esbuildOutputTargets(buildOptions);
|
|
399
557
|
hostConditions = buildOptions.conditions ?? [];
|
|
558
|
+
hostExtensions = esbuildExtensionPolicy(buildOptions.resolveExtensions);
|
|
559
|
+
hostAssets = esbuildAssetClassification(buildOptions.loader);
|
|
400
560
|
watching = () => watch;
|
|
401
561
|
buildOptions.define = {
|
|
402
562
|
...buildOptions.define,
|
|
@@ -448,7 +608,30 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
448
608
|
function wireWebpackLike(compiler) {
|
|
449
609
|
modeOracle = compiler.options.mode === "development" ? "development" : "production";
|
|
450
610
|
hostConditions = (compiler.options.resolve?.conditionNames ?? []).filter((name) => name !== "...");
|
|
611
|
+
hostExtensions = webpackExtensionPolicy(meta.framework, compiler.options.resolve ?? {}, compiler.webpack?.version ?? compiler.rspack?.rspackVersion);
|
|
612
|
+
hostAssets = builtInAssetClassification("hostOptionUnreadable", `${meta.framework === "rspack" ? "rspack" : "webpack"} rules not modelled`);
|
|
451
613
|
watching = () => compiler.watchMode === true;
|
|
614
|
+
hostOutputTargets = () => webpackOutputTargets(compiler.options.output?.path);
|
|
615
|
+
const resolverFactory = compiler.resolverFactory;
|
|
616
|
+
hostLoadExpander = meta.framework === "webpack" && resolverFactory !== void 0 ? webpackHostExpander({
|
|
617
|
+
resolveReading: (category) => {
|
|
618
|
+
const read = resolverFactory.get("normal", { dependencyType: category }).options;
|
|
619
|
+
const context = resolverFactory.get("context", { dependencyType: category }).options;
|
|
620
|
+
return {
|
|
621
|
+
extensions: [...read.extensions],
|
|
622
|
+
mainFiles: [...read.mainFiles],
|
|
623
|
+
modules: read.modules,
|
|
624
|
+
fullySpecified: read.fullySpecified === true,
|
|
625
|
+
enforceExtension: read.enforceExtension === true,
|
|
626
|
+
aliasNames: [read, context].flatMap((resolver) => [...resolver.alias ?? [], ...resolver.fallback ?? []].map((entry) => entry.name))
|
|
627
|
+
};
|
|
628
|
+
},
|
|
629
|
+
options: () => ({
|
|
630
|
+
rules: compiler.options.module?.rules ?? [],
|
|
631
|
+
defaultRulesAreWebpacks: defaultRulesAreWebpacks(compiler),
|
|
632
|
+
wrappedDefaults: wrappedContextDefaults(compiler.options.module?.parser)
|
|
633
|
+
})
|
|
634
|
+
}) : void 0;
|
|
452
635
|
const DefinePlugin = compiler.webpack?.DefinePlugin ?? compiler.rspack?.DefinePlugin;
|
|
453
636
|
if (!DefinePlugin) throw new Error("[animus] compiler exposes no DefinePlugin — cannot supply the __ANIMUS_DEV__ dev-signal define");
|
|
454
637
|
new DefinePlugin({ __ANIMUS_DEV__: JSON.stringify(effectiveMode() === "development") }).apply(compiler);
|
|
@@ -460,6 +643,10 @@ const unpluginFactory = (rawOptions, meta) => {
|
|
|
460
643
|
disposeSessionDir(state);
|
|
461
644
|
releaseClaim();
|
|
462
645
|
});
|
|
646
|
+
compiler.hooks.watchClose?.tap(PLUGIN_NAME, () => {
|
|
647
|
+
disposeSessionDir(state);
|
|
648
|
+
releaseClaim();
|
|
649
|
+
});
|
|
463
650
|
}
|
|
464
651
|
};
|
|
465
652
|
//#endregion
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AnimusUnpluginOptions } from './options';
|
|
2
|
-
import type { AnimusMode } from '@animus-ui/extract/pipeline';
|
|
2
|
+
import type { AnimusMode, ServedFiles } from '@animus-ui/extract/pipeline';
|
|
3
|
+
import type { SessionKey } from '@animus-ui/extract/session';
|
|
3
4
|
import type { UnpluginFactory } from 'unplugin';
|
|
4
5
|
/** Extension-free: esbuild picks loaders by extension. No `\0` prefix:
|
|
5
6
|
* webpack's virtual-module bridge requires plain ids. */
|
|
@@ -23,6 +24,14 @@ export interface HostState {
|
|
|
23
24
|
hasComponents: boolean;
|
|
24
25
|
}) | null;
|
|
25
26
|
sessionDir: string | null;
|
|
27
|
+
/** The build of the root this plugin instance analyses, once a pipeline
|
|
28
|
+
* run's session joined it. */
|
|
29
|
+
key: SessionKey | null;
|
|
30
|
+
/** The files the run's analysis extracted components from, and the
|
|
31
|
+
* extensions it dropped over their parent. */
|
|
32
|
+
served: ServedFiles;
|
|
33
|
+
/** Every file the run's analysis read, absolute. */
|
|
34
|
+
analyzedFiles: string[];
|
|
26
35
|
}
|
|
27
36
|
export declare function createHostState(): HostState;
|
|
28
37
|
export declare function shouldClaimTransform(filePath: string, state: Pick<HostState, 'externalPackageDirs' | 'redirectTargets'>): boolean;
|
|
@@ -37,6 +46,9 @@ export declare function transformWithEngine(code: string, id: string, ctx: {
|
|
|
37
46
|
code: string;
|
|
38
47
|
hasComponents: boolean;
|
|
39
48
|
};
|
|
49
|
+
/** The root-relative files the analysis extracted components from,
|
|
50
|
+
* which must transform, and those it dropped over their parent. */
|
|
51
|
+
served?: ServedFiles;
|
|
40
52
|
}): string | null;
|
|
41
53
|
export declare const unpluginFactory: UnpluginFactory<AnimusUnpluginOptions | undefined>;
|
|
42
54
|
//# sourceMappingURL=core.d.ts.map
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,KAAK,EACV,UAAU,EAQV,WAAW,EACZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAEV,UAAU,EACX,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAIV,eAAe,EAChB,MAAM,UAAU,CAAC;AAElB;0DAC0D;AAC1D,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAQtD,eAAO,MAAM,cAAc,eAAe,CAAC;AAQ3C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;wCACoC;IACpC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EACT,CAAC,CACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,KACjB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,CAAC,GAC9C,IAAI,CAAC;IACT,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;mCAC+B;IAC/B,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACvB;mDAC+C;IAC/C,MAAM,EAAE,WAAW,CAAC;IACpB,oDAAoD;IACpD,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,eAAe,IAAI,SAAS,CAiB3C;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,qBAAqB,GAAG,iBAAiB,CAAC,GAChE,OAAO,CAMT;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,EAChB,SAAS,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IACmB,GAC9C,IAAI,CAKN;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACxB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC,CAYf;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASzD;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,MAAM,GAAG,IAAI,CAGf;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,GAAG,EAAE;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,CACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,KACjB;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,CAAC;IAC9C;wEACoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GACA,MAAM,GAAG,IAAI,CAgBf;AAwSD,eAAO,MAAM,eAAe,EAAE,eAAe,CAC3C,qBAAqB,GAAG,SAAS,CA8tBlC,CAAC"}
|
package/dist/esbuild.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_core = require("./core-
|
|
5
|
+
const require_core = require("./core-B-uObifz.cjs");
|
|
6
6
|
//#region src/esbuild.ts
|
|
7
7
|
const animusEsbuild = (0, require("unplugin").createEsbuildPlugin)(require_core.unpluginFactory);
|
|
8
8
|
//#endregion
|
package/dist/esbuild.mjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_core = require("./core-
|
|
5
|
+
const require_core = require("./core-B-uObifz.cjs");
|
|
6
6
|
//#region src/index.ts
|
|
7
7
|
const animusUnplugin = (0, require("unplugin").createUnplugin)(require_core.unpluginFactory);
|
|
8
8
|
//#endregion
|
package/dist/index.mjs
CHANGED
package/dist/rollup.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_core = require("./core-
|
|
5
|
+
const require_core = require("./core-B-uObifz.cjs");
|
|
6
6
|
//#region src/rollup.ts
|
|
7
7
|
const animusRollup = (0, require("unplugin").createRollupPlugin)(require_core.unpluginFactory);
|
|
8
8
|
//#endregion
|
package/dist/rollup.mjs
CHANGED
package/dist/rspack.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_core = require("./core-
|
|
5
|
+
const require_core = require("./core-B-uObifz.cjs");
|
|
6
6
|
//#region src/rspack.ts
|
|
7
7
|
const animusRspack = (0, require("unplugin").createRspackPlugin)(require_core.unpluginFactory);
|
|
8
8
|
//#endregion
|
package/dist/rspack.mjs
CHANGED
package/dist/webpack.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_core = require("./core-
|
|
5
|
+
const require_core = require("./core-B-uObifz.cjs");
|
|
6
6
|
//#region src/webpack.ts
|
|
7
7
|
const animusWebpack = (0, require("unplugin").createWebpackPlugin)(require_core.unpluginFactory);
|
|
8
8
|
//#endregion
|
package/dist/webpack.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animus-ui/unplugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "Animus transform host for non-plugin bundlers — unplugin-based rollup/esbuild/rspack/webpack entry points over the one extraction session",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"animus",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"compile": "tsc --noEmit"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@animus-ui/extract": "0.1.
|
|
60
|
+
"@animus-ui/extract": "0.1.27",
|
|
61
61
|
"unplugin": "^3.3.0"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|