@wular/pnext 0.1.6 → 0.1.8
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/bin/pnext +9 -2
- package/dist/server/_chunks/aliases-pycbtjt1.js +46 -0
- package/dist/server/_chunks/analyze-4d9e00g9.js +449 -0
- package/dist/server/_chunks/boot-bhemypxz.js +38 -0
- package/dist/server/_chunks/build-c991dv65.js +86 -0
- package/dist/server/_chunks/build-kh5e3x48.js +3341 -0
- package/dist/server/_chunks/build-tier-0a96kmx3.js +2456 -0
- package/dist/server/_chunks/compile-040r79gj.js +22 -0
- package/dist/server/_chunks/config-0tvz03a6.js +24 -0
- package/dist/server/_chunks/config-27rj7830.js +36 -0
- package/dist/server/_chunks/create-9rvwshsp.js +135 -0
- package/dist/server/_chunks/dev-ex9exynt.js +220 -0
- package/dist/server/_chunks/esbuild-yyktfrtt.js +15 -0
- package/dist/server/_chunks/generate-myw9hef7.js +22 -0
- package/dist/server/_chunks/index-0r5eqfc7.js +279 -0
- package/dist/server/_chunks/index-0yjv5v47.js +105 -0
- package/dist/server/_chunks/index-11xpbfej.js +17 -0
- package/dist/server/_chunks/index-141vcwk6.js +109 -0
- package/dist/server/_chunks/index-1pzm1hdy.js +4130 -0
- package/dist/server/_chunks/index-29pq0kax.js +590 -0
- package/dist/server/_chunks/index-2vz0wzdn.js +59 -0
- package/dist/server/_chunks/index-2wfv4kvx.js +182 -0
- package/dist/server/_chunks/index-38xpdxwd.js +194 -0
- package/dist/server/_chunks/index-3e075kny.js +128 -0
- package/dist/server/_chunks/index-3ycf5ckv.js +472 -0
- package/dist/server/_chunks/index-4399bvd2.js +18 -0
- package/dist/server/_chunks/index-4da76t62.js +297 -0
- package/dist/server/_chunks/index-4t92hdxd.js +172 -0
- package/dist/server/_chunks/index-4zzebszd.js +10 -0
- package/dist/server/_chunks/index-52k54ykj.js +95 -0
- package/dist/server/_chunks/index-5hr4062s.js +70 -0
- package/dist/server/_chunks/index-68m3mwbd.js +84 -0
- package/dist/server/_chunks/index-6b009mt0.js +56 -0
- package/dist/server/_chunks/index-6gex3pfa.js +15 -0
- package/dist/server/_chunks/index-6kp9r0d9.js +11 -0
- package/dist/server/_chunks/index-6q7zvrap.js +134 -0
- package/dist/server/_chunks/index-71885zaq.js +284 -0
- package/dist/server/_chunks/index-73z4esab.js +38 -0
- package/dist/server/_chunks/index-79ngvam8.js +60 -0
- package/dist/server/_chunks/index-7wc9n8be.js +25 -0
- package/dist/server/_chunks/index-8ct7rqy3.js +198 -0
- package/dist/server/_chunks/index-8kcxdfya.js +206 -0
- package/dist/server/_chunks/index-9ch50vtq.js +18 -0
- package/dist/server/_chunks/index-9f49w76j.js +213 -0
- package/dist/server/_chunks/index-9hz3s0m8.js +851 -0
- package/dist/server/_chunks/index-akkrvjn6.js +535 -0
- package/dist/server/_chunks/index-b6wtkdp4.js +24 -0
- package/dist/server/_chunks/index-b7j671dj.js +207 -0
- package/dist/server/_chunks/index-bcws5eh2.js +35 -0
- package/dist/server/_chunks/index-bzd2ef7t.js +10 -0
- package/dist/server/_chunks/index-cjgqs13g.js +65 -0
- package/dist/server/_chunks/index-ckkdpht5.js +41 -0
- package/dist/server/_chunks/index-cn86z041.js +296 -0
- package/dist/server/_chunks/index-cvr4z22m.js +92 -0
- package/dist/server/_chunks/index-cyfednwb.js +87 -0
- package/dist/server/_chunks/index-d158y67j.js +152 -0
- package/dist/server/_chunks/index-d1jsmhhk.js +955 -0
- package/dist/server/_chunks/index-dg0f05zs.js +199 -0
- package/dist/server/_chunks/index-dgr390q7.js +9438 -0
- package/dist/server/_chunks/index-drwv61cc.js +185 -0
- package/dist/server/_chunks/index-e3a6yx84.js +18 -0
- package/dist/server/_chunks/index-e88tyv35.js +45 -0
- package/dist/server/_chunks/index-en7n9f7m.js +22 -0
- package/dist/server/_chunks/index-entm8bmz.js +28 -0
- package/dist/server/_chunks/index-evhd413j.js +57 -0
- package/dist/server/_chunks/index-ezgj0tr1.js +88 -0
- package/dist/server/_chunks/index-fjv96re1.js +5295 -0
- package/dist/server/_chunks/index-fn1chkkd.js +214 -0
- package/dist/server/_chunks/index-fp8r0sqs.js +64 -0
- package/dist/server/_chunks/index-gcmj16xy.js +92 -0
- package/dist/server/_chunks/index-gkndxkxf.js +736 -0
- package/dist/server/_chunks/index-grta8ap3.js +238 -0
- package/dist/server/_chunks/index-h2a70tg4.js +7 -0
- package/dist/server/_chunks/index-h4xy648y.js +51 -0
- package/dist/server/_chunks/index-hdbwtdv2.js +352 -0
- package/dist/server/_chunks/index-he6n2bvp.js +1270 -0
- package/dist/server/_chunks/index-j0m1jxqa.js +1253 -0
- package/dist/server/_chunks/index-j2zrcp1k.js +66 -0
- package/dist/server/_chunks/index-j681c48a.js +2530 -0
- package/dist/server/_chunks/index-jbj7ehef.js +50 -0
- package/dist/server/_chunks/index-jcsjq3d1.js +20 -0
- package/dist/server/_chunks/index-jks0x0a1.js +14 -0
- package/dist/server/_chunks/index-jn9rbhrx.js +1599 -0
- package/dist/server/_chunks/index-jt8e1pje.js +12 -0
- package/dist/server/_chunks/index-kdhxpwyq.js +483 -0
- package/dist/server/_chunks/index-knp0s912.js +7 -0
- package/dist/server/_chunks/index-kqyy1d4f.js +50 -0
- package/dist/server/_chunks/index-kresp2n8.js +445 -0
- package/dist/server/_chunks/index-m63czgq5.js +590 -0
- package/dist/server/_chunks/index-ms9v9tnx.js +31 -0
- package/dist/server/_chunks/index-n4hxpng2.js +11 -0
- package/dist/server/_chunks/index-n629dy38.js +1071 -0
- package/dist/server/_chunks/index-nf3df4jy.js +266 -0
- package/dist/server/_chunks/index-nqh3xhdc.js +57 -0
- package/dist/server/_chunks/index-pym1cezq.js +39 -0
- package/dist/server/_chunks/index-q3r9z8mq.js +213 -0
- package/dist/server/_chunks/index-q738kkhj.js +100 -0
- package/dist/server/_chunks/index-qcrvt6er.js +112 -0
- package/dist/server/_chunks/index-qjj6gddn.js +54 -0
- package/dist/server/_chunks/index-qpwsgt3a.js +158 -0
- package/dist/server/_chunks/index-r97ptz1q.js +97 -0
- package/dist/server/_chunks/index-ras0sdab.js +26 -0
- package/dist/server/_chunks/index-rcs322t1.js +19 -0
- package/dist/server/_chunks/index-rgj5mx84.js +101 -0
- package/dist/server/_chunks/index-rjegyfx4.js +1435 -0
- package/dist/server/_chunks/index-rt9qq1va.js +4 -0
- package/dist/server/_chunks/index-rthrsed5.js +356 -0
- package/dist/server/_chunks/index-sq3kvz3g.js +200 -0
- package/dist/server/_chunks/index-stbk3jhn.js +31 -0
- package/dist/server/_chunks/index-tf4j19ge.js +130 -0
- package/dist/server/_chunks/index-tgcakdxc.js +125 -0
- package/dist/server/_chunks/index-tgsfjmep.js +74 -0
- package/dist/server/_chunks/index-tq1f96v7.js +51 -0
- package/dist/server/_chunks/index-tq3b39a5.js +107 -0
- package/dist/server/_chunks/index-typcbcsv.js +819 -0
- package/dist/server/_chunks/index-v1ags1na.js +132 -0
- package/dist/server/_chunks/index-vmr35jjw.js +170 -0
- package/dist/server/_chunks/index-vvq7rqtn.js +329 -0
- package/dist/server/_chunks/index-vz0km5qk.js +33 -0
- package/dist/server/_chunks/index-w6h8m6vp.js +138 -0
- package/dist/server/_chunks/index-web361b8.js +138 -0
- package/dist/server/_chunks/index-wm36rj4v.js +311 -0
- package/dist/server/_chunks/index-x0y005nh.js +283 -0
- package/dist/server/_chunks/index-x2m17v9c.js +6166 -0
- package/dist/server/_chunks/index-x3yn4ywm.js +22 -0
- package/dist/server/_chunks/index-x9c55pzy.js +871 -0
- package/dist/server/_chunks/index-xh1nbk46.js +1299 -0
- package/dist/server/_chunks/index-xvj80c3a.js +30 -0
- package/dist/server/_chunks/index-xywjg2vc.js +100 -0
- package/dist/server/_chunks/index-y4d02znn.js +66 -0
- package/dist/server/_chunks/index-y7mzvq2q.js +110 -0
- package/dist/server/_chunks/index-ye9hmsvf.js +47 -0
- package/dist/server/_chunks/index-yhxkxghe.js +56 -0
- package/dist/server/_chunks/index-yrjkqtfj.js +86 -0
- package/dist/server/_chunks/index-z88qv16t.js +11 -0
- package/dist/server/_chunks/index-zfrwq472.js +154 -0
- package/dist/server/_chunks/index-zqpqyg8p.js +666 -0
- package/dist/server/_chunks/loader-5en7wpt5.js +80 -0
- package/dist/server/_chunks/modules-t92favpj.js +76 -0
- package/dist/server/_chunks/pipeline-4t9q43ht.js +836 -0
- package/dist/server/_chunks/production-385bw8df.js +55 -0
- package/dist/server/_chunks/proxy-config-60gprphe.js +23 -0
- package/dist/server/_chunks/proxy-gfhmktbk.js +35 -0
- package/dist/server/_chunks/router-xnrva921.js +501 -0
- package/dist/server/_chunks/routes-ht868pdc.js +66 -0
- package/dist/server/_chunks/run-d40d63ag.js +697 -0
- package/dist/server/_chunks/server-2p8fgqq2.js +1839 -0
- package/dist/server/_chunks/tsconfig-defaults-bcn34eqb.js +21 -0
- package/dist/server/_chunks/typegen-dvtcjtaw.js +37 -0
- package/dist/server/api/client-cache.js +14 -0
- package/dist/server/cli/index.js +375 -0
- package/dist/server/cli/start.js +158 -0
- package/dist/server/client/reference.js +16 -0
- package/dist/server/compat/next/cache.js +56 -0
- package/dist/server/compat/next/canonical-url.js +13 -0
- package/dist/server/compat/next/client-cache.js +57 -0
- package/dist/server/compat/next/client-navigation.js +232 -0
- package/dist/server/compat/next/client-only.js +1 -0
- package/dist/server/compat/next/client-script.js +178 -0
- package/dist/server/compat/next/client-server.js +34 -0
- package/dist/server/compat/next/config-headers.js +34 -0
- package/dist/server/compat/next/config-loader.js +25 -0
- package/dist/server/compat/next/config.js +10 -0
- package/dist/server/compat/next/constants.js +18 -0
- package/dist/server/compat/next/custom-server.js +10 -0
- package/dist/server/compat/next/dist/client/components/app-router-headers.js +48 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/revalidate.js +27 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-cache.js +25 -0
- package/dist/server/compat/next/dist/server/web/spec-extension/unstable-no-store.js +25 -0
- package/dist/server/compat/next/dynamic.js +21 -0
- package/dist/server/compat/next/error.js +112 -0
- package/dist/server/compat/next/font/cache.js +16 -0
- package/dist/server/compat/next/font/google.js +3 -0
- package/dist/server/compat/next/font/index.js +1 -0
- package/dist/server/compat/next/font/local.js +24 -0
- package/dist/server/compat/next/font/runtime-client.js +33 -0
- package/dist/server/compat/next/font/runtime.js +43 -0
- package/dist/server/compat/next/font/shared.js +22 -0
- package/dist/server/compat/next/form.js +129 -0
- package/dist/server/compat/next/head.js +10 -0
- package/dist/server/compat/next/headers.js +30 -0
- package/dist/server/compat/next/image/client.js +11 -0
- package/dist/server/compat/next/image/config.js +18 -0
- package/dist/server/compat/next/image/optimizer.js +25 -0
- package/dist/server/compat/next/image/patterns.js +12 -0
- package/dist/server/compat/next/image/props.js +16 -0
- package/dist/server/compat/next/image/shared.js +86 -0
- package/dist/server/compat/next/image/static-metadata.js +32 -0
- package/dist/server/compat/next/image/validate.js +8 -0
- package/dist/server/compat/next/image.js +59 -0
- package/dist/server/compat/next/index.js +1 -0
- package/dist/server/compat/next/legacy-image.js +78 -0
- package/dist/server/compat/next/legacy-request-apis.js +24 -0
- package/dist/server/compat/next/link-transform.js +15 -0
- package/dist/server/compat/next/link.js +14 -0
- package/dist/server/compat/next/navigation.js +191 -0
- package/dist/server/compat/next/offline.js +45 -0
- package/dist/server/compat/next/og.js +8 -0
- package/dist/server/compat/next/preferred-region.js +8 -0
- package/dist/server/compat/next/redirects.js +32 -0
- package/dist/server/compat/next/resource-hints.js +30 -0
- package/dist/server/compat/next/rewrites.js +43 -0
- package/dist/server/compat/next/root-params.js +121 -0
- package/dist/server/compat/next/route-state.js +23 -0
- package/dist/server/compat/next/router.js +103 -0
- package/dist/server/compat/next/script.js +37 -0
- package/dist/server/compat/next/server-only.js +1 -0
- package/dist/server/compat/next/server.js +131 -0
- package/dist/server/compat/next/svgr.js +14 -0
- package/dist/server/compat/next/telemetry.js +10 -0
- package/dist/server/compat/next/usage.js +13 -0
- package/dist/server/compat/next/user-agent.js +12 -0
- package/dist/server/compat/next/web-vitals.js +35 -0
- package/dist/server/compat/react/action-state.js +11 -0
- package/dist/server/compat/react/client-lite.js +83 -0
- package/dist/server/compat/react/client.js +131 -0
- package/dist/server/compat/react/compiler-runtime.js +42 -0
- package/dist/server/compat/react/dom-client.js +106 -0
- package/dist/server/compat/react/dom-react-server.js +37 -0
- package/dist/server/compat/react/dom-server.js +40 -0
- package/dist/server/compat/react/dom.js +52 -0
- package/dist/server/compat/react/hooks-extra.js +12 -0
- package/dist/server/compat/react/internals.js +14 -0
- package/dist/server/compat/react/parity.js +11 -0
- package/dist/server/compat/react/preact.js +113 -0
- package/dist/server/compat/react/react-server.js +133 -0
- package/dist/server/compat/react/router-shim.js +8 -0
- package/dist/server/compat/react/server-component-use.js +14 -0
- package/dist/server/compat/react/server-inserted-html.js +14 -0
- package/dist/server/compat/react/server.js +194 -0
- package/dist/server/compat/react/style-values.js +10 -0
- package/dist/server/compat/react/use.js +10 -0
- package/dist/server/compat/react/view-transition.js +12 -0
- package/dist/server/generation.json +1 -0
- package/package.json +4 -1
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/dev.md +1 -1
- package/reference/getting-started.md +1 -1
- package/reference/rendering.md +4 -4
- package/src/api/dynamic.tsx +86 -4
- package/src/api/server.ts +24 -6
- package/src/cli/adapters/vercel-warm.ts +327 -62
- package/src/cli/adapters/vercel.ts +164 -1054
- package/src/cli/analyze.ts +3 -2
- package/src/cli/build/cache.ts +6 -6
- package/src/cli/build.ts +78 -45
- package/src/cli/index.ts +21 -3
- package/src/cli/serve/immutable.ts +31 -0
- package/src/cli/serve/pipeline.ts +97 -93
- package/src/cli/serve/standalone-worker.ts +8 -0
- package/src/cli/serve/standalone.ts +703 -0
- package/src/cli/start.ts +31 -8
- package/src/client/build.ts +1 -1
- package/src/client/chunk-fold.ts +19 -6
- package/src/client/react-tier.ts +3 -2
- package/src/client/reference-stub.ts +23 -36
- package/src/compat/actions/client-plugin.ts +4 -2
- package/src/compat/actions/config.ts +6 -5
- package/src/compat/actions/extensions.ts +5 -5
- package/src/compat/aliases.ts +8 -1
- package/src/compat/bundler/config.ts +88 -0
- package/src/compat/bundler/optimize-package-imports.ts +86 -26
- package/src/compat/bundler/relay-transform.ts +15 -3
- package/src/compat/bundler/require-context.ts +2 -1
- package/src/compat/bundler/webpack-loaders.ts +3 -2
- package/src/compat/bundler/worker.ts +2 -2
- package/src/compat/cache-control.ts +16 -8
- package/src/compat/css/inline-css.ts +1 -1
- package/src/compat/css/modules.ts +18 -5
- package/src/compat/export/build-complete.ts +1 -1
- package/src/compat/export/emit.ts +4 -4
- package/src/compat/export/standalone.ts +30 -65
- package/src/compat/image-optimizer/optimize.ts +1 -1
- package/src/compat/lifecycle/error-funnel.ts +1 -1
- package/src/compat/lifecycle/instrumentation-client.ts +4 -3
- package/src/compat/lifecycle/instrumentation.ts +117 -24
- package/src/compat/lifecycle/testmode.ts +3 -2
- package/src/compat/metadata-artifacts.ts +1 -1
- package/src/compat/next/config-loader.ts +140 -13
- package/src/compat/next/dynamic.tsx +10 -23
- package/src/compat/next/font/cache.ts +2 -1
- package/src/compat/next/font/runtime.ts +23 -3
- package/src/compat/next/og.ts +3 -3
- package/src/compat/next/usage.ts +3 -2
- package/src/compat/pages/api.ts +83 -14
- package/src/compat/pages/router.ts +30 -14
- package/src/compat/register/bundler.ts +3 -1
- package/src/compat/register/image.ts +1 -1
- package/src/compat/register/middleware.ts +1 -1
- package/src/compat/register/otel.ts +5 -9
- package/src/compat/register/render.ts +3 -1
- package/src/compat/register/use-cache.ts +3 -1
- package/src/compat/release.ts +46 -0
- package/src/compat/segment/serve.ts +1 -1
- package/src/compat/typecheck/check.ts +6 -4
- package/src/compat/validation/validate.ts +10 -7
- package/src/config.ts +76 -9
- package/src/css/assets.ts +213 -0
- package/src/css/build.ts +190 -247
- package/src/dev/client-chunk-store.ts +2 -1
- package/src/dev/restart/client-key.ts +2 -1
- package/src/dev/restart/global-css.ts +2 -1
- package/src/dev/restart/route-bundle-key.ts +2 -1
- package/src/dev/restart/route-facts.ts +2 -1
- package/src/dev/server.ts +34 -14
- package/src/extensions.ts +4 -0
- package/src/out-paths.ts +10 -0
- package/src/render/hooks.ts +13 -0
- package/src/render/renderer.ts +53 -33
- package/src/request/context.ts +9 -0
- package/src/resolve/dynamic.ts +7 -1
- package/src/resolve/engine.ts +2 -12
- package/src/resolve/imports.ts +12 -52
- package/src/resolve/package-json.ts +56 -0
- package/src/resolve/scan-facts.ts +250 -1
- package/src/routing/href.ts +10 -3
- package/src/routing/match.ts +287 -0
- package/src/routing/metadata-files.ts +20 -6
- package/src/routing/proxy-config.ts +137 -0
- package/src/routing/proxy.ts +35 -134
- package/src/routing/routes.ts +22 -281
- package/src/runtime/fingerprint.ts +23 -8
- package/src/runtime/load.ts +170 -0
- package/src/runtime/loader.ts +218 -44
- package/src/runtime/module-cache.ts +15 -1
- package/src/runtime/modules.ts +405 -82
- package/src/runtime/prebundle.ts +101 -0
- package/src/runtime/production.ts +456 -0
- package/src/runtime/release-graph.ts +342 -0
- package/src/runtime/vendor-build.ts +750 -17
- package/src/runtime/vendor.ts +16 -3
- package/src/types.ts +4 -3
- package/src/utils/directive.ts +40 -0
- package/src/utils/fs.ts +95 -4
- package/src/utils/resource-query.ts +12 -0
- package/src/cli/serve/entry.ts +0 -45
package/src/css/build.ts
CHANGED
|
@@ -1,20 +1,46 @@
|
|
|
1
|
-
import { existsSync
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
2
|
+
import { productionRelease } from '../runtime/production'
|
|
2
3
|
import { readFile, rename, writeFile } from 'node:fs/promises'
|
|
3
4
|
import path from 'node:path'
|
|
4
5
|
import type { Plugin } from 'esbuild'
|
|
5
6
|
import { hashedAssetName } from '../utils/asset-hash'
|
|
6
7
|
import { build } from '../utils/esbuild'
|
|
7
|
-
import {
|
|
8
|
+
import { ensureDir, readText } from '../utils/fs'
|
|
8
9
|
import { postcssConfigFile, runPostcss } from './postcss'
|
|
9
10
|
import { extraPageExtensions, getCssExtensions } from '../extensions'
|
|
10
|
-
import { nextCompatEnabled } from '../render/hooks'
|
|
11
11
|
import { resolveImport } from '../resolve/imports'
|
|
12
|
+
import { readSourceSync } from '../resolve/source-text'
|
|
12
13
|
import { createVerboseLogger } from '../utils/verbose'
|
|
13
14
|
import type { ClientReference } from '../client/reference'
|
|
14
15
|
import type { ResolvedConfig } from '../config'
|
|
15
16
|
import type { RouteManifestEntry } from '../types'
|
|
16
17
|
|
|
17
18
|
import type { CssWorkerRequest, CssWorkerResponse } from './worker'
|
|
19
|
+
import {
|
|
20
|
+
cssClassNames,
|
|
21
|
+
cssModuleClassName,
|
|
22
|
+
cssModuleMapping,
|
|
23
|
+
isCssModuleFile,
|
|
24
|
+
recordEmittedAsset,
|
|
25
|
+
} from './assets'
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
assetHref,
|
|
29
|
+
assetPathname,
|
|
30
|
+
clearEmittedAssets,
|
|
31
|
+
cssModuleMapping,
|
|
32
|
+
emitFontCssStylesheet,
|
|
33
|
+
emittedAssetName,
|
|
34
|
+
emittedAssetNames,
|
|
35
|
+
publishEmittedAssets,
|
|
36
|
+
recordEmittedAsset,
|
|
37
|
+
registerCssRuntime,
|
|
38
|
+
routeCssAssetNames,
|
|
39
|
+
routeCssHref,
|
|
40
|
+
withAssetPrefix,
|
|
41
|
+
type AssetHrefConfig,
|
|
42
|
+
} from './assets'
|
|
43
|
+
import { outCachePath } from '../out-paths'
|
|
18
44
|
|
|
19
45
|
interface Pending {
|
|
20
46
|
resolve: () => void
|
|
@@ -89,14 +115,20 @@ export async function stopCssWorker(): Promise<void> {
|
|
|
89
115
|
if (active) await Promise.resolve(active.terminate())
|
|
90
116
|
}
|
|
91
117
|
|
|
118
|
+
// Tailwind skips the out root and caches candidates in it; dev keeps its own subtree.
|
|
119
|
+
function scanOutDir(config: Pick<ResolvedConfig, 'outPath' | 'outRootPath'>, dev: boolean) {
|
|
120
|
+
return dev ? config.outPath : config.outRootPath
|
|
121
|
+
}
|
|
122
|
+
|
|
92
123
|
export async function runPostcssOffThread(
|
|
93
|
-
config: Pick<ResolvedConfig, 'root' | 'outPath'>,
|
|
124
|
+
config: Pick<ResolvedConfig, 'root' | 'outPath' | 'outRootPath'>,
|
|
94
125
|
cssFile: string,
|
|
95
126
|
options: { dev?: boolean },
|
|
96
127
|
from?: string,
|
|
97
128
|
) {
|
|
98
|
-
const { root, outPath: outDir } = config
|
|
99
129
|
const dev = options.dev ?? false
|
|
130
|
+
const { root } = config
|
|
131
|
+
const outDir = scanOutDir(config, dev)
|
|
100
132
|
const sent = send(id => ({ kind: 'process', id, root, dev, outDir, cssFile, from }))
|
|
101
133
|
if (sent) return sent
|
|
102
134
|
return runPostcss(root, cssFile, { dev, outDir }, from)
|
|
@@ -107,7 +139,7 @@ export async function runPostcssOffThread(
|
|
|
107
139
|
* stylesheet, so a cold Tailwind boot overlaps with the rest of dev startup.
|
|
108
140
|
*/
|
|
109
141
|
export function warmCssWorker(
|
|
110
|
-
config: Pick<ResolvedConfig, 'root' | 'outPath'>,
|
|
142
|
+
config: Pick<ResolvedConfig, 'root' | 'outPath' | 'outRootPath'>,
|
|
111
143
|
options: { dev?: boolean } = {},
|
|
112
144
|
) {
|
|
113
145
|
send(id => ({
|
|
@@ -115,7 +147,7 @@ export function warmCssWorker(
|
|
|
115
147
|
id,
|
|
116
148
|
root: config.root,
|
|
117
149
|
dev: options.dev ?? false,
|
|
118
|
-
outDir: config.
|
|
150
|
+
outDir: scanOutDir(config, options.dev ?? false),
|
|
119
151
|
}))?.catch(() => {
|
|
120
152
|
// A broken postcss config surfaces on the real build; warming stays quiet.
|
|
121
153
|
})
|
|
@@ -126,8 +158,6 @@ interface CssBuildOptions {
|
|
|
126
158
|
verbose?: boolean
|
|
127
159
|
}
|
|
128
160
|
|
|
129
|
-
let cssRuntimeRegistered = false
|
|
130
|
-
|
|
131
161
|
export function globalCssSource(config: ResolvedConfig) {
|
|
132
162
|
return globalCssSources(config)[0]
|
|
133
163
|
}
|
|
@@ -135,7 +165,10 @@ export function globalCssSource(config: ResolvedConfig) {
|
|
|
135
165
|
export function globalCssSources(
|
|
136
166
|
config: Pick<ResolvedConfig, 'root' | 'appPath'> & Partial<Pick<ResolvedConfig, 'workspaceRoot'>>,
|
|
137
167
|
) {
|
|
138
|
-
return
|
|
168
|
+
return (
|
|
169
|
+
productionRelease(config)?.globalCss ??
|
|
170
|
+
globalCssSourcesForPaths(config.root, config.appPath, config.workspaceRoot)
|
|
171
|
+
)
|
|
139
172
|
}
|
|
140
173
|
|
|
141
174
|
// The walk below reads and resolves the ROOT LAYOUT'S WHOLE IMPORT GRAPH, and every render asks it
|
|
@@ -213,7 +246,7 @@ function collectGlobalCssSources(
|
|
|
213
246
|
}
|
|
214
247
|
visited.add(resolvedFile)
|
|
215
248
|
|
|
216
|
-
for (const specifier of moduleSpecifiers(
|
|
249
|
+
for (const specifier of moduleSpecifiers(readSourceSync(resolvedFile))) {
|
|
217
250
|
const resolved = resolveImport(root, resolvedFile, specifier, workspaceRoot)
|
|
218
251
|
if (!resolved) continue
|
|
219
252
|
if (isCssFile(resolved)) {
|
|
@@ -233,137 +266,13 @@ function rootLayoutFile(appPath: string, missing?: Set<string>) {
|
|
|
233
266
|
return path.join(appPath, 'layout.tsx')
|
|
234
267
|
}
|
|
235
268
|
|
|
236
|
-
export function globalCssHref(config: ResolvedConfig) {
|
|
237
|
-
return globalCssSources(config).length > 0 ? assetHref(config, 'global.css') : undefined
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
export type AssetHrefConfig = Pick<ResolvedConfig, 'assetPrefix' | 'compat' | 'outPath'>
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Logical build-asset name -> the content-hashed name the build actually emitted
|
|
244
|
-
* (`global.css` -> `global-1f4a9c2b3d5e6f70.css`). A production asset name must
|
|
245
|
-
* carry its content, or the URL cannot honestly be served `immutable`: the same
|
|
246
|
-
* name would answer different bytes after a deploy.
|
|
247
|
-
*
|
|
248
|
-
* Keyed by outPath, never process-global: one process builds several apps (the
|
|
249
|
-
* test suite does it constantly) and their names must not cross. Empty in dev,
|
|
250
|
-
* where names stay flat and every asset is served `no-cache` anyway.
|
|
251
|
-
*/
|
|
252
|
-
const emittedAssets = new Map<string, Map<string, string>>()
|
|
253
|
-
|
|
254
|
-
export function recordEmittedAsset(outPath: string, logical: string, emitted: string): void {
|
|
255
|
-
const names = emittedAssets.get(outPath) ?? new Map<string, string>()
|
|
256
|
-
names.set(logical, emitted)
|
|
257
|
-
emittedAssets.set(outPath, names)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** Re-publish the build's name map at server boot (see BuildManifest.assetNames). */
|
|
261
|
-
export function publishEmittedAssets(
|
|
262
|
-
outPath: string,
|
|
263
|
-
names: Record<string, string> | undefined,
|
|
264
|
-
): void {
|
|
265
|
-
if (!names) return
|
|
266
|
-
for (const [logical, emitted] of Object.entries(names))
|
|
267
|
-
recordEmittedAsset(outPath, logical, emitted)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export function emittedAssetNames(outPath: string): Record<string, string> {
|
|
271
|
-
return Object.fromEntries(emittedAssets.get(outPath) ?? [])
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export function clearEmittedAssets(outPath: string): void {
|
|
275
|
-
emittedAssets.delete(outPath)
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** The file name a logical asset name resolves to. Identity until a build records one. */
|
|
279
|
-
export function emittedAssetName(
|
|
280
|
-
config: Pick<ResolvedConfig, 'outPath'> | undefined,
|
|
281
|
-
name: string,
|
|
282
|
-
): string {
|
|
283
|
-
if (!config?.outPath) return name
|
|
284
|
-
return emittedAssets.get(config.outPath)?.get(name) ?? name
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Where a built asset lives in the URL space. next-compat serves the build output under Next's
|
|
288
|
-
// static path, so a compat app's document references its CSS/JS exactly as Next does; core keeps
|
|
289
|
-
// `/assets/`. Every document-emitted build-asset URL goes through here (and the dev/prod servers
|
|
290
|
-
// accept both spellings), so an emitted href can never name a path the server will not serve —
|
|
291
|
-
// including the content hash the production name carries.
|
|
292
|
-
export function assetPathname(
|
|
293
|
-
config: Pick<ResolvedConfig, 'compat' | 'outPath'> | undefined,
|
|
294
|
-
name: string,
|
|
295
|
-
) {
|
|
296
|
-
const emitted = emittedAssetName(config, name)
|
|
297
|
-
return nextCompatEnabled(config ?? {}) ? `/_next/static/${emitted}` : `/assets/${emitted}`
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export function assetHref(config: AssetHrefConfig | undefined, name: string) {
|
|
301
|
-
return withAssetPrefix(config, assetPathname(config, name))
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// A route's built CSS filenames - the one rule behind the document's links, the
|
|
305
|
-
// inline-CSS path and analyze, so no consumer can disagree about whether a
|
|
306
|
-
// route has CSS. compat cssChunking records split names in cssAssets.
|
|
307
|
-
export function routeCssAssetNames(
|
|
308
|
-
route: Pick<RouteManifestEntry, 'id' | 'cssImports' | 'cssAssets'>,
|
|
309
|
-
): string[] {
|
|
310
|
-
if (route.cssImports.length === 0) return []
|
|
311
|
-
return route.cssAssets?.length ? route.cssAssets : [`${route.id}.css`]
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export function routeCssHref(
|
|
315
|
-
route: RouteManifestEntry,
|
|
316
|
-
config?: AssetHrefConfig,
|
|
317
|
-
): string | string[] | undefined {
|
|
318
|
-
const assets = routeCssAssetNames(route)
|
|
319
|
-
if (assets.length === 0) return undefined
|
|
320
|
-
return assets.map(asset => assetHref(config, asset))
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Put a render's next/font rules in the first stylesheet chunk, matching Next's
|
|
325
|
-
* linked CSS delivery without changing the rest of the route's chunk order.
|
|
326
|
-
*/
|
|
327
|
-
export async function emitFontCssStylesheet(
|
|
328
|
-
config: ResolvedConfig,
|
|
329
|
-
routeId: string,
|
|
330
|
-
fontCss: string,
|
|
331
|
-
baseAsset: string | undefined,
|
|
332
|
-
options: { dev: boolean },
|
|
333
|
-
) {
|
|
334
|
-
const outDir = path.join(config.outPath, options.dev ? 'cache' : 'public', 'assets')
|
|
335
|
-
await ensureDir(outDir)
|
|
336
|
-
const baseFile = baseAsset ? path.join(outDir, baseAsset) : undefined
|
|
337
|
-
const baseCss = baseFile && existsSync(baseFile) ? await readFile(baseFile, 'utf8') : ''
|
|
338
|
-
const contents = [fontCss, baseCss].filter(Boolean).join('\n')
|
|
339
|
-
const logicalName = baseAsset
|
|
340
|
-
? baseAsset.replace(/-[0-9a-f]{16}(?=\.css$)/, '')
|
|
341
|
-
: `${routeId}.css`
|
|
342
|
-
const name = hashedAssetName(logicalName, contents)
|
|
343
|
-
const file = path.join(outDir, name)
|
|
344
|
-
if (!existsSync(file) || (await readFile(file, 'utf8')) !== contents)
|
|
345
|
-
await writeFile(file, contents)
|
|
346
|
-
return name
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Prepend the configured assetPrefix (a CDN origin or path) to an app-absolute
|
|
350
|
-
// asset URL. Link hrefs use basePath instead and must NOT go through here.
|
|
351
|
-
export function withAssetPrefix(
|
|
352
|
-
config: Pick<ResolvedConfig, 'assetPrefix'> | undefined,
|
|
353
|
-
href: string,
|
|
354
|
-
) {
|
|
355
|
-
const prefix = config?.assetPrefix
|
|
356
|
-
if (!prefix) return href
|
|
357
|
-
return `${prefix.replace(/\/$/, '')}${href}`
|
|
358
|
-
}
|
|
359
|
-
|
|
360
269
|
/**
|
|
361
270
|
* Spawn the CSS worker and load the app's postcss config before any stylesheet
|
|
362
271
|
* is asked for, so Tailwind's cold boot overlaps with the rest of startup
|
|
363
272
|
* instead of landing on the first request. No-op without a postcss config.
|
|
364
273
|
*/
|
|
365
274
|
export function warmCssPipeline(
|
|
366
|
-
config: Pick<ResolvedConfig, 'root' | 'outPath'>,
|
|
275
|
+
config: Pick<ResolvedConfig, 'root' | 'outPath' | 'outRootPath'>,
|
|
367
276
|
options: CssBuildOptions = {},
|
|
368
277
|
) {
|
|
369
278
|
if (!hasPostcssConfig(config.root)) return
|
|
@@ -379,8 +288,8 @@ export async function buildGlobalCss(config: ResolvedConfig, options: CssBuildOp
|
|
|
379
288
|
}
|
|
380
289
|
|
|
381
290
|
const outDir = options.dev
|
|
382
|
-
? path.join(config.outPath, '
|
|
383
|
-
: path.join(config.outPath, '
|
|
291
|
+
? path.join(outCachePath(config.outPath), 'assets')
|
|
292
|
+
: path.join(config.outPath, 'static', 'assets')
|
|
384
293
|
const outfile = path.join(outDir, 'global.css')
|
|
385
294
|
await ensureDir(outDir)
|
|
386
295
|
|
|
@@ -394,7 +303,7 @@ export async function buildGlobalCss(config: ResolvedConfig, options: CssBuildOp
|
|
|
394
303
|
await log.step('global css: esbuild bundle', () =>
|
|
395
304
|
build({
|
|
396
305
|
stdin: {
|
|
397
|
-
contents:
|
|
306
|
+
contents: stdinImports(config.root, sources),
|
|
398
307
|
loader: 'css',
|
|
399
308
|
resolveDir: config.root,
|
|
400
309
|
sourcefile: 'global.css',
|
|
@@ -447,8 +356,9 @@ async function fingerprintAsset(
|
|
|
447
356
|
outDir: string,
|
|
448
357
|
assetName: string,
|
|
449
358
|
options: CssBuildOptions,
|
|
359
|
+
file = assetName,
|
|
450
360
|
) {
|
|
451
|
-
const outfile = path.join(outDir,
|
|
361
|
+
const outfile = path.join(outDir, file)
|
|
452
362
|
if (options.dev) return outfile
|
|
453
363
|
const emittedName = hashedAssetName(assetName, await readFile(outfile))
|
|
454
364
|
const emitted = path.join(outDir, emittedName)
|
|
@@ -457,6 +367,19 @@ async function fingerprintAsset(
|
|
|
457
367
|
return emitted
|
|
458
368
|
}
|
|
459
369
|
|
|
370
|
+
// Relative to the build's resolveDir: an absolute specifier would match the public-url plugin's
|
|
371
|
+
// `^/` filter and cost a JS round trip per import.
|
|
372
|
+
function stdinImports(root: string, files: string[]) {
|
|
373
|
+
return files
|
|
374
|
+
.map(file => {
|
|
375
|
+
const relative = path.relative(root, file).split(path.sep).join('/')
|
|
376
|
+
const specifier =
|
|
377
|
+
path.isAbsolute(relative) || relative.startsWith('../') ? relative : `./${relative}`
|
|
378
|
+
return `@import ${JSON.stringify(specifier)};`
|
|
379
|
+
})
|
|
380
|
+
.join('\n')
|
|
381
|
+
}
|
|
382
|
+
|
|
460
383
|
function moduleSpecifiers(source: string) {
|
|
461
384
|
const specifiers: string[] = []
|
|
462
385
|
const pattern = /(?:import|export)\s+(?:[^'";]+?\s+from\s+)?['"]([^'"]+)['"]/g
|
|
@@ -501,38 +424,120 @@ export function prepareRouteCssChunks(routes: Pick<RouteManifestEntry, 'id' | 'c
|
|
|
501
424
|
for (const [id, segments] of plan) routeCssPlan.set(id, segments)
|
|
502
425
|
}
|
|
503
426
|
|
|
427
|
+
interface CssChunk {
|
|
428
|
+
imports: string[]
|
|
429
|
+
name: string
|
|
430
|
+
label: string
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/** A route's stylesheet chunks, one per planned slice, and the split names the route records. */
|
|
434
|
+
function routeCssChunks(route: RouteManifestEntry) {
|
|
435
|
+
if (route.cssImports.length === 0) return undefined
|
|
436
|
+
const segments = routeCssPlan.get(route.id)
|
|
437
|
+
if (segments && segments.length > 1) {
|
|
438
|
+
const cssAssets = segments.map((_, index) => `${route.id}-${index}.css`)
|
|
439
|
+
const chunks: CssChunk[] = segments.map((imports, index) => ({
|
|
440
|
+
imports,
|
|
441
|
+
name: cssAssets[index]!,
|
|
442
|
+
label: `route css ${route.route} #${index + 1}`,
|
|
443
|
+
}))
|
|
444
|
+
return { cssAssets, chunks }
|
|
445
|
+
}
|
|
446
|
+
const chunks: CssChunk[] = [
|
|
447
|
+
{ imports: route.cssImports, name: `${route.id}.css`, label: `route css ${route.route}` },
|
|
448
|
+
]
|
|
449
|
+
return { cssAssets: undefined, chunks }
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function clientReferenceCssChunks(reference: ClientReference): CssChunk[] {
|
|
453
|
+
if (!reference.cssImports || reference.cssImports.length === 0) return []
|
|
454
|
+
return [
|
|
455
|
+
{
|
|
456
|
+
imports: reference.cssImports,
|
|
457
|
+
name: `${reference.id}.css`,
|
|
458
|
+
label: `island css ${reference.id}`,
|
|
459
|
+
},
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
|
|
504
463
|
export async function buildRouteCss(
|
|
505
464
|
config: ResolvedConfig,
|
|
506
465
|
route: RouteManifestEntry,
|
|
507
466
|
options: CssBuildOptions = {},
|
|
508
467
|
) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
for (const [index, segment] of segments.entries()) {
|
|
516
|
-
files.push(
|
|
517
|
-
await bundleCssChunk(
|
|
518
|
-
config,
|
|
519
|
-
segment,
|
|
520
|
-
assetNames[index]!,
|
|
521
|
-
`route css ${route.route} #${index + 1}`,
|
|
522
|
-
options,
|
|
523
|
-
),
|
|
524
|
-
)
|
|
525
|
-
}
|
|
526
|
-
return files
|
|
468
|
+
const css = routeCssChunks(route)
|
|
469
|
+
if (!css) return undefined
|
|
470
|
+
route.cssAssets = css.cssAssets
|
|
471
|
+
const files: string[] = []
|
|
472
|
+
for (const chunk of css.chunks) {
|
|
473
|
+
files.push(await bundleCssChunk(config, chunk.imports, chunk.name, chunk.label, options))
|
|
527
474
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
475
|
+
return css.cssAssets ? files : files[0]
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** Logical names the document stylesheets own; a route chunk spelled the same waits for them. */
|
|
479
|
+
const DOCUMENT_CSS = new Set([
|
|
480
|
+
'global.css',
|
|
481
|
+
'not-found.css',
|
|
482
|
+
'global-not-found.css',
|
|
483
|
+
'global-error.css',
|
|
484
|
+
])
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Every route's and island's stylesheet for a production build, bundled at once rather than one
|
|
488
|
+
* route after another and alongside the document stylesheets. Each route gets a `publish` that the
|
|
489
|
+
* prerender loop calls in route order once the document sheets are done: it records the route's
|
|
490
|
+
* names exactly when, and in the order, a serial pass would, so the manifest is unchanged.
|
|
491
|
+
*/
|
|
492
|
+
export function buildRouteStylesheets(
|
|
493
|
+
config: ResolvedConfig,
|
|
494
|
+
routes: RouteManifestEntry[],
|
|
495
|
+
documentCss: Promise<unknown>,
|
|
496
|
+
options: CssBuildOptions = {},
|
|
497
|
+
) {
|
|
498
|
+
// One bundle per distinct input; an island several routes reach is built once.
|
|
499
|
+
const builds = new Map<string, { file: string; outDir: Promise<string>; emitted?: string }>()
|
|
500
|
+
const taken = new Set<string>()
|
|
501
|
+
const publish = new Map<RouteManifestEntry, () => Promise<void>>()
|
|
502
|
+
for (const route of routes) {
|
|
503
|
+
const css = routeCssChunks(route)
|
|
504
|
+
const chunks = [
|
|
505
|
+
...(css?.chunks ?? []),
|
|
506
|
+
...route.clientReferences.flatMap(clientReferenceCssChunks),
|
|
507
|
+
]
|
|
508
|
+
const own = chunks.map(chunk => {
|
|
509
|
+
const key = `${chunk.name}\0${chunk.imports.join('\0')}`
|
|
510
|
+
let build = builds.get(key)
|
|
511
|
+
if (!build) {
|
|
512
|
+
// Two routes can share an id (`/a-b`, `/a/b`): different input under a taken name gets its own file.
|
|
513
|
+
const file = taken.has(chunk.name) ? `.${builds.size}-${chunk.name}` : chunk.name
|
|
514
|
+
taken.add(chunk.name)
|
|
515
|
+
const write = () => writeCssChunk(config, chunk.imports, file, chunk.label, options)
|
|
516
|
+
const outDir = DOCUMENT_CSS.has(file) ? documentCss.then(write) : write()
|
|
517
|
+
outDir.catch(() => undefined)
|
|
518
|
+
build = { file, outDir }
|
|
519
|
+
builds.set(key, build)
|
|
520
|
+
}
|
|
521
|
+
return { name: chunk.name, build }
|
|
522
|
+
})
|
|
523
|
+
publish.set(route, async () => {
|
|
524
|
+
if (css) route.cssAssets = css.cssAssets
|
|
525
|
+
for (const { name, build } of own) {
|
|
526
|
+
if (build.emitted) recordEmittedAsset(config.outPath, name, build.emitted)
|
|
527
|
+
else {
|
|
528
|
+
const emitted = await fingerprintAsset(
|
|
529
|
+
config,
|
|
530
|
+
await build.outDir,
|
|
531
|
+
name,
|
|
532
|
+
options,
|
|
533
|
+
build.file,
|
|
534
|
+
)
|
|
535
|
+
build.emitted = path.basename(emitted)
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
})
|
|
539
|
+
}
|
|
540
|
+
return publish
|
|
536
541
|
}
|
|
537
542
|
|
|
538
543
|
// The synthetic document conventions are created at render time and never
|
|
@@ -581,14 +586,9 @@ export async function buildClientReferenceCss(
|
|
|
581
586
|
reference: ClientReference,
|
|
582
587
|
options: CssBuildOptions = {},
|
|
583
588
|
) {
|
|
584
|
-
|
|
585
|
-
return
|
|
586
|
-
|
|
587
|
-
reference.cssImports,
|
|
588
|
-
`${reference.id}.css`,
|
|
589
|
-
`island css ${reference.id}`,
|
|
590
|
-
options,
|
|
591
|
-
)
|
|
589
|
+
const [chunk] = clientReferenceCssChunks(reference)
|
|
590
|
+
if (!chunk) return undefined
|
|
591
|
+
return bundleCssChunk(config, chunk.imports, chunk.name, chunk.label, options)
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
async function bundleCssChunk(
|
|
@@ -597,12 +597,24 @@ async function bundleCssChunk(
|
|
|
597
597
|
assetName: string,
|
|
598
598
|
label: string,
|
|
599
599
|
options: CssBuildOptions,
|
|
600
|
+
) {
|
|
601
|
+
const outDir = await writeCssChunk(config, cssImports, assetName, label, options)
|
|
602
|
+
return fingerprintAsset(config, outDir, assetName, options)
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/** Bundle (and postcss) one stylesheet under its logical name; returns its directory. */
|
|
606
|
+
async function writeCssChunk(
|
|
607
|
+
config: ResolvedConfig,
|
|
608
|
+
cssImports: string[],
|
|
609
|
+
assetName: string,
|
|
610
|
+
label: string,
|
|
611
|
+
options: CssBuildOptions,
|
|
600
612
|
) {
|
|
601
613
|
const log = createVerboseLogger(options.verbose ?? false, 'css')
|
|
602
614
|
|
|
603
615
|
const outDir = options.dev
|
|
604
|
-
? path.join(config.outPath, '
|
|
605
|
-
: path.join(config.outPath, '
|
|
616
|
+
? path.join(outCachePath(config.outPath), 'assets')
|
|
617
|
+
: path.join(config.outPath, 'static', 'assets')
|
|
606
618
|
const outfile = path.join(outDir, assetName)
|
|
607
619
|
await ensureDir(outDir)
|
|
608
620
|
|
|
@@ -611,7 +623,7 @@ async function bundleCssChunk(
|
|
|
611
623
|
const postcss = hasPostcssConfig(config.root)
|
|
612
624
|
await build({
|
|
613
625
|
stdin: {
|
|
614
|
-
contents:
|
|
626
|
+
contents: stdinImports(config.root, cssImports),
|
|
615
627
|
loader: 'css',
|
|
616
628
|
resolveDir: config.root,
|
|
617
629
|
sourcefile: assetName,
|
|
@@ -649,8 +661,7 @@ async function bundleCssChunk(
|
|
|
649
661
|
await rewriteTailwindConfigDirectives(outfile, cssImports)
|
|
650
662
|
await log.step(`${label}: postcss`, () => runPostcssOffThread(config, outfile, options))
|
|
651
663
|
}
|
|
652
|
-
|
|
653
|
-
return fingerprintAsset(config, outDir, assetName, options)
|
|
664
|
+
return outDir
|
|
654
665
|
}
|
|
655
666
|
|
|
656
667
|
// A leading slash in a CSS url() is a public URL, not an app-root filesystem
|
|
@@ -667,34 +678,6 @@ function cssPublicUrlPlugin(): Plugin {
|
|
|
667
678
|
}
|
|
668
679
|
}
|
|
669
680
|
|
|
670
|
-
export function registerCssRuntime() {
|
|
671
|
-
if (cssRuntimeRegistered) return
|
|
672
|
-
cssRuntimeRegistered = true
|
|
673
|
-
|
|
674
|
-
Bun.plugin({
|
|
675
|
-
name: 'pnext-css-runtime',
|
|
676
|
-
setup(plugin) {
|
|
677
|
-
plugin.onLoad({ filter: /\.(?:css|scss|sass)$/ }, async ({ path: file }) =>
|
|
678
|
-
isCssModuleFile(file)
|
|
679
|
-
? {
|
|
680
|
-
exports: { default: await cssModuleMapping(file) },
|
|
681
|
-
loader: 'object',
|
|
682
|
-
}
|
|
683
|
-
: {
|
|
684
|
-
contents: 'export default undefined;',
|
|
685
|
-
loader: 'js',
|
|
686
|
-
},
|
|
687
|
-
)
|
|
688
|
-
},
|
|
689
|
-
})
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
// Sass is unsupported (no compiler); its imports still must not break the
|
|
693
|
-
// bundle, so .scss/.sass load as empty modules with module class-name maps.
|
|
694
|
-
function isCssModuleFile(file: string) {
|
|
695
|
-
return /\.module\.(?:css|scss|sass)$/.test(file)
|
|
696
|
-
}
|
|
697
|
-
|
|
698
681
|
export function cssModuleClientPlugin(): Plugin {
|
|
699
682
|
return {
|
|
700
683
|
name: 'pnext-css-modules',
|
|
@@ -822,31 +805,6 @@ function cssModuleBuildPlugin(): Plugin {
|
|
|
822
805
|
}
|
|
823
806
|
}
|
|
824
807
|
|
|
825
|
-
async function cssModuleMapping(file: string) {
|
|
826
|
-
// Compat handles *.module.{scss,sass} (sass compiles + scopes); core keeps
|
|
827
|
-
// plain .module.css. Lazy read: the registry populates at compat bootstrap.
|
|
828
|
-
const compatMapping = getCssExtensions().resolveCssModule(file)
|
|
829
|
-
if (compatMapping) return compatMapping
|
|
830
|
-
const source = await readText(file)
|
|
831
|
-
const classNames = cssClassNames(source)
|
|
832
|
-
|
|
833
|
-
return Object.fromEntries(
|
|
834
|
-
[...classNames].map(className => [className, cssModuleClassName(file, className)]),
|
|
835
|
-
)
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
function cssClassNames(source: string) {
|
|
839
|
-
const classNames = new Set<string>()
|
|
840
|
-
const classPattern = /(^|[^\\])\.(-?[_a-zA-Z][\w-]*)/g
|
|
841
|
-
let match: RegExpExecArray | null
|
|
842
|
-
|
|
843
|
-
while ((match = classPattern.exec(source))) {
|
|
844
|
-
if (match[2]) classNames.add(match[2])
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
return classNames
|
|
848
|
-
}
|
|
849
|
-
|
|
850
808
|
function transformCssModule(source: string, file: string) {
|
|
851
809
|
let css = source
|
|
852
810
|
for (const className of cssClassNames(source)) {
|
|
@@ -899,15 +857,6 @@ function keyframeNames(css: string) {
|
|
|
899
857
|
return names
|
|
900
858
|
}
|
|
901
859
|
|
|
902
|
-
function cssModuleClassName(file: string, className: string) {
|
|
903
|
-
const base = path
|
|
904
|
-
.basename(file)
|
|
905
|
-
.replace(/\.module\.css$/, '')
|
|
906
|
-
.replace(/[^_a-zA-Z0-9]/g, '_')
|
|
907
|
-
const hash = pathHash(cssModuleScopePath(file))
|
|
908
|
-
return `${base}_${className}_${hash}`
|
|
909
|
-
}
|
|
910
|
-
|
|
911
860
|
function rewriteClassSelector(css: string, scopedClassName: string, originalClassName: string) {
|
|
912
861
|
const esbuildNamePattern = new RegExp(
|
|
913
862
|
`\\.${escapeRegex(originalClassName)}(?![-_a-zA-Z0-9])`,
|
|
@@ -916,12 +865,6 @@ function rewriteClassSelector(css: string, scopedClassName: string, originalClas
|
|
|
916
865
|
return css.replace(esbuildNamePattern, `.${scopedClassName}`)
|
|
917
866
|
}
|
|
918
867
|
|
|
919
|
-
function pathHash(file: string) {
|
|
920
|
-
let hash = 5381
|
|
921
|
-
for (const char of file) hash = ((hash << 5) + hash) ^ char.charCodeAt(0)
|
|
922
|
-
return (hash >>> 0).toString(36).slice(0, 5)
|
|
923
|
-
}
|
|
924
|
-
|
|
925
868
|
function escapeRegex(value: string) {
|
|
926
869
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
927
870
|
}
|
|
@@ -9,9 +9,10 @@ import { createHash } from 'node:crypto'
|
|
|
9
9
|
import { link, mkdir, readFile, readdir, rm, stat, unlink } from 'node:fs/promises'
|
|
10
10
|
import path from 'node:path'
|
|
11
11
|
import { listFiles } from '../utils/fs'
|
|
12
|
+
import { outCachePath } from '../out-paths'
|
|
12
13
|
|
|
13
14
|
export function clientChunkStoreDir(outPath: string) {
|
|
14
|
-
return path.join(outPath, '
|
|
15
|
+
return path.join(outCachePath(outPath), 'client-store')
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
function contentHash(data: Buffer) {
|
|
@@ -23,6 +23,7 @@ import type { ResolvedConfig } from '../../config'
|
|
|
23
23
|
import type { RouteManifestEntry } from '../../types'
|
|
24
24
|
import { writeFileAtomic } from '../../utils/fs'
|
|
25
25
|
import { restartCacheEnabled } from './enabled'
|
|
26
|
+
import { outCachePath } from '../../out-paths'
|
|
26
27
|
|
|
27
28
|
/** `[file, mtimeMs, size, contentHash]` — the same record shape the module index uses. */
|
|
28
29
|
type SourceEntry = [string, number, number, string]
|
|
@@ -53,7 +54,7 @@ interface KeyCache {
|
|
|
53
54
|
const caches = new Map<string, KeyCache>()
|
|
54
55
|
|
|
55
56
|
function keyCache(config: ResolvedConfig): KeyCache {
|
|
56
|
-
const file = path.join(config.outPath, '
|
|
57
|
+
const file = path.join(outCachePath(config.outPath), 'client', 'keys.json')
|
|
57
58
|
const existing = caches.get(file)
|
|
58
59
|
if (existing) return existing
|
|
59
60
|
const created: KeyCache = { file, routes: readIndex(file), dirty: false, retries: 0 }
|
|
@@ -17,6 +17,7 @@ import { setGlobalCssSourceStore, type GlobalCssSourceStore } from '../../css/bu
|
|
|
17
17
|
import { traceEnabled } from '../../utils/trace-flags'
|
|
18
18
|
import { restartCacheEnabled } from './enabled'
|
|
19
19
|
import { hash, lazyRecordCacheKey, revalidate, sourceEntries, type SourceEntry } from './record'
|
|
20
|
+
import { outCachePath } from '../../out-paths'
|
|
20
21
|
|
|
21
22
|
interface RecordFile {
|
|
22
23
|
version: number
|
|
@@ -34,7 +35,7 @@ export function installGlobalCssCache(config: ResolvedConfig) {
|
|
|
34
35
|
if (!restartCacheEnabled()) return
|
|
35
36
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
36
37
|
if (process.env.PNEXT_DEV_GLOBAL_CSS_CACHE === '0') return
|
|
37
|
-
const dir = path.join(config.outPath, '
|
|
38
|
+
const dir = path.join(outCachePath(config.outPath), 'global-css')
|
|
38
39
|
setGlobalCssSourceStore(createStore(dir, lazyRecordCacheKey(config, RECORD_VERSION)))
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
type DevGraphSource,
|
|
26
26
|
} from '../../runtime/module-cache'
|
|
27
27
|
import { restartCacheEnabled } from './enabled'
|
|
28
|
+
import { outCachePath } from '../../out-paths'
|
|
28
29
|
|
|
29
30
|
interface RecordFile {
|
|
30
31
|
version: number
|
|
@@ -49,7 +50,7 @@ function enabled() {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
function recordFile(config: ResolvedConfig, routeId: string) {
|
|
52
|
-
return path.join(config.outPath, '
|
|
53
|
+
return path.join(outCachePath(config.outPath), 'route-bundles', `${hash(routeId)}.json`)
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/**
|