@b9g/shovel 0.2.0-beta.10 → 0.2.0-beta.11
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/CHANGELOG.md +160 -0
- package/README.md +301 -42
- package/bin/cli.js +29 -9
- package/bin/create.js +22 -22
- package/package.json +21 -13
- package/{activate-5LWUTBLL.js → src/_chunks/activate-TP6RQP47.js} +14 -11
- package/src/_chunks/build-V3IPZGKC.js +434 -0
- package/src/_chunks/chunk-ADR5RW57.js +78 -0
- package/src/_chunks/chunk-GRAFMTEH.js +1150 -0
- package/src/_chunks/chunk-JJFM7PO2.js +468 -0
- package/src/_chunks/develop-A7EU2ZDY.js +404 -0
- package/{info-PRYEMZS4.js → src/_chunks/info-TDUY3FZN.js} +1 -1
- package/build-NDUV2F2Z.js +0 -386
- package/chunk-CSH7M4MK.js +0 -861
- package/chunk-ILQUUH2L.js +0 -164
- package/develop-5ORIPB7M.js +0 -264
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
// src/plugins/assets.ts
|
|
2
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import { join, basename, extname, relative, dirname } from "path";
|
|
5
|
+
import mime from "mime";
|
|
6
|
+
import * as ESBuild from "esbuild";
|
|
7
|
+
import { getLogger } from "@logtape/logtape";
|
|
8
|
+
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
|
|
9
|
+
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
|
|
10
|
+
var TRANSPILABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
11
|
+
".ts",
|
|
12
|
+
".tsx",
|
|
13
|
+
".jsx",
|
|
14
|
+
".mts",
|
|
15
|
+
".cts"
|
|
16
|
+
]);
|
|
17
|
+
var CSS_EXTENSIONS = /* @__PURE__ */ new Set([".css"]);
|
|
18
|
+
var logger = getLogger(["shovel"]);
|
|
19
|
+
var DEFAULT_CONFIG = {
|
|
20
|
+
outDir: "dist",
|
|
21
|
+
clientBuild: {}
|
|
22
|
+
};
|
|
23
|
+
var HASH_LENGTH = 16;
|
|
24
|
+
function mergeConfig(userConfig = {}) {
|
|
25
|
+
return {
|
|
26
|
+
...DEFAULT_CONFIG,
|
|
27
|
+
...userConfig
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function normalizePath(basePath) {
|
|
31
|
+
if (!basePath.startsWith("/")) {
|
|
32
|
+
basePath = "/" + basePath;
|
|
33
|
+
}
|
|
34
|
+
if (!basePath.endsWith("/")) {
|
|
35
|
+
basePath = basePath + "/";
|
|
36
|
+
}
|
|
37
|
+
return basePath;
|
|
38
|
+
}
|
|
39
|
+
function assetsPlugin(options = {}) {
|
|
40
|
+
const config = mergeConfig(options);
|
|
41
|
+
const manifest = {
|
|
42
|
+
assets: {},
|
|
43
|
+
generated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44
|
+
config: {
|
|
45
|
+
outDir: config.outDir
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const contexts = /* @__PURE__ */ new Map();
|
|
49
|
+
return {
|
|
50
|
+
name: "shovel-assets",
|
|
51
|
+
setup(build) {
|
|
52
|
+
build.onResolve({ filter: /.*/ }, (_args) => {
|
|
53
|
+
return null;
|
|
54
|
+
});
|
|
55
|
+
async function getContext(absPath, buildOptions) {
|
|
56
|
+
let ctx = contexts.get(absPath);
|
|
57
|
+
if (!ctx) {
|
|
58
|
+
ctx = await ESBuild.context(buildOptions);
|
|
59
|
+
contexts.set(absPath, ctx);
|
|
60
|
+
}
|
|
61
|
+
return ctx;
|
|
62
|
+
}
|
|
63
|
+
build.onLoad({ filter: /.*/ }, async (args) => {
|
|
64
|
+
if (!args.with?.assetBase || typeof args.with.assetBase !== "string") {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const ext = extname(args.path);
|
|
69
|
+
const name = basename(args.path, ext);
|
|
70
|
+
const wantsCSS = args.with.type === "css";
|
|
71
|
+
const needsTranspilation = TRANSPILABLE_EXTENSIONS.has(ext);
|
|
72
|
+
const needsCSSBundling = CSS_EXTENSIONS.has(ext);
|
|
73
|
+
if (wantsCSS && !needsTranspilation) {
|
|
74
|
+
return {
|
|
75
|
+
errors: [
|
|
76
|
+
{
|
|
77
|
+
text: `type: "css" can only be used with transpilable files (.ts, .tsx, .jsx, etc.), not ${ext}`
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
let content;
|
|
83
|
+
let outputExt = ext;
|
|
84
|
+
let mimeType;
|
|
85
|
+
if (needsTranspilation) {
|
|
86
|
+
const clientOpts = config.clientBuild;
|
|
87
|
+
const defaultPlugins = [
|
|
88
|
+
NodeModulesPolyfillPlugin(),
|
|
89
|
+
NodeGlobalsPolyfillPlugin({
|
|
90
|
+
process: true,
|
|
91
|
+
buffer: true
|
|
92
|
+
})
|
|
93
|
+
];
|
|
94
|
+
const plugins = clientOpts.plugins ? [...clientOpts.plugins, ...defaultPlugins] : defaultPlugins;
|
|
95
|
+
const ctx = await getContext(args.path, {
|
|
96
|
+
entryPoints: [args.path],
|
|
97
|
+
bundle: true,
|
|
98
|
+
format: "esm",
|
|
99
|
+
target: "es2022",
|
|
100
|
+
platform: "browser",
|
|
101
|
+
write: false,
|
|
102
|
+
minify: true,
|
|
103
|
+
// outdir is required for esbuild to know where to put extracted CSS
|
|
104
|
+
outdir: config.outDir,
|
|
105
|
+
// Apply polyfills and user-provided client build options
|
|
106
|
+
plugins,
|
|
107
|
+
define: clientOpts.define,
|
|
108
|
+
inject: clientOpts.inject,
|
|
109
|
+
external: clientOpts.external,
|
|
110
|
+
alias: clientOpts.alias,
|
|
111
|
+
// Apply JSX configuration (defaults to @b9g/crank automatic runtime)
|
|
112
|
+
jsx: clientOpts.jsx ?? "automatic",
|
|
113
|
+
jsxFactory: clientOpts.jsxFactory,
|
|
114
|
+
jsxFragment: clientOpts.jsxFragment,
|
|
115
|
+
jsxImportSource: clientOpts.jsxImportSource ?? "@b9g/crank"
|
|
116
|
+
});
|
|
117
|
+
const result = await ctx.rebuild();
|
|
118
|
+
if (!result.outputFiles) {
|
|
119
|
+
return {
|
|
120
|
+
errors: [{ text: `No output files generated for ${args.path}` }]
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (wantsCSS) {
|
|
124
|
+
const cssOutput = result.outputFiles.find(
|
|
125
|
+
(f) => f.path.endsWith(".css")
|
|
126
|
+
);
|
|
127
|
+
if (!cssOutput) {
|
|
128
|
+
return {
|
|
129
|
+
errors: [
|
|
130
|
+
{
|
|
131
|
+
text: `No CSS was extracted from ${args.path}. The file must import CSS for type: "css" to work.`
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
content = Buffer.from(cssOutput.text);
|
|
137
|
+
outputExt = ".css";
|
|
138
|
+
mimeType = "text/css";
|
|
139
|
+
} else {
|
|
140
|
+
const jsOutput = result.outputFiles.find(
|
|
141
|
+
(f) => f.path.endsWith(".js")
|
|
142
|
+
);
|
|
143
|
+
if (!jsOutput) {
|
|
144
|
+
return {
|
|
145
|
+
errors: [
|
|
146
|
+
{
|
|
147
|
+
text: `No JavaScript output was generated for ${args.path}`
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
content = Buffer.from(jsOutput.text);
|
|
153
|
+
outputExt = ".js";
|
|
154
|
+
mimeType = "application/javascript";
|
|
155
|
+
}
|
|
156
|
+
} else if (needsCSSBundling) {
|
|
157
|
+
const entryPath = args.path;
|
|
158
|
+
const externalAbsolutePathsPlugin = {
|
|
159
|
+
name: "external-absolute-paths",
|
|
160
|
+
setup(build2) {
|
|
161
|
+
build2.onResolve({ filter: /^\// }, (resolveArgs) => {
|
|
162
|
+
if (resolveArgs.kind === "entry-point") {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
path: resolveArgs.path,
|
|
167
|
+
external: true
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
const ctx = await getContext(entryPath, {
|
|
173
|
+
entryPoints: [entryPath],
|
|
174
|
+
bundle: true,
|
|
175
|
+
write: false,
|
|
176
|
+
minify: true,
|
|
177
|
+
// outdir required for esbuild to generate output paths
|
|
178
|
+
outdir: config.outDir,
|
|
179
|
+
plugins: [externalAbsolutePathsPlugin],
|
|
180
|
+
// Loaders for web assets referenced in CSS via url()
|
|
181
|
+
loader: {
|
|
182
|
+
// Fonts
|
|
183
|
+
".woff": "file",
|
|
184
|
+
".woff2": "file",
|
|
185
|
+
".ttf": "file",
|
|
186
|
+
".eot": "file",
|
|
187
|
+
// Images
|
|
188
|
+
".svg": "file",
|
|
189
|
+
".png": "file",
|
|
190
|
+
".jpg": "file",
|
|
191
|
+
".jpeg": "file",
|
|
192
|
+
".gif": "file",
|
|
193
|
+
".webp": "file",
|
|
194
|
+
".ico": "file",
|
|
195
|
+
// Media
|
|
196
|
+
".mp4": "file",
|
|
197
|
+
".webm": "file",
|
|
198
|
+
".mp3": "file",
|
|
199
|
+
".ogg": "file"
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const result = await ctx.rebuild();
|
|
203
|
+
const cssOutput = result.outputFiles?.find(
|
|
204
|
+
(f) => f.path.endsWith(".css")
|
|
205
|
+
);
|
|
206
|
+
if (!cssOutput) {
|
|
207
|
+
return {
|
|
208
|
+
errors: [{ text: `No CSS output generated for ${args.path}` }]
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const basePath2 = normalizePath(args.with.assetBase);
|
|
212
|
+
const cssOutputDir = join(config.outDir, "public", basePath2);
|
|
213
|
+
if (!existsSync(cssOutputDir)) {
|
|
214
|
+
mkdirSync(cssOutputDir, { recursive: true });
|
|
215
|
+
}
|
|
216
|
+
for (const file of result.outputFiles || []) {
|
|
217
|
+
if (file === cssOutput)
|
|
218
|
+
continue;
|
|
219
|
+
const assetFilename = file.path.split("/").pop();
|
|
220
|
+
const assetPath = join(cssOutputDir, assetFilename);
|
|
221
|
+
writeFileSync(assetPath, file.contents);
|
|
222
|
+
const assetUrl = `${basePath2}${assetFilename}`;
|
|
223
|
+
const assetHash = createHash("sha256").update(file.contents).digest("hex").slice(0, HASH_LENGTH);
|
|
224
|
+
manifest.assets[assetFilename] = {
|
|
225
|
+
source: assetFilename,
|
|
226
|
+
output: assetFilename,
|
|
227
|
+
url: assetUrl,
|
|
228
|
+
hash: assetHash,
|
|
229
|
+
size: file.contents.length,
|
|
230
|
+
type: mime.getType(assetFilename) || void 0
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
content = Buffer.from(cssOutput.text);
|
|
234
|
+
outputExt = ".css";
|
|
235
|
+
mimeType = "text/css";
|
|
236
|
+
} else {
|
|
237
|
+
content = readFileSync(args.path);
|
|
238
|
+
mimeType = mime.getType(args.path) || void 0;
|
|
239
|
+
}
|
|
240
|
+
const hash = createHash("sha256").update(content).digest("hex").slice(0, HASH_LENGTH);
|
|
241
|
+
let filename;
|
|
242
|
+
if (args.with.assetName && typeof args.with.assetName === "string") {
|
|
243
|
+
filename = args.with.assetName.replace(/\[name\]/g, name).replace(/\[ext\]/g, outputExt.slice(1));
|
|
244
|
+
} else {
|
|
245
|
+
filename = `${name}-${hash}${outputExt}`;
|
|
246
|
+
}
|
|
247
|
+
const basePath = normalizePath(args.with.assetBase);
|
|
248
|
+
const publicURL = `${basePath}${filename}`;
|
|
249
|
+
const outputDir = join(config.outDir, "public", basePath);
|
|
250
|
+
if (!existsSync(outputDir)) {
|
|
251
|
+
mkdirSync(outputDir, { recursive: true });
|
|
252
|
+
}
|
|
253
|
+
const outputPath = join(outputDir, filename);
|
|
254
|
+
writeFileSync(outputPath, content);
|
|
255
|
+
const sourcePath = relative(process.cwd(), args.path);
|
|
256
|
+
const manifestEntry = {
|
|
257
|
+
source: sourcePath,
|
|
258
|
+
output: filename,
|
|
259
|
+
url: publicURL,
|
|
260
|
+
hash,
|
|
261
|
+
size: content.length,
|
|
262
|
+
type: mimeType
|
|
263
|
+
};
|
|
264
|
+
manifest.assets[sourcePath] = manifestEntry;
|
|
265
|
+
return {
|
|
266
|
+
contents: `export default ${JSON.stringify(publicURL)};`,
|
|
267
|
+
loader: "js"
|
|
268
|
+
};
|
|
269
|
+
} catch (error) {
|
|
270
|
+
return {
|
|
271
|
+
errors: [
|
|
272
|
+
{
|
|
273
|
+
text: `Failed to process asset: ${error.message}`,
|
|
274
|
+
detail: error
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
build.onEnd(async () => {
|
|
281
|
+
for (const ctx of contexts.values()) {
|
|
282
|
+
await ctx.dispose();
|
|
283
|
+
}
|
|
284
|
+
contexts.clear();
|
|
285
|
+
try {
|
|
286
|
+
const manifestPath = join(config.outDir, "server", "assets.json");
|
|
287
|
+
const manifestDir = dirname(manifestPath);
|
|
288
|
+
if (!existsSync(manifestDir)) {
|
|
289
|
+
mkdirSync(manifestDir, { recursive: true });
|
|
290
|
+
}
|
|
291
|
+
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
292
|
+
logger.debug("Generated asset manifest", {
|
|
293
|
+
path: manifestPath,
|
|
294
|
+
assetCount: Object.keys(manifest.assets).length
|
|
295
|
+
});
|
|
296
|
+
} catch (error) {
|
|
297
|
+
logger.warn("Failed to write asset manifest: {error}", { error });
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/plugins/import-meta.ts
|
|
305
|
+
import { readFile } from "fs/promises";
|
|
306
|
+
import { dirname as dirname2 } from "path";
|
|
307
|
+
import { pathToFileURL } from "url";
|
|
308
|
+
function importMetaPlugin() {
|
|
309
|
+
return {
|
|
310
|
+
name: "import-meta-transform",
|
|
311
|
+
setup(build) {
|
|
312
|
+
build.onLoad({ filter: /\.[jt]sx?$/, namespace: "file" }, async (args) => {
|
|
313
|
+
if (args.path.includes("node_modules") || args.path.includes("/packages/")) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
const contents = await readFile(args.path, "utf8");
|
|
317
|
+
if (!contents.includes("import.meta.url") && !contents.includes("import.meta.dirname") && !contents.includes("import.meta.filename")) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
const fileUrl = pathToFileURL(args.path).href;
|
|
321
|
+
const fileDirname = dirname2(args.path);
|
|
322
|
+
const fileFilename = args.path;
|
|
323
|
+
let transformed = contents;
|
|
324
|
+
transformed = transformed.replace(
|
|
325
|
+
/\bimport\.meta\.url\b/g,
|
|
326
|
+
JSON.stringify(fileUrl)
|
|
327
|
+
);
|
|
328
|
+
transformed = transformed.replace(
|
|
329
|
+
/\bimport\.meta\.dirname\b/g,
|
|
330
|
+
JSON.stringify(fileDirname)
|
|
331
|
+
);
|
|
332
|
+
transformed = transformed.replace(
|
|
333
|
+
/\bimport\.meta\.filename\b/g,
|
|
334
|
+
JSON.stringify(fileFilename)
|
|
335
|
+
);
|
|
336
|
+
const ext = args.path.split(".").pop();
|
|
337
|
+
let loader = "js";
|
|
338
|
+
if (ext === "ts")
|
|
339
|
+
loader = "ts";
|
|
340
|
+
else if (ext === "tsx")
|
|
341
|
+
loader = "tsx";
|
|
342
|
+
else if (ext === "jsx")
|
|
343
|
+
loader = "jsx";
|
|
344
|
+
return {
|
|
345
|
+
contents: transformed,
|
|
346
|
+
loader
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/utils/jsx-config.ts
|
|
354
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
355
|
+
import { join as join2, dirname as dirname3 } from "path";
|
|
356
|
+
import { existsSync as existsSync2 } from "fs";
|
|
357
|
+
var CRANK_JSX_DEFAULTS = {
|
|
358
|
+
jsx: "automatic",
|
|
359
|
+
jsxImportSource: "@b9g/crank"
|
|
360
|
+
};
|
|
361
|
+
async function findTsConfig(startDir) {
|
|
362
|
+
let dir = startDir;
|
|
363
|
+
while (dir !== dirname3(dir)) {
|
|
364
|
+
const tsconfigPath = join2(dir, "tsconfig.json");
|
|
365
|
+
if (existsSync2(tsconfigPath)) {
|
|
366
|
+
return tsconfigPath;
|
|
367
|
+
}
|
|
368
|
+
dir = dirname3(dir);
|
|
369
|
+
}
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
async function parseTsConfig(tsconfigPath) {
|
|
373
|
+
const content = await readFile2(tsconfigPath, "utf8");
|
|
374
|
+
const stripped = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
375
|
+
const config = JSON.parse(stripped);
|
|
376
|
+
if (config.extends) {
|
|
377
|
+
const baseDir = dirname3(tsconfigPath);
|
|
378
|
+
let extendsPath = config.extends;
|
|
379
|
+
if (extendsPath.startsWith(".")) {
|
|
380
|
+
extendsPath = join2(baseDir, extendsPath);
|
|
381
|
+
} else {
|
|
382
|
+
extendsPath = join2(baseDir, "node_modules", extendsPath);
|
|
383
|
+
}
|
|
384
|
+
if (!extendsPath.endsWith(".json")) {
|
|
385
|
+
extendsPath += ".json";
|
|
386
|
+
}
|
|
387
|
+
if (existsSync2(extendsPath)) {
|
|
388
|
+
const baseConfig = await parseTsConfig(extendsPath);
|
|
389
|
+
return {
|
|
390
|
+
...baseConfig,
|
|
391
|
+
...config,
|
|
392
|
+
compilerOptions: {
|
|
393
|
+
...baseConfig.compilerOptions,
|
|
394
|
+
...config.compilerOptions
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return config;
|
|
400
|
+
}
|
|
401
|
+
function mapTSConfigToESBuild(compilerOptions) {
|
|
402
|
+
const options = {};
|
|
403
|
+
if (compilerOptions.jsx) {
|
|
404
|
+
switch (compilerOptions.jsx) {
|
|
405
|
+
case "react":
|
|
406
|
+
case "react-native":
|
|
407
|
+
options.jsx = "transform";
|
|
408
|
+
break;
|
|
409
|
+
case "react-jsx":
|
|
410
|
+
case "react-jsxdev":
|
|
411
|
+
options.jsx = "automatic";
|
|
412
|
+
break;
|
|
413
|
+
case "preserve":
|
|
414
|
+
options.jsx = "preserve";
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (compilerOptions.jsxFactory) {
|
|
419
|
+
options.jsxFactory = compilerOptions.jsxFactory;
|
|
420
|
+
}
|
|
421
|
+
if (compilerOptions.jsxFragmentFactory) {
|
|
422
|
+
options.jsxFragment = compilerOptions.jsxFragmentFactory;
|
|
423
|
+
}
|
|
424
|
+
if (compilerOptions.jsxImportSource) {
|
|
425
|
+
options.jsxImportSource = compilerOptions.jsxImportSource;
|
|
426
|
+
}
|
|
427
|
+
return options;
|
|
428
|
+
}
|
|
429
|
+
async function loadJSXConfig(projectRoot) {
|
|
430
|
+
const tsconfigPath = await findTsConfig(projectRoot);
|
|
431
|
+
if (tsconfigPath) {
|
|
432
|
+
const config = await parseTsConfig(tsconfigPath);
|
|
433
|
+
const compilerOptions = config.compilerOptions || {};
|
|
434
|
+
const hasJSXConfig = compilerOptions.jsx || compilerOptions.jsxFactory || compilerOptions.jsxFragmentFactory || compilerOptions.jsxImportSource;
|
|
435
|
+
if (hasJSXConfig) {
|
|
436
|
+
const tsOptions = mapTSConfigToESBuild(compilerOptions);
|
|
437
|
+
return {
|
|
438
|
+
...CRANK_JSX_DEFAULTS,
|
|
439
|
+
...tsOptions
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return { ...CRANK_JSX_DEFAULTS };
|
|
444
|
+
}
|
|
445
|
+
function applyJSXOptions(buildOptions, jsxOptions) {
|
|
446
|
+
if (jsxOptions.jsx) {
|
|
447
|
+
buildOptions.jsx = jsxOptions.jsx;
|
|
448
|
+
}
|
|
449
|
+
if (jsxOptions.jsxFactory) {
|
|
450
|
+
buildOptions.jsxFactory = jsxOptions.jsxFactory;
|
|
451
|
+
}
|
|
452
|
+
if (jsxOptions.jsxFragment) {
|
|
453
|
+
buildOptions.jsxFragment = jsxOptions.jsxFragment;
|
|
454
|
+
}
|
|
455
|
+
if (jsxOptions.jsxImportSource) {
|
|
456
|
+
buildOptions.jsxImportSource = jsxOptions.jsxImportSource;
|
|
457
|
+
}
|
|
458
|
+
if (jsxOptions.jsxSideEffects !== void 0) {
|
|
459
|
+
buildOptions.jsxSideEffects = jsxOptions.jsxSideEffects;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export {
|
|
464
|
+
assetsPlugin,
|
|
465
|
+
importMetaPlugin,
|
|
466
|
+
loadJSXConfig,
|
|
467
|
+
applyJSXOptions
|
|
468
|
+
};
|