@junejs/server 0.0.19 → 0.0.20
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/package.json +3 -3
- package/src/build.ts +3 -2
- package/src/css.ts +41 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junejs/server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "June host adapters + dev server. Host-coupled; depends on the pure @junejs/core contract layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"typecheck": "tsc --noEmit"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@junejs/core": "0.0.
|
|
34
|
-
"@junejs/db": "0.0.
|
|
33
|
+
"@junejs/core": "0.0.20",
|
|
34
|
+
"@junejs/db": "0.0.20",
|
|
35
35
|
"marked": "^18.0.5",
|
|
36
36
|
"rolldown": "^1.1.0",
|
|
37
37
|
"lightningcss": "^1.27.0"
|
package/src/build.ts
CHANGED
|
@@ -34,7 +34,7 @@ import { createWorker, type WorkerManifest } from "./worker";
|
|
|
34
34
|
import { findExtraFile } from "./router";
|
|
35
35
|
import type { ExtraHandler, LayoutComponent, LoadingComponent } from "./pipeline";
|
|
36
36
|
import { findClientEntry, bundleClientToFile, CLIENT_SCRIPT_URL } from "./client-bundle";
|
|
37
|
-
import { findGlobalCss, minifyCss, processCss, STYLES_URL } from "./css";
|
|
37
|
+
import { cssTargets, findGlobalCss, minifyCss, processCss, STYLES_URL } from "./css";
|
|
38
38
|
import { buildModuleCss, rolldownCssModulesPlugin, registerCssModules } from "./css-modules";
|
|
39
39
|
|
|
40
40
|
export type BuildResult = {
|
|
@@ -290,7 +290,8 @@ export async function juneBuild(
|
|
|
290
290
|
const { maps: cssModuleMaps, css: rawModuleCss } = await buildModuleCss(appDir, appRoot);
|
|
291
291
|
// Minify for build (dev serves it readable). Scoped class names are untouched,
|
|
292
292
|
// so the hashed sheet still matches the maps the bundlers/loaders hand out.
|
|
293
|
-
const moduleCss =
|
|
293
|
+
const moduleCss =
|
|
294
|
+
rawModuleCss === null ? null : await minifyCss(rawModuleCss, "modules.css", await cssTargets(appDir));
|
|
294
295
|
let moduleCssAsset: string | null = null;
|
|
295
296
|
if (moduleCss !== null) {
|
|
296
297
|
const hash = createHash("sha256").update(moduleCss).digest("hex").slice(0, 8);
|
package/src/css.ts
CHANGED
|
@@ -15,6 +15,8 @@ import { createRequire } from "node:module";
|
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import { pathToFileURL } from "node:url";
|
|
17
17
|
|
|
18
|
+
import type { Targets } from "lightningcss"; // type-only — never enters the graph
|
|
19
|
+
|
|
18
20
|
// Framework-emitted assets live under the reserved /_june/ prefix so they never
|
|
19
21
|
// collide with — or squat on — a user's own paths (cf. Next /_next/, Astro
|
|
20
22
|
// /_astro/). Build content-hashes the file under here; this is the dev URL.
|
|
@@ -39,6 +41,32 @@ function resolveFromApp(specifier: string, appDir: string): string | null {
|
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
// Browser targets for autoprefix + syntax lowering (CSS nesting, :is(), oklch,
|
|
45
|
+
// logical properties, …). June adds NO dep here: if the app installs `browserslist`
|
|
46
|
+
// its config (or the browserslist defaults) drives the targets; otherwise a baked,
|
|
47
|
+
// broadly-supported baseline. Override per app the standard way — a `browserslist`
|
|
48
|
+
// field in package.json or a .browserslistrc.
|
|
49
|
+
const v = (major: number, minor = 0): number => (major << 16) | (minor << 8);
|
|
50
|
+
const DEFAULT_TARGETS: Targets = { chrome: v(107), edge: v(107), firefox: v(104), safari: v(16) };
|
|
51
|
+
|
|
52
|
+
let targetsCache: { appDir: string; targets: Targets } | null = null;
|
|
53
|
+
export async function cssTargets(appDir: string): Promise<Targets> {
|
|
54
|
+
if (targetsCache?.appDir === appDir) return targetsCache.targets;
|
|
55
|
+
let targets: Targets = DEFAULT_TARGETS;
|
|
56
|
+
const blPath = resolveFromApp("browserslist", appDir);
|
|
57
|
+
if (blPath) {
|
|
58
|
+
try {
|
|
59
|
+
const browserslist = ((await import(blPath)) as { default: (q?: unknown, o?: unknown) => string[] }).default;
|
|
60
|
+
const { browserslistToTargets } = await import("lightningcss");
|
|
61
|
+
targets = browserslistToTargets(browserslist(undefined, { path: appDir }));
|
|
62
|
+
} catch {
|
|
63
|
+
/* malformed config / resolution race → keep the baked default */
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
targetsCache = { appDir, targets };
|
|
67
|
+
return targets;
|
|
68
|
+
}
|
|
69
|
+
|
|
42
70
|
async function compileTailwind(
|
|
43
71
|
css: string,
|
|
44
72
|
file: string,
|
|
@@ -76,16 +104,17 @@ export function invalidateCss(): void {
|
|
|
76
104
|
devCache = null;
|
|
77
105
|
}
|
|
78
106
|
|
|
79
|
-
// Minify a finished stylesheet with Lightning CSS —
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
107
|
+
// Minify a finished stylesheet with Lightning CSS — and, given `targets`, ALSO
|
|
108
|
+
// autoprefix + lower modern syntax (nesting, :is(), oklch, logical props) for the
|
|
109
|
+
// target browsers. The same engine Tailwind v4 optimizes with, so all of June's
|
|
110
|
+
// build-time CSS comes out consistently. It never touches identifiers, so scoped
|
|
111
|
+
// CSS-module class names survive intact (hydration stays byte-identical to SSR).
|
|
112
|
+
// Lazy import: build/dev-time only, never in the worker graph. Falls back to the
|
|
113
|
+
// input if Lightning CSS can't parse it, so it can never break a build.
|
|
114
|
+
export async function minifyCss(css: string, filename = "input.css", targets?: Targets): Promise<string> {
|
|
86
115
|
try {
|
|
87
116
|
const { transform } = await import("lightningcss");
|
|
88
|
-
const { code } = transform({ filename, code: Buffer.from(css), minify: true });
|
|
117
|
+
const { code } = transform({ filename, code: Buffer.from(css), minify: true, targets });
|
|
89
118
|
return code.toString();
|
|
90
119
|
} catch (e) {
|
|
91
120
|
console.warn("[june] CSS minify failed; emitting unminified:", e);
|
|
@@ -112,7 +141,8 @@ export async function processCss(
|
|
|
112
141
|
"[june] global.css uses Tailwind but @tailwindcss/postcss isn't installed — serving raw CSS.",
|
|
113
142
|
);
|
|
114
143
|
}
|
|
115
|
-
// Plain CSS (or the Tailwind fallback): minify
|
|
116
|
-
//
|
|
117
|
-
|
|
144
|
+
// Plain CSS (or the Tailwind fallback): minify + autoprefix/lower for the app's
|
|
145
|
+
// browser targets, so the non-Tailwind path is optimized too. (Tailwind v4 owns
|
|
146
|
+
// its own targeting; dev stays readable and untargeted.)
|
|
147
|
+
return opts.minify ? await minifyCss(css, file, await cssTargets(appDir)) : css;
|
|
118
148
|
}
|