Skip to content

Commit 7e64f75

Browse files
committed
refactor(pack): ship lightningcss as a core dependency, not an optional peer
lightningcss is already a core dependency (Vite's lightningcss transformer uses it), so the bundled @tsdown/css can use it directly and CSS bundling works with no extra install. Revert the optional-peer + loader churn: keep lightningcss in dependencies (via catalog) and drop the __vpImportLightningcss helper and the missing-lightningcss snap test.
1 parent bbc3770 commit 7e64f75

13 files changed

Lines changed: 28 additions & 131 deletions

File tree

docs/guide/pack.md

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,4 @@ See the official [tsdown executable docs](https://tsdown.dev/options/exe#executa
6666

6767
## CSS Bundling
6868

69-
`vp pack` can transform and bundle CSS (including CSS Modules and Lightning CSS optimizations) for your entry points. This support is bundled into Vite+, so you do not need to install `@tsdown/css`.
70-
71-
CSS transforms are powered by [Lightning CSS](https://lightningcss.dev/), which ships as a native module and is an optional peer dependency. Install it when you bundle CSS:
72-
73-
```bash
74-
vp add -D lightningcss
75-
```
76-
77-
If it is missing, `vp pack` prints an actionable error telling you to install it.
69+
`vp pack` can transform and bundle CSS (including CSS Modules and [Lightning CSS](https://lightningcss.dev/) optimizations) for your entry points. This support is bundled into Vite+, so you do not need to install `@tsdown/css` or `lightningcss` separately, it works out of the box.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/block-lightningcss.mjs

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/package.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/register-block.mjs

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/snap.txt

Lines changed: 0 additions & 9 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/src/index.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/src/style.css

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/cli/snap-tests/command-pack-css-missing-lightningcss/steps.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/core/build.ts

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ async function bundleTsdown() {
394394

395395
// Everything else in tsdown's peer dependencies stays external. `lightningcss`
396396
// (a native module) and `postcss` also stay external: `@tsdown/css` pulls them
397-
// in, and they cannot be bundled. `lightningcss` becomes an optional peer with
398-
// a friendly loader injected by `wireBundledTsdownExtensions()`.
397+
// in and they cannot be bundled. Both are core `dependencies`, so they resolve
398+
// at runtime and CSS bundling works without users installing anything.
399399
const tsdownExternal = [
400400
...Object.keys(pkgJson.peerDependencies).filter((name) => !bundledTsdownPackages.has(name)),
401401
'lightningcss',
@@ -585,20 +585,21 @@ async function brandTsdown() {
585585

586586
// Wire the bundled `@tsdown/exe` and `@tsdown/css` extensions into the bundled
587587
// tsdown so they load from the local chunks instead of resolving external
588-
// top-level packages, and make `lightningcss` an optional peer with a friendly
589-
// loader. See https://github.com/voidzero-dev/vite-plus/issues/1586
588+
// top-level packages. See https://github.com/voidzero-dev/vite-plus/issues/1586
590589
async function wireBundledTsdownExtensions() {
591590
const tsdownDistDir = join(projectDir, 'dist/tsdown');
592591
const buildFiles = await glob(toPosixPath(join(tsdownDistDir, 'build-*.js')), { absolute: true });
593592
if (buildFiles.length === 0) {
594593
throw new Error('wireBundledTsdownExtensions: no build chunk found in dist/tsdown/');
595594
}
596595

597-
// 1) Route `@tsdown/exe` and `@tsdown/css` to the bundled entries.
598-
// - `importWithError("@tsdown/exe")` dynamically imports a runtime string,
599-
// which rolldown cannot follow, so rewrite the call site to the chunk.
600-
// - `pkgExists("@tsdown/css")` resolves the top-level package at runtime;
601-
// since it is bundled now, force it on and point the import at the chunk.
596+
// Route `@tsdown/exe` and `@tsdown/css` to the bundled entries.
597+
// - `importWithError("@tsdown/exe")` dynamically imports a runtime string,
598+
// which rolldown cannot follow, so rewrite the call site to the chunk.
599+
// - `pkgExists("@tsdown/css")` resolves the top-level package at runtime;
600+
// since it is bundled now, force it on and point the import at the chunk.
601+
// `@tsdown/css` still imports `lightningcss` (a native module that cannot be
602+
// bundled), which resolves to core's own `lightningcss` dependency.
602603
let exeWired = false;
603604
let cssWired = false;
604605
for (const buildFile of buildFiles) {
@@ -628,37 +629,6 @@ async function wireBundledTsdownExtensions() {
628629
if (!cssWired) {
629630
throw new Error('wireBundledTsdownExtensions: `pkgExists("@tsdown/css")` not found');
630631
}
631-
632-
// 2) `lightningcss` is a native module and an optional peer. Wrap its dynamic
633-
// import so a missing install produces an actionable error instead of a raw
634-
// `Cannot find package 'lightningcss'`.
635-
const helper =
636-
'async function __vpImportLightningcss() {\n' +
637-
' try {\n' +
638-
' return await import("lightningcss");\n' +
639-
' } catch (cause) {\n' +
640-
' throw new Error(' +
641-
'"Cannot find package \\"lightningcss\\". CSS bundling with `vp pack` requires it. ' +
642-
'Install it with `vp add -D lightningcss`.", { cause });\n' +
643-
' }\n' +
644-
'}\n';
645-
const allChunks = await glob(toPosixPath(join(tsdownDistDir, '*.js')), { absolute: true });
646-
let lightningcssWired = false;
647-
for (const chunk of allChunks) {
648-
let content = await readFile(chunk, 'utf-8');
649-
if (!content.includes('import("lightningcss")')) {
650-
continue;
651-
}
652-
// Rewrite the call sites first, then prepend the helper (whose own
653-
// `import("lightningcss")` must not be rewritten).
654-
content = content.replaceAll('import("lightningcss")', '__vpImportLightningcss()');
655-
content = helper + content;
656-
await writeFile(chunk, content);
657-
lightningcssWired = true;
658-
}
659-
if (!lightningcssWired) {
660-
throw new Error('wireBundledTsdownExtensions: `import("lightningcss")` not found');
661-
}
662632
}
663633

664634
// Actually do nothing now, we will polish it in the future when `vitepress` is ready
@@ -755,14 +725,6 @@ async function mergePackageJson() {
755725
const vitePkg = JSON.parse(await readFile(vitePkgPath, 'utf-8'));
756726
const destPkg = JSON.parse(await readFile(destPkgPath, 'utf-8'));
757727

758-
// Track the bundled `@tsdown/css` lightningcss dependency so the optional peer
759-
// range stays in lockstep with what the bundled CSS code expects.
760-
const require = createRequire(import.meta.url);
761-
const tsdownCssPkg = JSON.parse(
762-
await readFile(require.resolve('@tsdown/css/package.json'), 'utf-8'),
763-
);
764-
const lightningcssPeerRange: string = tsdownCssPkg.dependencies?.lightningcss ?? '^1.30.2';
765-
766728
// Merge peerDependencies from tsdown and vite
767729
destPkg.peerDependencies = {
768730
...tsdownPkg.peerDependencies,
@@ -775,17 +737,15 @@ async function mergePackageJson() {
775737
...vitePkg.peerDependenciesMeta,
776738
};
777739

778-
// `@tsdown/exe` and `@tsdown/css` are bundled into core (see bundleTsdown),
779-
// so they must not be advertised as peers anymore. `lightningcss` is a native
780-
// module pulled in by the bundled `@tsdown/css` (and Vite's lightningcss
781-
// transformer); keep it external as an optional peer so users only install it
782-
// when they actually bundle CSS.
740+
// `@tsdown/exe` and `@tsdown/css` are bundled into core (see bundleTsdown), so
741+
// they must not be advertised as peers anymore. `lightningcss` (which the
742+
// bundled `@tsdown/css` and Vite's lightningcss transformer use) stays a core
743+
// `dependency`, kept in lockstep with `@tsdown/css` by the upgrade-deps script,
744+
// so CSS bundling works without any extra install.
783745
for (const bundled of ['@tsdown/exe', '@tsdown/css']) {
784746
delete destPkg.peerDependencies[bundled];
785747
delete destPkg.peerDependenciesMeta[bundled];
786748
}
787-
destPkg.peerDependencies['lightningcss'] = lightningcssPeerRange;
788-
destPkg.peerDependenciesMeta['lightningcss'] = { optional: true };
789749

790750
destPkg.bundledVersions = {
791751
...destPkg.bundledVersions,

packages/core/package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"dependencies": {
103103
"@oxc-project/runtime": "catalog:",
104104
"@oxc-project/types": "catalog:",
105+
"lightningcss": "catalog:",
105106
"postcss": "^8.5.6"
106107
},
107108
"devDependencies": {
@@ -116,7 +117,6 @@
116117
"@vitejs/devtools": "^0.3.3",
117118
"es-module-lexer": "^1.7.0",
118119
"hookable": "^6.0.1",
119-
"lightningcss": "^1.32.0",
120120
"magic-string": "^0.30.21",
121121
"oxc-parser": "catalog:",
122122
"oxfmt": "catalog:",
@@ -140,7 +140,6 @@
140140
"esbuild": "^0.27.0 || ^0.28.0",
141141
"jiti": ">=1.21.0",
142142
"less": "^4.0.0",
143-
"lightningcss": "^1.32.0",
144143
"publint": "^0.3.8",
145144
"sass": "^1.70.0",
146145
"sass-embedded": "^1.70.0",
@@ -204,9 +203,6 @@
204203
},
205204
"yaml": {
206205
"optional": true
207-
},
208-
"lightningcss": {
209-
"optional": true
210206
}
211207
},
212208
"optionalDependencies": {

0 commit comments

Comments
 (0)