@buding0904/vitepad 0.3.0 → 0.3.2

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/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var fs2 = require('fs/promises');
3
+ var fs3 = require('fs/promises');
4
4
  var os = require('os');
5
- var path2 = require('path');
5
+ var path3 = require('path');
6
6
  var process2 = require('process');
7
7
  var url = require('url');
8
8
  var vite = require('vite');
@@ -13,15 +13,15 @@ var module$1 = require('module');
13
13
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
16
- var fs2__default = /*#__PURE__*/_interopDefault(fs2);
16
+ var fs3__default = /*#__PURE__*/_interopDefault(fs3);
17
17
  var os__default = /*#__PURE__*/_interopDefault(os);
18
- var path2__default = /*#__PURE__*/_interopDefault(path2);
18
+ var path3__default = /*#__PURE__*/_interopDefault(path3);
19
19
  var process2__default = /*#__PURE__*/_interopDefault(process2);
20
20
  var pc2__default = /*#__PURE__*/_interopDefault(pc2);
21
21
 
22
22
  // src/runtime/index.ts
23
- var packageRoot = path2__default.default.resolve(url.fileURLToPath(new URL("..", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))));
24
- var requireFromPackage = module$1.createRequire(path2__default.default.join(packageRoot, "package.json"));
23
+ var packageRoot = path3__default.default.resolve(url.fileURLToPath(new URL("..", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))));
24
+ var requireFromPackage = module$1.createRequire(path3__default.default.join(packageRoot, "package.json"));
25
25
  var linkedPeerPackages = ["vite"];
26
26
  var log = {
27
27
  framework(requested, resolved) {
@@ -46,20 +46,17 @@ async function resolveFramework(spec, options) {
46
46
  requested: "vanilla",
47
47
  cacheStatus: "local",
48
48
  aliases: [],
49
- packageLinks: packageLinks(["tailwindcss"]),
49
+ packageLinks: packageLinks(["unocss"]),
50
50
  editorPackageLinks: []
51
51
  };
52
52
  }
53
53
  const resolved = await resolveFrameworkPackages(spec.name, spec.version);
54
54
  const cacheDir = frameworkCacheDir(spec.name, resolved.version);
55
- const nodeModules = path2__default.default.join(cacheDir, "node_modules");
55
+ const nodeModules = path3__default.default.join(cacheDir, "node_modules");
56
56
  const installed = await isInstalled(cacheDir, resolved.packages);
57
- if (options.forceInstall && await pathExists(cacheDir)) {
58
- await fs2__default.default.rm(cacheDir, { recursive: true, force: true });
59
- }
60
57
  log.framework(`${spec.name}@${spec.version}`, `${spec.name}@${resolved.version}`);
61
58
  const cacheStatus = options.forceInstall ? "miss" : installed ? "hit" : "miss";
62
- if (options.forceInstall || !installed) {
59
+ if (!installed) {
63
60
  log.install(resolved.packages);
64
61
  await installFrameworkCache(cacheDir, resolved.packages);
65
62
  }
@@ -72,7 +69,7 @@ async function resolveFramework(spec, options) {
72
69
  cacheDir,
73
70
  aliases: [],
74
71
  packageLinks: [
75
- ...packageLinks(["tailwindcss"]),
72
+ ...packageLinks(["unocss"]),
76
73
  ...packageLinks(nodeModules, frameworkRuntimePackages(spec.name))
77
74
  ],
78
75
  editorPackageLinks: packageLinks(nodeModules, frameworkEditorPackages(spec.name))
@@ -271,33 +268,33 @@ function packageLinks(nodeModulesOrPackageNames, maybePackageNames) {
271
268
  const packageNames = maybePackageNames ?? [];
272
269
  return packageNames.map((packageName) => ({
273
270
  name: packageName,
274
- source: path2__default.default.join(nodeModules, packageName)
271
+ source: path3__default.default.join(nodeModules, packageName)
275
272
  }));
276
273
  }
277
274
  function resolveInstalledPackageDir(packageName) {
278
275
  const packageJson = requireFromPackage.resolve(`${packageName}/package.json`);
279
- return path2__default.default.dirname(packageJson);
276
+ return path3__default.default.dirname(packageJson);
280
277
  }
281
278
  function frameworkCacheDir(framework, version) {
282
- const base = process.env.VITEPAD_CACHE_DIR || (process.env.XDG_CACHE_HOME ? path2__default.default.join(process.env.XDG_CACHE_HOME, "vitepad") : path2__default.default.join(os__default.default.homedir(), ".cache", "vitepad"));
283
- return path2__default.default.join(base, "frameworks", `${framework}-${sanitizeCacheKey(version)}`);
279
+ const base = process.env.VITEPAD_CACHE_DIR || (process.env.XDG_CACHE_HOME ? path3__default.default.join(process.env.XDG_CACHE_HOME, "vitepad") : path3__default.default.join(os__default.default.homedir(), ".cache", "vitepad"));
280
+ return path3__default.default.join(base, "frameworks", `${framework}-${sanitizeCacheKey(version)}`);
284
281
  }
285
282
  function sanitizeCacheKey(value) {
286
283
  return value.replace(/[^a-zA-Z0-9._-]/g, "_");
287
284
  }
288
285
  async function isInstalled(cacheDir, packages) {
289
- if (!await pathExists(path2__default.default.join(cacheDir, "node_modules"))) return false;
286
+ if (!await pathExists(path3__default.default.join(cacheDir, "node_modules"))) return false;
290
287
  for (const pkg of packages) {
291
288
  const { name } = splitPackageSpec(pkg);
292
- if (!await pathExists(path2__default.default.join(cacheDir, "node_modules", name))) {
289
+ if (!await pathExists(path3__default.default.join(cacheDir, "node_modules", name))) {
293
290
  return false;
294
291
  }
295
292
  }
296
293
  return true;
297
294
  }
298
295
  async function installFrameworkCache(cacheDir, packages) {
299
- await fs2__default.default.mkdir(cacheDir, { recursive: true });
300
- await fs2__default.default.writeFile(path2__default.default.join(cacheDir, "package.json"), JSON.stringify({
296
+ await fs3__default.default.mkdir(cacheDir, { recursive: true });
297
+ await fs3__default.default.writeFile(path3__default.default.join(cacheDir, "package.json"), JSON.stringify({
301
298
  private: true,
302
299
  type: "module",
303
300
  dependencies: Object.fromEntries(packages.map((pkg) => packageToDependency(pkg)))
@@ -337,12 +334,12 @@ ${output.trim()}`));
337
334
  });
338
335
  }
339
336
  async function linkPeerPackages(cacheDir) {
340
- await fs2__default.default.mkdir(path2__default.default.join(cacheDir, "node_modules"), { recursive: true });
337
+ await fs3__default.default.mkdir(path3__default.default.join(cacheDir, "node_modules"), { recursive: true });
341
338
  for (const packageName of linkedPeerPackages) {
342
339
  try {
343
340
  await linkPackage({
344
341
  source: resolveInstalledPackageDir(packageName),
345
- target: path2__default.default.join(cacheDir, "node_modules", packageName)
342
+ target: path3__default.default.join(cacheDir, "node_modules", packageName)
346
343
  });
347
344
  } catch (error) {
348
345
  const message = error instanceof Error ? error.message : String(error);
@@ -352,16 +349,16 @@ ${message}`);
352
349
  }
353
350
  }
354
351
  async function linkPackage(input) {
355
- const source = await fs2__default.default.realpath(input.source);
356
- const existing = await fs2__default.default.lstat(input.target).catch(() => null);
352
+ const source = await fs3__default.default.realpath(input.source);
353
+ const existing = await fs3__default.default.lstat(input.target).catch(() => null);
357
354
  if (existing) {
358
355
  if (existing.isSymbolicLink()) {
359
- const current = await fs2__default.default.realpath(input.target).catch(() => null);
356
+ const current = await fs3__default.default.realpath(input.target).catch(() => null);
360
357
  if (current === source) return;
361
358
  }
362
- await fs2__default.default.rm(input.target, { recursive: true, force: true });
359
+ await fs3__default.default.rm(input.target, { recursive: true, force: true });
363
360
  }
364
- await fs2__default.default.symlink(source, input.target, "dir");
361
+ await fs3__default.default.symlink(source, input.target, "dir");
365
362
  }
366
363
  function createProgress(label) {
367
364
  const width = 18;
@@ -397,16 +394,37 @@ function splitPackageSpec(spec) {
397
394
  return { name: spec.slice(0, at), version: spec.slice(at + 1) };
398
395
  }
399
396
  async function importCachePackage(cacheDir, packageName) {
400
- const requireFromCache = module$1.createRequire(path2__default.default.join(cacheDir, "package.json"));
397
+ const requireFromCache = module$1.createRequire(path3__default.default.join(cacheDir, "package.json"));
401
398
  const resolved = requireFromCache.resolve(packageName);
402
399
  return import(url.pathToFileURL(resolved).href);
403
400
  }
404
401
  async function pathExists(file) {
405
- return fs2__default.default.access(file).then(() => true, () => false);
402
+ return fs3__default.default.access(file).then(() => true, () => false);
403
+ }
404
+ async function packageVersion() {
405
+ const packageJson = await readPackageJson();
406
+ if (typeof packageJson.version === "string") return packageJson.version;
407
+ throw new Error("Failed to read vitepad version from package.json.");
408
+ }
409
+ async function readPackageJson() {
410
+ let current = path3__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
411
+ while (true) {
412
+ const packageJsonPath = path3__default.default.join(current, "package.json");
413
+ const source = await fs3__default.default.readFile(packageJsonPath, "utf8").catch(() => null);
414
+ if (source) {
415
+ const packageJson = JSON.parse(source);
416
+ if (packageJson.name === "@buding0904/vitepad") return packageJson;
417
+ }
418
+ const parent = path3__default.default.dirname(current);
419
+ if (parent === current) {
420
+ throw new Error("Failed to locate vitepad package.json.");
421
+ }
422
+ current = parent;
423
+ }
406
424
  }
407
425
 
408
426
  // src/runtime/index.ts
409
- var rootDir = path2__default.default.resolve(url.fileURLToPath(new URL("..", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))));
427
+ var rootDir = path3__default.default.resolve(url.fileURLToPath(new URL("..", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)))));
410
428
  var supportedComponentExts = /* @__PURE__ */ new Set([".jsx", ".tsx", ".vue", ".svelte"]);
411
429
  var supportedMainExts = /* @__PURE__ */ new Set([".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"]);
412
430
  var frameworkValues = /* @__PURE__ */ new Set(["auto", "react", "preact", "solid", "vue", "svelte", "vanilla"]);
@@ -416,17 +434,21 @@ async function run(argv) {
416
434
  console.log(helpText());
417
435
  return;
418
436
  }
437
+ if (options.version) {
438
+ console.log(await packageVersion());
439
+ return;
440
+ }
419
441
  if (!options.entry) {
420
442
  throw new Error(helpText("Missing entry file."));
421
443
  }
422
- const entry = path2__default.default.resolve(process2__default.default.cwd(), options.entry);
423
- const stat = await fs2__default.default.stat(entry).catch(() => null);
444
+ const entry = path3__default.default.resolve(process2__default.default.cwd(), options.entry);
445
+ const stat = await fs3__default.default.stat(entry).catch(() => null);
424
446
  if (!stat?.isFile()) {
425
447
  throw new Error(`Entry file does not exist: ${entry}`);
426
448
  }
427
- const extension = path2__default.default.extname(entry).toLowerCase();
449
+ const extension = path3__default.default.extname(entry).toLowerCase();
428
450
  const mode = inferMode(extension);
429
- const source = await fs2__default.default.readFile(entry, "utf8");
451
+ const source = await fs3__default.default.readFile(entry, "utf8");
430
452
  const framework = inferFramework({
431
453
  extension,
432
454
  source,
@@ -434,15 +456,12 @@ async function run(argv) {
434
456
  version: options.frameworkVersion
435
457
  });
436
458
  validateCombination({ mode, framework: framework.name, extension });
437
- const resolvedFramework = await resolveFramework(framework, { forceInstall: options.forceInstall });
438
- await setupEditorPackages(path2__default.default.dirname(entry), resolvedFramework.editorPackageLinks);
439
- const classTokens = await collectClassTokens(entry);
459
+ const resolvedFramework = await resolveFramework(framework, { forceInstall: false });
460
+ await setupEditorPackages(path3__default.default.dirname(entry), resolvedFramework.editorPackageLinks);
440
461
  const workspace = await createWorkspace({
441
462
  entry,
442
463
  mode,
443
464
  framework: resolvedFramework.name,
444
- sourceDirs: uniquePaths([process2__default.default.cwd(), path2__default.default.dirname(entry)]),
445
- classTokens,
446
465
  packageLinks: resolvedFramework.packageLinks
447
466
  });
448
467
  const config = await loadUserConfig(options.config);
@@ -452,7 +471,8 @@ async function run(argv) {
452
471
  server: {
453
472
  host: options.host,
454
473
  port: options.port,
455
- open: options.open,
474
+ strictPort: options.strictPort,
475
+ open: false,
456
476
  watch: {
457
477
  ignored: (file) => vite.normalizePath(file).startsWith(`${vite.normalizePath(workspace)}/`)
458
478
  },
@@ -460,7 +480,7 @@ async function run(argv) {
460
480
  allow: [
461
481
  rootDir,
462
482
  process2__default.default.cwd(),
463
- path2__default.default.dirname(entry),
483
+ path3__default.default.dirname(entry),
464
484
  workspace,
465
485
  ...resolvedFramework.cacheDir ? [resolvedFramework.cacheDir] : []
466
486
  ]
@@ -472,13 +492,13 @@ async function run(argv) {
472
492
  ...resolvedFramework.aliases,
473
493
  {
474
494
  find: "@",
475
- replacement: path2__default.default.dirname(entry)
495
+ replacement: path3__default.default.dirname(entry)
476
496
  }
477
497
  ],
478
498
  dedupe: frameworkDedupe(resolvedFramework.name)
479
499
  },
480
500
  optimizeDeps: {
481
- entries: [path2__default.default.join(workspace, "src/main.js")],
501
+ entries: [path3__default.default.join(workspace, "src/main.js")],
482
502
  include: frameworkOptimizeDeps(resolvedFramework.name)
483
503
  },
484
504
  customLogger: createVitepadLogger()
@@ -500,22 +520,24 @@ function parseArgs(argv) {
500
520
  const options = {
501
521
  framework: "auto",
502
522
  frameworkVersion: "latest",
503
- forceInstall: false,
504
523
  port: 8e3,
524
+ strictPort: false,
505
525
  host: "0.0.0.0",
506
- open: "/",
507
- help: false
526
+ help: false,
527
+ version: false
508
528
  };
509
529
  for (let index = 0; index < argv.length; index += 1) {
510
530
  const arg = argv[index];
511
531
  if (arg === "-h" || arg === "--help") {
512
532
  options.help = true;
533
+ } else if (arg === "-v" || arg === "--version") {
534
+ options.version = true;
513
535
  } else if (arg === "--framework" || arg === "-f") {
514
536
  Object.assign(options, parseFramework(readValue(argv, ++index, arg)));
515
537
  } else if (arg.startsWith("--framework=")) {
516
538
  Object.assign(options, parseFramework(arg.slice("--framework=".length)));
517
- } else if (arg === "--force-install") {
518
- options.forceInstall = true;
539
+ } else if (arg === "--strictPort") {
540
+ options.strictPort = true;
519
541
  } else if (arg === "--port" || arg === "-p") {
520
542
  options.port = Number(readValue(argv, ++index, arg));
521
543
  } else if (arg.startsWith("--port=")) {
@@ -524,10 +546,6 @@ function parseArgs(argv) {
524
546
  options.host = readValue(argv, ++index, arg);
525
547
  } else if (arg.startsWith("--host=")) {
526
548
  options.host = arg.slice("--host=".length);
527
- } else if (arg === "--no-open") {
528
- options.open = false;
529
- } else if (arg === "--open") {
530
- options.open = "/";
531
549
  } else if (arg === "--config" || arg === "-c") {
532
550
  options.config = readValue(argv, ++index, arg);
533
551
  } else if (arg.startsWith("--config=")) {
@@ -591,32 +609,29 @@ function validateCombination(input) {
591
609
  }
592
610
  }
593
611
  async function createWorkspace(input) {
594
- const workspace = await fs2__default.default.mkdtemp(path2__default.default.join(await fs2__default.default.realpath(os__default.default.tmpdir()), "vitepad-"));
595
- const srcDir = path2__default.default.join(workspace, "src");
596
- const nodeModulesDir = path2__default.default.join(workspace, "node_modules");
597
- await fs2__default.default.mkdir(srcDir, { recursive: true });
598
- await fs2__default.default.mkdir(nodeModulesDir, { recursive: true });
612
+ const workspace = await fs3__default.default.mkdtemp(path3__default.default.join(await fs3__default.default.realpath(os__default.default.tmpdir()), "vitepad-"));
613
+ const srcDir = path3__default.default.join(workspace, "src");
614
+ const nodeModulesDir = path3__default.default.join(workspace, "node_modules");
615
+ await fs3__default.default.mkdir(srcDir, { recursive: true });
616
+ await fs3__default.default.mkdir(nodeModulesDir, { recursive: true });
599
617
  await Promise.all([
600
- fs2__default.default.writeFile(path2__default.default.join(workspace, "index.html"), htmlTemplate()),
601
- fs2__default.default.writeFile(path2__default.default.join(srcDir, "style.css"), styleTemplate(input.sourceDirs, input.classTokens)),
602
- fs2__default.default.writeFile(path2__default.default.join(srcDir, "main.js"), mainTemplate(input)),
618
+ fs3__default.default.writeFile(path3__default.default.join(workspace, "index.html"), htmlTemplate()),
619
+ fs3__default.default.writeFile(path3__default.default.join(srcDir, "main.js"), mainTemplate(input)),
603
620
  ...input.packageLinks.map((link) => linkWorkspacePackage(nodeModulesDir, link))
604
621
  ]);
605
622
  return workspace;
606
623
  }
607
624
  async function linkWorkspacePackage(nodeModulesDir, link) {
608
- const source = await fs2__default.default.realpath(link.source);
609
- const target = path2__default.default.join(nodeModulesDir, link.name);
610
- await fs2__default.default.mkdir(path2__default.default.dirname(target), { recursive: true });
611
- await fs2__default.default.symlink(source, target, "dir");
625
+ const source = await fs3__default.default.realpath(link.source);
626
+ const target = path3__default.default.join(nodeModulesDir, link.name);
627
+ await fs3__default.default.mkdir(path3__default.default.dirname(target), { recursive: true });
628
+ await fs3__default.default.symlink(source, target, "dir");
612
629
  }
613
630
  async function setupEditorPackages(projectDir, links) {
614
631
  if (links.length === 0) return;
615
- const nodeModulesDir = path2__default.default.join(projectDir, "node_modules");
616
- await fs2__default.default.mkdir(nodeModulesDir, { recursive: true });
617
632
  const linked = [];
618
633
  for (const link of links) {
619
- const result = await linkEditorPackage(nodeModulesDir, link);
634
+ const result = await linkEditorPackage(projectDir, link);
620
635
  if (result === "linked") {
621
636
  linked.push(link.name);
622
637
  }
@@ -625,81 +640,34 @@ async function setupEditorPackages(projectDir, links) {
625
640
  console.log(`${pc2__default.default.cyan("vitepad")} ${pc2__default.default.green("editor")} linked ${linked.map((name) => pc2__default.default.cyan(name)).join(pc2__default.default.gray(", "))}`);
626
641
  }
627
642
  }
628
- async function linkEditorPackage(nodeModulesDir, link) {
629
- const source = await fs2__default.default.realpath(link.source);
630
- const target = path2__default.default.join(nodeModulesDir, link.name);
631
- await fs2__default.default.mkdir(path2__default.default.dirname(target), { recursive: true });
632
- const existing = await fs2__default.default.lstat(target).catch(() => null);
643
+ async function linkEditorPackage(projectDir, link) {
644
+ const source = await fs3__default.default.realpath(link.source);
645
+ const existingResolvablePackage = await findResolvablePackage(projectDir, link.name);
646
+ if (existingResolvablePackage) return "skipped";
647
+ const nodeModulesDir = path3__default.default.join(projectDir, "node_modules");
648
+ const target = path3__default.default.join(nodeModulesDir, link.name);
649
+ await fs3__default.default.mkdir(path3__default.default.dirname(target), { recursive: true });
650
+ const existing = await fs3__default.default.lstat(target).catch(() => null);
633
651
  if (existing) {
634
652
  if (existing.isSymbolicLink()) {
635
- const current = await fs2__default.default.realpath(target).catch(() => null);
653
+ const current = await fs3__default.default.realpath(target).catch(() => null);
636
654
  if (current === source) return "skipped";
637
655
  }
638
656
  return "skipped";
639
657
  }
640
- await fs2__default.default.symlink(source, target, "dir");
658
+ await fs3__default.default.symlink(source, target, "dir");
641
659
  return "linked";
642
660
  }
643
- function uniquePaths(paths) {
644
- return [...new Set(paths.map((item) => vite.normalizePath(path2__default.default.resolve(item))))];
645
- }
646
- function styleTemplate(sourceDirs, classTokens) {
647
- return [
648
- '@import "tailwindcss";',
649
- ...sourceDirs.map((sourceDir) => `@source ${JSON.stringify(sourceDir)};`),
650
- classTokens.length ? `/* vitepad safelist: ${classTokens.join(" ")} */` : "",
651
- ""
652
- ].join("\n");
653
- }
654
- async function collectClassTokens(entry) {
655
- const visited = /* @__PURE__ */ new Set();
656
- const tokens = /* @__PURE__ */ new Set();
657
- await collectFileClassTokens(entry, visited, tokens);
658
- return [...tokens].sort();
659
- }
660
- async function collectFileClassTokens(file, visited, tokens) {
661
- const resolved = path2__default.default.resolve(file);
662
- if (visited.has(resolved)) return;
663
- visited.add(resolved);
664
- const source = await fs2__default.default.readFile(resolved, "utf8").catch(() => "");
665
- for (const match of source.matchAll(/\b(?:class|className)\s*=\s*(?:"([^"]+)"|'([^']+)'|{`([^`]+)`})/g)) {
666
- const value = match[1] || match[2] || match[3] || "";
667
- for (const token of value.split(/\s+/)) {
668
- if (token && !/[${}]/.test(token)) tokens.add(token);
669
- }
670
- }
671
- for (const specifier of localImportSpecifiers(source)) {
672
- const imported = await resolveLocalImport(resolved, specifier);
673
- if (imported) {
674
- await collectFileClassTokens(imported, visited, tokens);
675
- }
676
- }
677
- }
678
- function localImportSpecifiers(source) {
679
- const specifiers = /* @__PURE__ */ new Set();
680
- for (const match of source.matchAll(/\bimport\s+(?:[^'"]+?\s+from\s+)?['"]([^'"]+)['"]/g)) {
681
- if (isLocalSpecifier(match[1])) specifiers.add(match[1]);
682
- }
683
- for (const match of source.matchAll(/\bexport\s+[^'"]+?\s+from\s+['"]([^'"]+)['"]/g)) {
684
- if (isLocalSpecifier(match[1])) specifiers.add(match[1]);
685
- }
686
- return [...specifiers];
687
- }
688
- function isLocalSpecifier(specifier) {
689
- return specifier.startsWith("./") || specifier.startsWith("../");
690
- }
691
- async function resolveLocalImport(importer, specifier) {
692
- const base = path2__default.default.resolve(path2__default.default.dirname(importer), specifier);
693
- const candidates = [
694
- base,
695
- ...[".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte"].map((ext) => `${base}${ext}`),
696
- ...["index.ts", "index.tsx", "index.js", "index.jsx", "index.vue", "index.svelte"].map((file) => path2__default.default.join(base, file))
697
- ];
698
- for (const candidate of candidates) {
699
- const stat = await fs2__default.default.stat(candidate).catch(() => null);
700
- if (stat?.isFile()) return candidate;
661
+ async function findResolvablePackage(fromDir, packageName) {
662
+ let current = path3__default.default.resolve(fromDir);
663
+ while (true) {
664
+ const candidate = path3__default.default.join(current, "node_modules", packageName);
665
+ const existing = await fs3__default.default.lstat(candidate).catch(() => null);
666
+ if (existing) return candidate;
667
+ const parent = path3__default.default.dirname(current);
668
+ if (parent === current) return null;
669
+ current = parent;
701
670
  }
702
- return void 0;
703
671
  }
704
672
  function htmlTemplate() {
705
673
  return `<!doctype html>
@@ -720,13 +688,13 @@ function mainTemplate(input) {
720
688
  const { entry, mode, framework } = input;
721
689
  const importPath = `/@fs/${vite.normalizePath(entry)}`;
722
690
  if (mode === "main") {
723
- return `import './style.css'
691
+ return `import 'virtual:uno.css'
724
692
  import ${JSON.stringify(importPath)}
725
693
  `;
726
694
  }
727
695
  switch (framework) {
728
696
  case "react":
729
- return `import './style.css'
697
+ return `import 'virtual:uno.css'
730
698
  import React from 'react'
731
699
  import { createRoot } from 'react-dom/client'
732
700
  import App from ${JSON.stringify(importPath)}
@@ -734,28 +702,28 @@ import App from ${JSON.stringify(importPath)}
734
702
  createRoot(document.getElementById('root')).render(React.createElement(App))
735
703
  `;
736
704
  case "preact":
737
- return `import './style.css'
705
+ return `import 'virtual:uno.css'
738
706
  import { h, render } from 'preact'
739
707
  import App from ${JSON.stringify(importPath)}
740
708
 
741
709
  render(h(App, null), document.getElementById('root'))
742
710
  `;
743
711
  case "solid":
744
- return `import './style.css'
712
+ return `import 'virtual:uno.css'
745
713
  import { render } from 'solid-js/web'
746
714
  import App from ${JSON.stringify(importPath)}
747
715
 
748
716
  render(() => App({}), document.getElementById('root'))
749
717
  `;
750
718
  case "vue":
751
- return `import './style.css'
719
+ return `import 'virtual:uno.css'
752
720
  import { createApp } from 'vue'
753
721
  import App from ${JSON.stringify(importPath)}
754
722
 
755
723
  createApp(App).mount('#root')
756
724
  `;
757
725
  case "svelte":
758
- return `import './style.css'
726
+ return `import 'virtual:uno.css'
759
727
  import { mount } from 'svelte'
760
728
  import App from ${JSON.stringify(importPath)}
761
729
 
@@ -769,17 +737,18 @@ export default app
769
737
  }
770
738
  async function loadUserConfig(configFile) {
771
739
  if (!configFile) return {};
772
- const resolved = path2__default.default.resolve(process2__default.default.cwd(), configFile);
740
+ const resolved = path3__default.default.resolve(process2__default.default.cwd(), configFile);
773
741
  const configModule = await import(url.pathToFileURL(resolved).href);
774
742
  return configModule.default ?? configModule;
775
743
  }
776
744
  async function loadPlugins(framework) {
777
- const [{ default: tailwindcss }, frameworkPlugins] = await Promise.all([
778
- import('@tailwindcss/vite'),
745
+ const [{ default: unocss }, { presetUno }, frameworkPlugins] = await Promise.all([
746
+ import('unocss/vite'),
747
+ import('unocss'),
779
748
  loadFrameworkPlugins(framework)
780
749
  ]);
781
750
  const plugins = [];
782
- appendPlugin(plugins, tailwindcss());
751
+ appendPlugin(plugins, unocss({ presets: [presetUno()] }));
783
752
  plugins.push(...frameworkPlugins);
784
753
  return plugins;
785
754
  }
@@ -832,10 +801,9 @@ Entries:
832
801
  Options:
833
802
  -f, --framework <name> auto, react, preact, solid, vue, svelte, vanilla
834
803
  Version specs are supported, e.g. react@18, vue@3.4.
835
- --force-install Reinstall the selected framework cache.
836
804
  -p, --port <number> Dev server port. Default: 8000
805
+ --strictPort Exit if the configured port is already in use.
837
806
  --host <host> Dev server host. Default: 0.0.0.0
838
- --no-open Do not open the browser automatically.
839
807
  -c, --config <file> Merge an extra Vite config file.
840
808
  -h, --help Show help.
841
809
  `;