@gjsify/rolldown-plugin-gjsify 0.3.15 → 0.3.17

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.
@@ -50,7 +50,6 @@ export const setupForBrowser = async (input) => {
50
50
  output: {
51
51
  ...input.output,
52
52
  format: 'esm',
53
- minify: false,
54
53
  sourcemap: false,
55
54
  // Single-bundle output. `codeSplitting: false` replaces the
56
55
  // deprecated `inlineDynamicImports: true`.
package/lib/app/gjs.js CHANGED
@@ -95,7 +95,6 @@ export const setupForGjs = async (input) => {
95
95
  output: {
96
96
  ...input.output,
97
97
  format,
98
- minify: false,
99
98
  sourcemap: false,
100
99
  // App builds emit a single bundle file. Disable code-splitting
101
100
  // so dynamic imports get inlined and the entire program lands
@@ -122,7 +121,11 @@ export const setupForGjs = async (input) => {
122
121
  }),
123
122
  blueprintPlugin(),
124
123
  deepkitPlugin({ reflection: input.pluginOptions.reflection }),
125
- cssAsStringPlugin(),
124
+ // GTK4's CSS engine is much older than browser engines — its
125
+ // parser predates nesting + many modern selectors. Targeting
126
+ // `firefox: 60 << 16` makes lightningcss flatten the source
127
+ // into the subset GTK4 understands.
128
+ cssAsStringPlugin({ targets: { firefox: 60 << 16 } }),
126
129
  nodeModulesPathRewritePlugin({ bundleDir }),
127
130
  processStubPlugin({ userBanner: input.userBanner }),
128
131
  // resolveShebangLine returns null when disabled (false/undefined) and
package/lib/app/node.js CHANGED
@@ -75,7 +75,6 @@ export const setupForNode = async (input) => {
75
75
  output: {
76
76
  ...input.output,
77
77
  format,
78
- minify: false,
79
78
  sourcemap: false,
80
79
  banner,
81
80
  // Single-bundle output. `codeSplitting: false` replaces the
@@ -58,7 +58,6 @@ export const setupLib = async (input) => {
58
58
  // Rolldown keeps the full project-relative path. The root is
59
59
  // computed from the common ancestor of resolved entries.
60
60
  preserveModulesRoot,
61
- minify: false,
62
61
  sourcemap: false,
63
62
  },
64
63
  treeshake: false,
@@ -1,2 +1,19 @@
1
1
  import type { Plugin } from 'rolldown';
2
- export declare function cssAsStringPlugin(): Plugin;
2
+ export interface CssAsStringOptions {
3
+ /**
4
+ * lightningcss browser targets passed to `bundleAsync`. When set,
5
+ * nesting + modern syntax are lowered for the given engines. The
6
+ * GJS orchestrator defaults this to `{ firefox: 60 << 16 }` to
7
+ * match the GTK4 CSS parser. Omit or leave undefined to skip
8
+ * lowering (output stays as-authored except for `@import` inlining).
9
+ */
10
+ targets?: import('lightningcss').Targets;
11
+ /**
12
+ * When true (default), `@import` statements are resolved by
13
+ * lightningcss `bundleAsync`. Set false to fall back to a plain
14
+ * `readFile` — useful only when you want to keep `@import` strings
15
+ * verbatim in the bundled JS (rare).
16
+ */
17
+ bundle?: boolean;
18
+ }
19
+ export declare function cssAsStringPlugin(options?: CssAsStringOptions): Plugin;
@@ -12,18 +12,27 @@
12
12
  //
13
13
  // — the canonical pattern for `Gtk.CssProvider` under GJS.
14
14
  //
15
- // `@import` resolution is left to the user / CSS preprocessor. For simple
16
- // app CSS this is fine; for @import-heavy CSS, run a preprocessor (e.g.
17
- // sass / postcss) ahead of `gjsify build` so the input file is already
18
- // flat.
15
+ // `@import` resolution + nesting/modern-syntax lowering are handled via
16
+ // lightningcss `bundleAsync`. The defaults work for the common case
17
+ // (resolve `@import`s, no targeting); the `--app gjs` orchestrator passes
18
+ // `targets: { firefox: 60 << 16 }` so nesting + modern selectors get
19
+ // flattened to GTK4-CSS-engine-compatible output. Targeting is opt-in —
20
+ // a missing `targets` keeps the source pristine.
21
+ //
22
+ // `lightningcss` is a regular dependency of this package; the plugin
23
+ // imports it lazily so missing-arch installs surface the underlying
24
+ // load error instead of crashing every gjsify build.
19
25
  import { readFile } from 'node:fs/promises';
20
- export function cssAsStringPlugin() {
26
+ export function cssAsStringPlugin(options = {}) {
27
+ const { targets, bundle = true } = options;
21
28
  return {
22
29
  name: 'gjsify-css-as-string',
23
30
  load: {
24
31
  filter: { id: /\.css$/ },
25
32
  async handler(id) {
26
- const code = await readFile(id, 'utf8');
33
+ const code = bundle
34
+ ? new TextDecoder('utf-8').decode(await loadAndBundleCss(id, targets))
35
+ : await readFile(id, 'utf8');
27
36
  return {
28
37
  code: `export default ${JSON.stringify(code)};`,
29
38
  moduleType: 'js',
@@ -32,3 +41,13 @@ export function cssAsStringPlugin() {
32
41
  },
33
42
  };
34
43
  }
44
+ async function loadAndBundleCss(filename, targets) {
45
+ const { bundleAsync } = await import('lightningcss');
46
+ const result = await bundleAsync({
47
+ filename,
48
+ targets,
49
+ minify: false,
50
+ errorRecovery: true,
51
+ });
52
+ return result.code;
53
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/rolldown-plugin-gjsify",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "description": "Rolldown / Rollup / Vite plugin orchestrator for GJS, Node, and Browser targets",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -42,13 +42,13 @@
42
42
  ],
43
43
  "license": "MIT",
44
44
  "dependencies": {
45
- "@gjsify/resolve-npm": "^0.3.15",
46
- "@gjsify/rolldown-plugin-deepkit": "^0.3.15",
47
- "@gjsify/rolldown-plugin-pnp": "^0.3.15",
48
- "@gjsify/vite-plugin-blueprint": "^0.3.15",
49
- "@rollup/pluginutils": "^5.1.4",
50
- "acorn": "^8.14.0",
51
- "acorn-walk": "^8.3.4",
45
+ "@gjsify/resolve-npm": "^0.3.17",
46
+ "@gjsify/rolldown-plugin-deepkit": "^0.3.17",
47
+ "@gjsify/rolldown-plugin-pnp": "^0.3.17",
48
+ "@gjsify/vite-plugin-blueprint": "^0.3.17",
49
+ "@rollup/pluginutils": "^5.3.0",
50
+ "acorn": "^8.16.0",
51
+ "acorn-walk": "^8.3.5",
52
52
  "fast-glob": "^3.3.3",
53
53
  "lightningcss": "^1.32.0"
54
54
  },
@@ -61,8 +61,8 @@
61
61
  }
62
62
  },
63
63
  "devDependencies": {
64
- "@types/node": "^25.6.0",
65
- "rolldown": "^1.0.0-rc.18",
64
+ "@types/node": "^25.6.2",
65
+ "rolldown": "^1.0.0",
66
66
  "typescript": "^6.0.3"
67
67
  }
68
68
  }
@@ -73,7 +73,6 @@ export const setupForBrowser = async (input: BrowserFactoryInput): Promise<Brows
73
73
  output: {
74
74
  ...input.output,
75
75
  format: 'esm',
76
- minify: false,
77
76
  sourcemap: false,
78
77
  // Single-bundle output. `codeSplitting: false` replaces the
79
78
  // deprecated `inlineDynamicImports: true`.
package/src/app/gjs.ts CHANGED
@@ -136,7 +136,6 @@ export const setupForGjs = async (input: GjsFactoryInput): Promise<GjsBuildConfi
136
136
  output: {
137
137
  ...input.output,
138
138
  format,
139
- minify: false,
140
139
  sourcemap: false,
141
140
  // App builds emit a single bundle file. Disable code-splitting
142
141
  // so dynamic imports get inlined and the entire program lands
@@ -165,7 +164,11 @@ export const setupForGjs = async (input: GjsFactoryInput): Promise<GjsBuildConfi
165
164
  }),
166
165
  blueprintPlugin() as RolldownPluginOption,
167
166
  deepkitPlugin({ reflection: input.pluginOptions.reflection }),
168
- cssAsStringPlugin(),
167
+ // GTK4's CSS engine is much older than browser engines — its
168
+ // parser predates nesting + many modern selectors. Targeting
169
+ // `firefox: 60 << 16` makes lightningcss flatten the source
170
+ // into the subset GTK4 understands.
171
+ cssAsStringPlugin({ targets: { firefox: 60 << 16 } }),
169
172
  nodeModulesPathRewritePlugin({ bundleDir }),
170
173
  processStubPlugin({ userBanner: input.userBanner }),
171
174
  // resolveShebangLine returns null when disabled (false/undefined) and
package/src/app/node.ts CHANGED
@@ -99,7 +99,6 @@ export const setupForNode = async (input: NodeFactoryInput): Promise<NodeBuildCo
99
99
  output: {
100
100
  ...input.output,
101
101
  format,
102
- minify: false,
103
102
  sourcemap: false,
104
103
  banner,
105
104
  // Single-bundle output. `codeSplitting: false` replaces the
@@ -79,7 +79,6 @@ export const setupLib = async (input: LibFactoryInput): Promise<LibBuildConfig>
79
79
  // Rolldown keeps the full project-relative path. The root is
80
80
  // computed from the common ancestor of resolved entries.
81
81
  preserveModulesRoot,
82
- minify: false,
83
82
  sourcemap: false,
84
83
  },
85
84
  treeshake: false,
@@ -12,21 +12,48 @@
12
12
  //
13
13
  // — the canonical pattern for `Gtk.CssProvider` under GJS.
14
14
  //
15
- // `@import` resolution is left to the user / CSS preprocessor. For simple
16
- // app CSS this is fine; for @import-heavy CSS, run a preprocessor (e.g.
17
- // sass / postcss) ahead of `gjsify build` so the input file is already
18
- // flat.
15
+ // `@import` resolution + nesting/modern-syntax lowering are handled via
16
+ // lightningcss `bundleAsync`. The defaults work for the common case
17
+ // (resolve `@import`s, no targeting); the `--app gjs` orchestrator passes
18
+ // `targets: { firefox: 60 << 16 }` so nesting + modern selectors get
19
+ // flattened to GTK4-CSS-engine-compatible output. Targeting is opt-in —
20
+ // a missing `targets` keeps the source pristine.
21
+ //
22
+ // `lightningcss` is a regular dependency of this package; the plugin
23
+ // imports it lazily so missing-arch installs surface the underlying
24
+ // load error instead of crashing every gjsify build.
19
25
 
20
26
  import { readFile } from 'node:fs/promises';
21
27
  import type { Plugin } from 'rolldown';
22
28
 
23
- export function cssAsStringPlugin(): Plugin {
29
+ export interface CssAsStringOptions {
30
+ /**
31
+ * lightningcss browser targets passed to `bundleAsync`. When set,
32
+ * nesting + modern syntax are lowered for the given engines. The
33
+ * GJS orchestrator defaults this to `{ firefox: 60 << 16 }` to
34
+ * match the GTK4 CSS parser. Omit or leave undefined to skip
35
+ * lowering (output stays as-authored except for `@import` inlining).
36
+ */
37
+ targets?: import('lightningcss').Targets;
38
+ /**
39
+ * When true (default), `@import` statements are resolved by
40
+ * lightningcss `bundleAsync`. Set false to fall back to a plain
41
+ * `readFile` — useful only when you want to keep `@import` strings
42
+ * verbatim in the bundled JS (rare).
43
+ */
44
+ bundle?: boolean;
45
+ }
46
+
47
+ export function cssAsStringPlugin(options: CssAsStringOptions = {}): Plugin {
48
+ const { targets, bundle = true } = options;
24
49
  return {
25
50
  name: 'gjsify-css-as-string',
26
51
  load: {
27
52
  filter: { id: /\.css$/ },
28
53
  async handler(id: string) {
29
- const code = await readFile(id, 'utf8');
54
+ const code = bundle
55
+ ? new TextDecoder('utf-8').decode(await loadAndBundleCss(id, targets))
56
+ : await readFile(id, 'utf8');
30
57
  return {
31
58
  code: `export default ${JSON.stringify(code)};`,
32
59
  moduleType: 'js' as const,
@@ -35,3 +62,17 @@ export function cssAsStringPlugin(): Plugin {
35
62
  },
36
63
  };
37
64
  }
65
+
66
+ async function loadAndBundleCss(
67
+ filename: string,
68
+ targets: import('lightningcss').Targets | undefined,
69
+ ): Promise<Uint8Array> {
70
+ const { bundleAsync } = await import('lightningcss');
71
+ const result = await bundleAsync({
72
+ filename,
73
+ targets,
74
+ minify: false,
75
+ errorRecovery: true,
76
+ });
77
+ return result.code;
78
+ }