cli: Switch CSS bundling from lightningcss to postcss-import

postcss-import naturally preserves @layer declarations during bundling,
eliminating the need for custom layer parsing and restoration logic.
This simplifies the implementation while also preserving source comments.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Patrik Oldsberg
2026-02-09 16:01:16 +01:00
parent 20131c561a
commit fb3bc36690
3 changed files with 47 additions and 156 deletions
+1 -1
View File
@@ -110,7 +110,6 @@
"inquirer": "^8.2.0",
"jest-css-modules": "^2.1.0",
"json-schema": "^0.4.0",
"lightningcss": "^1.29.1",
"lodash": "^4.17.21",
"minimatch": "^9.0.0",
"node-stdlib-browser": "^1.3.1",
@@ -119,6 +118,7 @@
"p-queue": "^6.6.2",
"pirates": "^4.0.6",
"postcss": "^8.1.0",
"postcss-import": "^16.1.0",
"process": "^0.11.10",
"raw-loader": "^4.0.2",
"react-dev-utils": "^12.0.0-next.60",
@@ -15,12 +15,14 @@
*/
import fs from 'fs-extra';
import { bundle, transform } from 'lightningcss';
import postcss from 'postcss';
// @ts-expect-error - no types available
import postcssImport from 'postcss-import';
import { resolve as resolvePath, dirname } from 'node:path';
import { EntryPoint } from '../../../../lib/entryPoints';
/**
* Bundles a CSS entry point, resolving @import statements and preserving @layer declarations.
* Bundles a CSS entry point, resolving @import statements.
*/
export async function buildCSSEntryPoint(
entryPoint: EntryPoint,
@@ -33,33 +35,20 @@ export async function buildCSSEntryPoint(
entryPoint.path.replace(/^(\.\/)?src\//, 'dist/'),
);
// Read source to extract @layer declaration before bundling
// Read source CSS
const source = await fs.readFile(sourcePath, 'utf8');
const layerMatch = source.match(/@layer\s+[^;]+;/);
// Bundle @import statements using lightningcss
const { code: bundledCode } = bundle({
filename: sourcePath,
// Bundle @import statements using postcss-import
const result = await postcss([postcssImport()]).process(source, {
from: sourcePath,
to: outputPath,
});
// Transform the bundled CSS
const { code } = transform({
filename: outputPath,
code: bundledCode,
minify: false,
});
// Restore @layer declaration if it was removed during bundling
let finalCode = code.toString();
if (layerMatch && !finalCode.includes(layerMatch[0])) {
finalCode = `${layerMatch[0]}\n\n${finalCode}`;
}
// Ensure output directory exists
await fs.mkdir(dirname(outputPath), { recursive: true });
// Write the bundled CSS
await fs.writeFile(outputPath, finalCode);
await fs.writeFile(outputPath, result.css);
}
/**
+36 -134
View File
@@ -3377,7 +3377,6 @@ __metadata:
jest-css-modules: "npm:^2.1.0"
jsdom: "npm:^27.1.0"
json-schema: "npm:^0.4.0"
lightningcss: "npm:^1.29.1"
lodash: "npm:^4.17.21"
mini-css-extract-plugin: "npm:^2.4.2"
minimatch: "npm:^9.0.0"
@@ -3389,6 +3388,7 @@ __metadata:
p-queue: "npm:^6.6.2"
pirates: "npm:^4.0.6"
postcss: "npm:^8.1.0"
postcss-import: "npm:^16.1.0"
process: "npm:^0.11.10"
raw-loader: "npm:^4.0.2"
react-dev-utils: "npm:^12.0.0-next.60"
@@ -29131,7 +29131,7 @@ __metadata:
languageName: node
linkType: hard
"detect-libc@npm:^2.0.0, detect-libc@npm:^2.0.3":
"detect-libc@npm:^2.0.0":
version: 2.0.3
resolution: "detect-libc@npm:2.0.3"
checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39
@@ -34799,7 +34799,7 @@ __metadata:
languageName: node
linkType: hard
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1":
"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.1":
version: 2.16.1
resolution: "is-core-module@npm:2.16.1"
dependencies:
@@ -37268,126 +37268,6 @@ __metadata:
languageName: node
linkType: hard
"lightningcss-android-arm64@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-android-arm64@npm:1.30.2"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"lightningcss-darwin-arm64@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-darwin-arm64@npm:1.30.2"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"lightningcss-darwin-x64@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-darwin-x64@npm:1.30.2"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"lightningcss-freebsd-x64@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-freebsd-x64@npm:1.30.2"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"lightningcss-linux-arm-gnueabihf@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-linux-arm-gnueabihf@npm:1.30.2"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"lightningcss-linux-arm64-gnu@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-linux-arm64-gnu@npm:1.30.2"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"lightningcss-linux-arm64-musl@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-linux-arm64-musl@npm:1.30.2"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"lightningcss-linux-x64-gnu@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-linux-x64-gnu@npm:1.30.2"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"lightningcss-linux-x64-musl@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-linux-x64-musl@npm:1.30.2"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"lightningcss-win32-arm64-msvc@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-win32-arm64-msvc@npm:1.30.2"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"lightningcss-win32-x64-msvc@npm:1.30.2":
version: 1.30.2
resolution: "lightningcss-win32-x64-msvc@npm:1.30.2"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"lightningcss@npm:^1.29.1":
version: 1.30.2
resolution: "lightningcss@npm:1.30.2"
dependencies:
detect-libc: "npm:^2.0.3"
lightningcss-android-arm64: "npm:1.30.2"
lightningcss-darwin-arm64: "npm:1.30.2"
lightningcss-darwin-x64: "npm:1.30.2"
lightningcss-freebsd-x64: "npm:1.30.2"
lightningcss-linux-arm-gnueabihf: "npm:1.30.2"
lightningcss-linux-arm64-gnu: "npm:1.30.2"
lightningcss-linux-arm64-musl: "npm:1.30.2"
lightningcss-linux-x64-gnu: "npm:1.30.2"
lightningcss-linux-x64-musl: "npm:1.30.2"
lightningcss-win32-arm64-msvc: "npm:1.30.2"
lightningcss-win32-x64-msvc: "npm:1.30.2"
dependenciesMeta:
lightningcss-android-arm64:
optional: true
lightningcss-darwin-arm64:
optional: true
lightningcss-darwin-x64:
optional: true
lightningcss-freebsd-x64:
optional: true
lightningcss-linux-arm-gnueabihf:
optional: true
lightningcss-linux-arm64-gnu:
optional: true
lightningcss-linux-arm64-musl:
optional: true
lightningcss-linux-x64-gnu:
optional: true
lightningcss-linux-x64-musl:
optional: true
lightningcss-win32-arm64-msvc:
optional: true
lightningcss-win32-x64-msvc:
optional: true
checksum: 10/d6cc06d9bac295589a49446e9c45a241dfa16f4f81a7318c26cbc0be3e189003ec0da5d9a0fd9bdffc63a3ce05878cc7329277eaac77a826e8b68c73dc96cfda
languageName: node
linkType: hard
"lilconfig@npm:^2.0.3":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
@@ -42617,6 +42497,19 @@ __metadata:
languageName: node
linkType: hard
"postcss-import@npm:^16.1.0":
version: 16.1.1
resolution: "postcss-import@npm:16.1.1"
dependencies:
postcss-value-parser: "npm:^4.0.0"
read-cache: "npm:^1.0.0"
resolve: "npm:^1.1.7"
peerDependencies:
postcss: ^8.0.0
checksum: 10/2afac2b6e25f263f45ac2168c5f5e4b2e49e3d44c620338138fe89cf81bd83e6056784a26d54c58611d05dda18bc56069212484ec750bbf6d2e29b623460a7f9
languageName: node
linkType: hard
"postcss-load-config@npm:^3.0.0":
version: 3.0.1
resolution: "postcss-load-config@npm:3.0.1"
@@ -42938,7 +42831,7 @@ __metadata:
languageName: node
linkType: hard
"postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0":
"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
checksum: 10/e4e4486f33b3163a606a6ed94f9c196ab49a37a7a7163abfcd469e5f113210120d70b8dd5e33d64636f41ad52316a3725655421eb9a1094f1bcab1db2f555c62
@@ -44749,6 +44642,15 @@ __metadata:
languageName: node
linkType: hard
"read-cache@npm:^1.0.0":
version: 1.0.0
resolution: "read-cache@npm:1.0.0"
dependencies:
pify: "npm:^2.3.0"
checksum: 10/83a39149d9dfa38f0c482ea0d77b34773c92fef07fe7599cdd914d255b14d0453e0229ef6379d8d27d6947f42d7581635296d0cfa7708f05a9bd8e789d398b31
languageName: node
linkType: hard
"read-cmd-shim@npm:^2.0.0":
version: 2.0.0
resolution: "read-cmd-shim@npm:2.0.0"
@@ -45329,16 +45231,16 @@ __metadata:
languageName: node
linkType: hard
"resolve@npm:^1.1.6, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.10, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1, resolve@npm:~1.22.2":
version: 1.22.10
resolution: "resolve@npm:1.22.10"
"resolve@npm:^1.1.6, resolve@npm:^1.1.7, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.10, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1, resolve@npm:~1.22.2":
version: 1.22.11
resolution: "resolve@npm:1.22.11"
dependencies:
is-core-module: "npm:^2.16.0"
is-core-module: "npm:^2.16.1"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/0a398b44da5c05e6e421d70108822c327675febb880eebe905587628de401854c61d5df02866ff34fc4cb1173a51c9f0e84a94702738df3611a62e2acdc68181
checksum: 10/e1b2e738884a08de03f97ee71494335eba8c2b0feb1de9ae065e82c48997f349f77a2b10e8817e147cf610bfabc4b1cb7891ee8eaf5bf80d4ad514a34c4fab0a
languageName: node
linkType: hard
@@ -45368,16 +45270,16 @@ __metadata:
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.10#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin<compat/resolve>":
version: 1.22.10
resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin<compat/resolve>::version=1.22.10&hash=c3c19d"
"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.1.7#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.10#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin<compat/resolve>":
version: 1.22.11
resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin<compat/resolve>::version=1.22.11&hash=c3c19d"
dependencies:
is-core-module: "npm:^2.16.0"
is-core-module: "npm:^2.16.1"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: 10/d4d878bfe3702d215ea23e75e0e9caf99468e3db76f5ca100d27ebdc527366fee3877e54bce7d47cc72ca8952fc2782a070d238bfa79a550eeb0082384c3b81a
checksum: 10/fd342cad25e52cd6f4f3d1716e189717f2522bfd6641109fe7aa372f32b5714a296ed7c238ddbe7ebb0c1ddfe0b7f71c9984171024c97cf1b2073e3e40ff71a8
languageName: node
linkType: hard