@wular/pnext 0.0.4 → 0.0.7
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/README.md +22 -16
- package/bin/pnext +6 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +87 -22
- package/reference/config.md +40 -93
- package/reference/css.md +42 -33
- package/reference/dev.md +26 -33
- package/reference/env.md +18 -20
- package/reference/getting-started.md +132 -0
- package/reference/metadata.md +31 -46
- package/reference/navigation.md +65 -105
- package/reference/performance.md +21 -142
- package/reference/rendering.md +78 -75
- package/reference/routing.md +97 -107
- package/reference/typegen.md +27 -29
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +121 -114
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +52 -53
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +72 -64
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +94 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +802 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +32 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +2022 -1995
- package/src/{api → client}/router/types.ts +98 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +86 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2087 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +87 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +954 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +428 -406
- package/src/styles.d.ts +9 -0
- package/src/types.ts +324 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/reference/overview.md +0 -35
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
// resolution. Namespace, default and mixed-default imports of the specifier are left untouched - Next
|
|
14
14
|
// bails on those too.
|
|
15
15
|
|
|
16
|
-
import { rewriteFacts, type ImportBinding } from '../../resolve/scan-facts'
|
|
17
|
-
import { spliceSource } from '../../
|
|
18
|
-
import { withSniff, type ServerSourceTransform } from '../../extensions'
|
|
19
|
-
import { specifierSniffTokens } from '../../utils/
|
|
16
|
+
import { rewriteFacts, type ImportBinding } from '../../resolve/scan-facts'
|
|
17
|
+
import { spliceSource } from '../../runtime/module-transform'
|
|
18
|
+
import { withSniff, type ServerSourceTransform } from '../../extensions'
|
|
19
|
+
import { specifierSniffTokens } from '../../utils/code'
|
|
20
20
|
|
|
21
21
|
/** A normalized `modularizeImports[specifier]` entry (string-template form). */
|
|
22
22
|
export interface ModularizeRule {
|
|
23
23
|
/** The output-path template, e.g. `'#/design-system/icons/{{ kebabCase member }}'`. */
|
|
24
|
-
transform: string
|
|
24
|
+
transform: string
|
|
25
25
|
/** `true` => named import of the member from the target; otherwise a default import. */
|
|
26
|
-
skipDefaultConversion?: boolean
|
|
26
|
+
skipDefaultConversion?: boolean
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Split an identifier into words on camelCase / digit / `_` / `-` boundaries. */
|
|
@@ -34,7 +34,7 @@ function splitWords(value: string): string[] {
|
|
|
34
34
|
.replace(/[_-]+/g, ' ')
|
|
35
35
|
.trim()
|
|
36
36
|
.split(/\s+/)
|
|
37
|
-
.filter(Boolean)
|
|
37
|
+
.filter(Boolean)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/** Apply a template helper (`kebabCase`/`camelCase`/`lowerCase`/`upperCase`) to a member name. */
|
|
@@ -43,19 +43,19 @@ function applyHelper(helper: string, member: string): string {
|
|
|
43
43
|
case 'kebabCase':
|
|
44
44
|
return splitWords(member)
|
|
45
45
|
.map(word => word.toLowerCase())
|
|
46
|
-
.join('-')
|
|
46
|
+
.join('-')
|
|
47
47
|
case 'camelCase':
|
|
48
48
|
return splitWords(member)
|
|
49
49
|
.map((word, index) =>
|
|
50
50
|
index === 0 ? word.toLowerCase() : word[0]!.toUpperCase() + word.slice(1).toLowerCase(),
|
|
51
51
|
)
|
|
52
|
-
.join('')
|
|
52
|
+
.join('')
|
|
53
53
|
case 'lowerCase':
|
|
54
|
-
return member.toLowerCase()
|
|
54
|
+
return member.toLowerCase()
|
|
55
55
|
case 'upperCase':
|
|
56
|
-
return member.toUpperCase()
|
|
56
|
+
return member.toUpperCase()
|
|
57
57
|
default:
|
|
58
|
-
return member
|
|
58
|
+
return member
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -63,7 +63,7 @@ function applyHelper(helper: string, member: string): string {
|
|
|
63
63
|
function applyTemplate(template: string, member: string): string {
|
|
64
64
|
return template.replace(/\{\{\s*(?:(\w+)\s+)?member\s*\}\}/g, (_full, helper?: string) =>
|
|
65
65
|
helper ? applyHelper(helper, member) : member,
|
|
66
|
-
)
|
|
66
|
+
)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
|
@@ -71,23 +71,26 @@ function applyTemplate(template: string, member: string): string {
|
|
|
71
71
|
* statements. Returns `undefined` (leaving the original import untouched) for a
|
|
72
72
|
* clause the rewrite does not own: no members, or a `type` import.
|
|
73
73
|
*/
|
|
74
|
-
function expandMembers(
|
|
75
|
-
|
|
74
|
+
function expandMembers(
|
|
75
|
+
bindings: readonly ImportBinding[],
|
|
76
|
+
rule: ModularizeRule,
|
|
77
|
+
): string | undefined {
|
|
78
|
+
if (bindings.length === 0) return undefined
|
|
76
79
|
|
|
77
|
-
const statements: string[] = []
|
|
80
|
+
const statements: string[] = []
|
|
78
81
|
for (const binding of bindings) {
|
|
79
|
-
if (binding.type || binding.imported === 'default' || binding.imported === '*') return undefined
|
|
80
|
-
const original = binding.imported
|
|
81
|
-
const local = binding.local
|
|
82
|
-
const target = JSON.stringify(applyTemplate(rule.transform, original))
|
|
82
|
+
if (binding.type || binding.imported === 'default' || binding.imported === '*') return undefined
|
|
83
|
+
const original = binding.imported
|
|
84
|
+
const local = binding.local
|
|
85
|
+
const target = JSON.stringify(applyTemplate(rule.transform, original))
|
|
83
86
|
if (rule.skipDefaultConversion) {
|
|
84
|
-
const named = original === local ? original : `${original} as ${local}
|
|
85
|
-
statements.push(`import { ${named} } from ${target};`)
|
|
87
|
+
const named = original === local ? original : `${original} as ${local}`
|
|
88
|
+
statements.push(`import { ${named} } from ${target};`)
|
|
86
89
|
} else {
|
|
87
|
-
statements.push(`import ${local} from ${target};`)
|
|
90
|
+
statements.push(`import ${local} from ${target};`)
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
|
-
return statements.join(' ')
|
|
93
|
+
return statements.join(' ')
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
/**
|
|
@@ -98,22 +101,22 @@ function expandMembers(bindings: readonly ImportBinding[], rule: ModularizeRule)
|
|
|
98
101
|
export function createModularizeImportsTransform(
|
|
99
102
|
rules: Record<string, ModularizeRule>,
|
|
100
103
|
): ServerSourceTransform {
|
|
101
|
-
if (Object.keys(rules).length === 0) return withSniff([], source => source)
|
|
104
|
+
if (Object.keys(rules).length === 0) return withSniff([], source => source)
|
|
102
105
|
|
|
103
106
|
// Folded onto the module record: one memoized parse instead
|
|
104
107
|
// of a per-rule import regex, and a configured specifier quoted in a string or
|
|
105
108
|
// a comment no longer expands.
|
|
106
109
|
return withSniff(specifierSniffTokens(Object.keys(rules)), (source, file) => {
|
|
107
|
-
if (!source.includes('import')) return source
|
|
108
|
-
const edits: { start: number; end: number; value: string }[] = []
|
|
110
|
+
if (!source.includes('import')) return source
|
|
111
|
+
const edits: { start: number; end: number; value: string }[] = []
|
|
109
112
|
for (const statement of rewriteFacts(file, source).imports) {
|
|
110
|
-
const rule = rules[statement.specifier]
|
|
111
|
-
if (!rule) continue
|
|
112
|
-
const expanded = expandMembers(statement.bindings, rule)
|
|
113
|
+
const rule = rules[statement.specifier]
|
|
114
|
+
if (!rule) continue
|
|
115
|
+
const expanded = expandMembers(statement.bindings, rule)
|
|
113
116
|
if (expanded !== undefined) {
|
|
114
|
-
edits.push({ start: statement.start, end: statement.end, value: expanded })
|
|
117
|
+
edits.push({ start: statement.start, end: statement.end, value: expanded })
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
|
-
return edits.length > 0 ? spliceSource(source, edits) : source
|
|
118
|
-
})
|
|
120
|
+
return edits.length > 0 ? spliceSource(source, edits) : source
|
|
121
|
+
})
|
|
119
122
|
}
|
|
@@ -12,22 +12,22 @@
|
|
|
12
12
|
//
|
|
13
13
|
// Applied to both graphs as a registered source transform.
|
|
14
14
|
|
|
15
|
-
import { rewriteReactProfilerServerSource } from './react-compiler'
|
|
15
|
+
import { rewriteReactProfilerServerSource } from './react-compiler'
|
|
16
16
|
|
|
17
17
|
// A `new URL('<image>', import.meta.url)` call whose first argument is a string
|
|
18
18
|
// literal ending in a static-image extension (optional ?query/#hash) and whose
|
|
19
19
|
// second argument is exactly `import.meta.url`. Non-asset `new URL(...)` calls
|
|
20
20
|
// (e.g. `new URL(request.url)`) never match.
|
|
21
|
-
const IMAGE_EXT = 'png|jpe?g|gif|webp|avif|svg|ico|bmp'
|
|
21
|
+
const IMAGE_EXT = 'png|jpe?g|gif|webp|avif|svg|ico|bmp'
|
|
22
22
|
const newUrlAssetPattern = () =>
|
|
23
23
|
new RegExp(
|
|
24
24
|
`new\\s+URL\\(\\s*(['"])([^'"]+?\\.(?:${IMAGE_EXT})(?:[?#][^'"]*)?)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)`,
|
|
25
25
|
'g',
|
|
26
|
-
)
|
|
26
|
+
)
|
|
27
27
|
|
|
28
28
|
/** Cheap gate: does the source contain any candidate `new URL(...import.meta.url)`? */
|
|
29
29
|
export function sourceHasNewUrlAsset(source: string): boolean {
|
|
30
|
-
return source.includes('import.meta.url') && newUrlAssetPattern().test(source)
|
|
30
|
+
return source.includes('import.meta.url') && newUrlAssetPattern().test(source)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
@@ -36,11 +36,11 @@ export function sourceHasNewUrlAsset(source: string): boolean {
|
|
|
36
36
|
* Returns the source unchanged when there is nothing to rewrite.
|
|
37
37
|
*/
|
|
38
38
|
export function rewriteNewUrlAssetSource(source: string, filePath?: string): string {
|
|
39
|
-
const rewritten = rewriteReactProfilerServerSource(source, filePath)
|
|
39
|
+
const rewritten = rewriteReactProfilerServerSource(source, filePath)
|
|
40
40
|
return rewriteNewUrlAssets(
|
|
41
41
|
rewritten,
|
|
42
42
|
typeof filePath === 'string' && filePath.includes('middleware'),
|
|
43
|
-
)
|
|
43
|
+
)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -49,28 +49,28 @@ export function rewriteNewUrlAssetSource(source: string, filePath?: string): str
|
|
|
49
49
|
* - that one is registered as its own client transform.
|
|
50
50
|
*/
|
|
51
51
|
export function rewriteNewUrlAssetClientSource(source: string): string {
|
|
52
|
-
return rewriteNewUrlAssets(source, false)
|
|
52
|
+
return rewriteNewUrlAssets(source, false)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function rewriteNewUrlAssets(source: string, isMiddleware: boolean): string {
|
|
56
|
-
if (!source.includes('import.meta.url')) return source
|
|
57
|
-
const bindings = new Map<string, string>()
|
|
56
|
+
if (!source.includes('import.meta.url')) return source
|
|
57
|
+
const bindings = new Map<string, string>()
|
|
58
58
|
const replaced = source.replace(newUrlAssetPattern(), (_match, _quote, spec: string) => {
|
|
59
|
-
let binding = bindings.get(spec)
|
|
59
|
+
let binding = bindings.get(spec)
|
|
60
60
|
if (!binding) {
|
|
61
|
-
binding = `__pnext_new_url_${bindings.size}
|
|
62
|
-
bindings.set(spec, binding)
|
|
61
|
+
binding = `__pnext_new_url_${bindings.size}`
|
|
62
|
+
bindings.set(spec, binding)
|
|
63
63
|
}
|
|
64
64
|
if (isMiddleware) {
|
|
65
|
-
return `('blob:' + ${binding}.src.split('/').pop())
|
|
65
|
+
return `('blob:' + ${binding}.src.split('/').pop())`
|
|
66
66
|
}
|
|
67
|
-
return `(${binding}.src)
|
|
68
|
-
})
|
|
69
|
-
if (bindings.size === 0) return source
|
|
67
|
+
return `(${binding}.src)`
|
|
68
|
+
})
|
|
69
|
+
if (bindings.size === 0) return source
|
|
70
70
|
const imports = [...bindings]
|
|
71
71
|
.map(([spec, binding]) => `import ${binding} from ${JSON.stringify(spec)};`)
|
|
72
|
-
.join('\n')
|
|
73
|
-
return injectAfterDirectives(replaced, imports)
|
|
72
|
+
.join('\n')
|
|
73
|
+
return injectAfterDirectives(replaced, imports)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
// Insert injected imports after any leading directive prologue ('use client' /
|
|
@@ -78,10 +78,8 @@ function rewriteNewUrlAssets(source: string, isMiddleware: boolean): string {
|
|
|
78
78
|
// `'use client'` stays the first statement (otherwise the directive is demoted
|
|
79
79
|
// to a plain expression and the module is treated as server-only).
|
|
80
80
|
function injectAfterDirectives(source: string, injection: string): string {
|
|
81
|
-
const prologue =
|
|
82
|
-
source
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return `${source.slice(0, index)}${injection}\n${source.slice(index)}`;
|
|
81
|
+
const prologue =
|
|
82
|
+
/^(\uFEFF?(?:#![^\n]*\n)?(?:[ \t]*(['"])use [\w-]+\2[ \t]*;?[ \t]*(?:\r?\n|$))*)/.exec(source)
|
|
83
|
+
const index = prologue ? prologue[0].length : 0
|
|
84
|
+
return `${source.slice(0, index)}${injection}\n${source.slice(index)}`
|
|
86
85
|
}
|
|
87
|
-
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
// the entry must be re-exports and nothing else - no declarations, no side effects - or the package
|
|
13
13
|
// is left alone, which is why an over-broad list cannot produce wrong code.
|
|
14
14
|
|
|
15
|
-
import path from 'node:path'
|
|
16
|
-
import { readFileSync } from 'node:fs'
|
|
15
|
+
import path from 'node:path'
|
|
16
|
+
import { readFileSync } from 'node:fs'
|
|
17
17
|
// Lazy: the oxc-parser native binding costs ~12.6 MB RSS; load it only when a parse happens.
|
|
18
18
|
const parseSync: typeof import('oxc-parser').parseSync = (...args) =>
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
20
|
-
loadNative(() => require('oxc-parser') as typeof import('oxc-parser')).parseSync(...args)
|
|
21
|
-
import { loadNative } from '../../utils/native-require'
|
|
22
|
-
import { rewriteFacts, type ImportBinding } from '../../resolve/scan-facts'
|
|
23
|
-
import { spliceSource } from '../../
|
|
24
|
-
import { resolvePackageSpecifier, resolveVendorPackageSpecifier } from '../../resolve/imports'
|
|
25
|
-
import { withSniff, type ServerSourceTransform } from '../../extensions'
|
|
26
|
-
import { specifierSniffTokens } from '../../utils/
|
|
20
|
+
loadNative(() => require('oxc-parser') as typeof import('oxc-parser')).parseSync(...args)
|
|
21
|
+
import { loadNative } from '../../utils/native-require'
|
|
22
|
+
import { rewriteFacts, type ImportBinding } from '../../resolve/scan-facts'
|
|
23
|
+
import { spliceSource } from '../../runtime/module-transform'
|
|
24
|
+
import { resolvePackageSpecifier, resolveVendorPackageSpecifier } from '../../resolve/imports'
|
|
25
|
+
import { withSniff, type ServerSourceTransform } from '../../extensions'
|
|
26
|
+
import { specifierSniffTokens } from '../../utils/code'
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Next's default `optimizePackageImports` set - the barrels big enough that compiling the entry is the
|
|
@@ -55,29 +55,29 @@ const DEFAULT_OPTIMIZED_PACKAGES = [
|
|
|
55
55
|
'react-use',
|
|
56
56
|
'recharts',
|
|
57
57
|
'rxjs',
|
|
58
|
-
]
|
|
58
|
+
]
|
|
59
59
|
|
|
60
60
|
export function optimizedPackageSet(configured: readonly string[]): string[] {
|
|
61
61
|
// Rewriting a barrel changes what the vendor pipeline compiles, so it is also
|
|
62
62
|
// what a slow or wrong artifact has to be bisected against — and how the
|
|
63
63
|
// bench A/Bs it (same seam shape as `PNEXT_VENDOR_GROUP=0`).
|
|
64
64
|
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
|
65
|
-
if (process.env.PNEXT_OPTIMIZE_PACKAGE_IMPORTS === '0') return []
|
|
66
|
-
return [...new Set([...DEFAULT_OPTIMIZED_PACKAGES, ...configured])]
|
|
65
|
+
if (process.env.PNEXT_OPTIMIZE_PACKAGE_IMPORTS === '0') return []
|
|
66
|
+
return [...new Set([...DEFAULT_OPTIMIZED_PACKAGES, ...configured])]
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/** Where one exported name really lives: the barrel's re-export target. */
|
|
70
70
|
interface BarrelMember {
|
|
71
71
|
/** The leaf module, relative to the barrel entry. */
|
|
72
|
-
source: string
|
|
72
|
+
source: string
|
|
73
73
|
/** The name to take from it: `default`, `*`, or an export name. */
|
|
74
|
-
imported: string
|
|
74
|
+
imported: string
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
/** The exported names a pure re-export barrel publishes, and their leaves. */
|
|
78
|
-
type BarrelMap = ReadonlyMap<string, BarrelMember
|
|
78
|
+
type BarrelMap = ReadonlyMap<string, BarrelMember>
|
|
79
79
|
|
|
80
|
-
const barrelMaps = new Map<string, BarrelMap | undefined>()
|
|
80
|
+
const barrelMaps = new Map<string, BarrelMap | undefined>()
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* The leaf map of a barrel entry, or undefined when the entry is not a pure
|
|
@@ -85,67 +85,67 @@ const barrelMaps = new Map<string, BarrelMap | undefined>();
|
|
|
85
85
|
* however many modules import it.
|
|
86
86
|
*/
|
|
87
87
|
function barrelMap(entry: string): BarrelMap | undefined {
|
|
88
|
-
if (barrelMaps.has(entry)) return barrelMaps.get(entry)
|
|
89
|
-
let map: BarrelMap | undefined
|
|
88
|
+
if (barrelMaps.has(entry)) return barrelMaps.get(entry)
|
|
89
|
+
let map: BarrelMap | undefined
|
|
90
90
|
try {
|
|
91
|
-
map = parseBarrel(entry)
|
|
91
|
+
map = parseBarrel(entry)
|
|
92
92
|
} catch {
|
|
93
|
-
map = undefined
|
|
93
|
+
map = undefined
|
|
94
94
|
}
|
|
95
|
-
barrelMaps.set(entry, map)
|
|
96
|
-
return map
|
|
95
|
+
barrelMaps.set(entry, map)
|
|
96
|
+
return map
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
function parseBarrel(entry: string): BarrelMap | undefined {
|
|
100
|
-
const source = readFileSync(entry, 'utf8')
|
|
101
|
-
const parsed = parseSync(entry, source, { lang: 'js' })
|
|
102
|
-
if (parsed.errors.length > 0) return undefined
|
|
100
|
+
const source = readFileSync(entry, 'utf8')
|
|
101
|
+
const parsed = parseSync(entry, source, { lang: 'js' })
|
|
102
|
+
if (parsed.errors.length > 0) return undefined
|
|
103
103
|
|
|
104
104
|
// A namespace re-export (`import * as icons from './icons/index.js'; export
|
|
105
105
|
// { icons }`) is two statements; the local binding is only allowed to leave
|
|
106
106
|
// the module through that export, or the barrel is doing something else.
|
|
107
|
-
const namespaces = new Map<string, string>()
|
|
107
|
+
const namespaces = new Map<string, string>()
|
|
108
108
|
for (const node of parsed.program.body) {
|
|
109
109
|
if (node.type === 'ImportDeclaration') {
|
|
110
|
-
const specifiers = node.specifiers ?? []
|
|
111
|
-
const only = specifiers[0]
|
|
112
|
-
if (specifiers.length !== 1 || only?.type !== 'ImportNamespaceSpecifier') return undefined
|
|
113
|
-
namespaces.set(only.local.name, node.source.value)
|
|
114
|
-
continue
|
|
110
|
+
const specifiers = node.specifiers ?? []
|
|
111
|
+
const only = specifiers[0]
|
|
112
|
+
if (specifiers.length !== 1 || only?.type !== 'ImportNamespaceSpecifier') return undefined
|
|
113
|
+
namespaces.set(only.local.name, node.source.value)
|
|
114
|
+
continue
|
|
115
115
|
}
|
|
116
116
|
if (node.type === 'ExportNamedDeclaration') {
|
|
117
117
|
// `export const x = …` is a definition, not a re-export: not a barrel.
|
|
118
|
-
if (node.declaration) return undefined
|
|
119
|
-
continue
|
|
118
|
+
if (node.declaration) return undefined
|
|
119
|
+
continue
|
|
120
120
|
}
|
|
121
121
|
// `export * from` hides its names in the target, so a demanded name cannot
|
|
122
122
|
// be attributed to a leaf; anything else is code with a side effect.
|
|
123
|
-
return undefined
|
|
123
|
+
return undefined
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
const members = new Map<string, BarrelMember>()
|
|
126
|
+
const members = new Map<string, BarrelMember>()
|
|
127
127
|
for (const statement of parsed.module.staticExports) {
|
|
128
128
|
for (const record of statement.entries) {
|
|
129
|
-
if (record.isType) continue
|
|
130
|
-
const exported = record.exportName.name
|
|
131
|
-
if (!exported) return undefined
|
|
132
|
-
const request = record.moduleRequest?.value
|
|
129
|
+
if (record.isType) continue
|
|
130
|
+
const exported = record.exportName.name
|
|
131
|
+
if (!exported) return undefined
|
|
132
|
+
const request = record.moduleRequest?.value
|
|
133
133
|
if (request) {
|
|
134
|
-
const kind: string = record.importName.kind
|
|
135
|
-
if (kind === 'AllButDefault') return undefined
|
|
134
|
+
const kind: string = record.importName.kind
|
|
135
|
+
if (kind === 'AllButDefault') return undefined
|
|
136
136
|
const imported =
|
|
137
|
-
kind === 'Default' ? 'default' : kind === 'All' ? '*' : record.importName.name
|
|
138
|
-
if (!imported) return undefined
|
|
139
|
-
members.set(exported, { source: request, imported })
|
|
140
|
-
continue
|
|
137
|
+
kind === 'Default' ? 'default' : kind === 'All' ? '*' : record.importName.name
|
|
138
|
+
if (!imported) return undefined
|
|
139
|
+
members.set(exported, { source: request, imported })
|
|
140
|
+
continue
|
|
141
141
|
}
|
|
142
|
-
const local = record.localName.name
|
|
143
|
-
const namespace = local === null ? undefined : namespaces.get(local)
|
|
144
|
-
if (!namespace) return undefined
|
|
145
|
-
members.set(exported, { source: namespace, imported: '*' })
|
|
142
|
+
const local = record.localName.name
|
|
143
|
+
const namespace = local === null ? undefined : namespaces.get(local)
|
|
144
|
+
if (!namespace) return undefined
|
|
145
|
+
members.set(exported, { source: namespace, imported: '*' })
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
return members.size > 0 ? members : undefined
|
|
148
|
+
return members.size > 0 ? members : undefined
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
@@ -154,11 +154,11 @@ function parseBarrel(entry: string): BarrelMap | undefined {
|
|
|
154
154
|
* catalogue per layer, and one rewritten source is compiled for both.
|
|
155
155
|
*/
|
|
156
156
|
function barrelEntry(root: string, file: string, specifier: string) {
|
|
157
|
-
const client = resolveVendorPackageSpecifier(root, file, specifier, CLIENT_CONDITIONS)
|
|
158
|
-
if (!client) return undefined
|
|
157
|
+
const client = resolveVendorPackageSpecifier(root, file, specifier, CLIENT_CONDITIONS)
|
|
158
|
+
if (!client) return undefined
|
|
159
159
|
return resolveVendorPackageSpecifier(root, file, specifier, SERVER_CONDITIONS) === client
|
|
160
160
|
? client
|
|
161
|
-
: undefined
|
|
161
|
+
: undefined
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
/**
|
|
@@ -169,48 +169,51 @@ function barrelEntry(root: string, file: string, specifier: string) {
|
|
|
169
169
|
* because one rewritten source is compiled for both.
|
|
170
170
|
*/
|
|
171
171
|
function leafSpecifier(root: string, entry: string, member: BarrelMember): string | undefined {
|
|
172
|
-
const key = `${entry}\0${member.source}
|
|
173
|
-
if (leafSpecifiers.has(key)) return leafSpecifiers.get(key)
|
|
174
|
-
const specifier = resolveLeafSpecifier(root, entry, member)
|
|
175
|
-
leafSpecifiers.set(key, specifier)
|
|
176
|
-
return specifier
|
|
172
|
+
const key = `${entry}\0${member.source}`
|
|
173
|
+
if (leafSpecifiers.has(key)) return leafSpecifiers.get(key)
|
|
174
|
+
const specifier = resolveLeafSpecifier(root, entry, member)
|
|
175
|
+
leafSpecifiers.set(key, specifier)
|
|
176
|
+
return specifier
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
const leafSpecifiers = new Map<string, string | undefined>()
|
|
179
|
+
const leafSpecifiers = new Map<string, string | undefined>()
|
|
180
180
|
|
|
181
|
-
const CLIENT_CONDITIONS = ['module', 'import']
|
|
182
|
-
const SERVER_CONDITIONS = ['react-server', 'node', 'module', 'import']
|
|
181
|
+
const CLIENT_CONDITIONS = ['module', 'import']
|
|
182
|
+
const SERVER_CONDITIONS = ['react-server', 'node', 'module', 'import']
|
|
183
183
|
|
|
184
184
|
function resolveLeafSpecifier(root: string, entry: string, member: BarrelMember) {
|
|
185
|
-
if (!member.source.startsWith('.')) return undefined
|
|
186
|
-
const file = path.resolve(path.dirname(entry), member.source)
|
|
187
|
-
const packageDir = packageDirOf(entry)
|
|
188
|
-
if (!packageDir) return undefined
|
|
189
|
-
const name = packageNameOfDir(packageDir)
|
|
190
|
-
const relative = path.relative(packageDir, file)
|
|
191
|
-
if (!name || relative.startsWith('..') || path.isAbsolute(relative)) return undefined
|
|
192
|
-
const specifier = `${name}/${relative.split(path.sep).join('/')}
|
|
185
|
+
if (!member.source.startsWith('.')) return undefined
|
|
186
|
+
const file = path.resolve(path.dirname(entry), member.source)
|
|
187
|
+
const packageDir = packageDirOf(entry)
|
|
188
|
+
if (!packageDir) return undefined
|
|
189
|
+
const name = packageNameOfDir(packageDir)
|
|
190
|
+
const relative = path.relative(packageDir, file)
|
|
191
|
+
if (!name || relative.startsWith('..') || path.isAbsolute(relative)) return undefined
|
|
192
|
+
const specifier = `${name}/${relative.split(path.sep).join('/')}`
|
|
193
193
|
for (const conditions of [CLIENT_CONDITIONS, SERVER_CONDITIONS]) {
|
|
194
|
-
if (resolvePackageSpecifier(root, entry, specifier, conditions) !== file) return undefined
|
|
194
|
+
if (resolvePackageSpecifier(root, entry, specifier, conditions) !== file) return undefined
|
|
195
195
|
}
|
|
196
|
-
return specifier
|
|
196
|
+
return specifier
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/** The installed package a barrel entry belongs to, by its `node_modules` segment. */
|
|
200
200
|
function packageDirOf(entry: string) {
|
|
201
|
-
const marker = `${path.sep}node_modules${path.sep}
|
|
202
|
-
const index = entry.lastIndexOf(marker)
|
|
203
|
-
if (index < 0) return undefined
|
|
204
|
-
const rest = entry.slice(index + marker.length).split(path.sep)
|
|
205
|
-
const segments = rest[0]?.startsWith('@') ? rest.slice(0, 2) : rest.slice(0, 1)
|
|
206
|
-
return path.join(entry.slice(0, index + marker.length), ...segments)
|
|
201
|
+
const marker = `${path.sep}node_modules${path.sep}`
|
|
202
|
+
const index = entry.lastIndexOf(marker)
|
|
203
|
+
if (index < 0) return undefined
|
|
204
|
+
const rest = entry.slice(index + marker.length).split(path.sep)
|
|
205
|
+
const segments = rest[0]?.startsWith('@') ? rest.slice(0, 2) : rest.slice(0, 1)
|
|
206
|
+
return path.join(entry.slice(0, index + marker.length), ...segments)
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
function packageNameOfDir(packageDir: string) {
|
|
210
|
-
const marker = `${path.sep}node_modules${path.sep}
|
|
211
|
-
const index = packageDir.lastIndexOf(marker)
|
|
212
|
-
if (index < 0) return undefined
|
|
213
|
-
return packageDir
|
|
210
|
+
const marker = `${path.sep}node_modules${path.sep}`
|
|
211
|
+
const index = packageDir.lastIndexOf(marker)
|
|
212
|
+
if (index < 0) return undefined
|
|
213
|
+
return packageDir
|
|
214
|
+
.slice(index + marker.length)
|
|
215
|
+
.split(path.sep)
|
|
216
|
+
.join('/')
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
/**
|
|
@@ -224,28 +227,29 @@ function expandBarrelImport(
|
|
|
224
227
|
root: string,
|
|
225
228
|
entry: string,
|
|
226
229
|
): string | undefined {
|
|
227
|
-
if (bindings.length === 0) return undefined
|
|
228
|
-
const statements: string[] = []
|
|
230
|
+
if (bindings.length === 0) return undefined
|
|
231
|
+
const statements: string[] = []
|
|
229
232
|
for (const binding of bindings) {
|
|
230
233
|
// A barrel publishes its types off the same entry, so `{ Icon, type Props }`
|
|
231
234
|
// is the common shape. The type binding is erased before anything resolves
|
|
232
235
|
// it, so dropping it is what lets the value bindings split at all.
|
|
233
|
-
if (binding.type) continue
|
|
234
|
-
if (binding.imported === 'default' || binding.imported === '*') return undefined
|
|
235
|
-
const member = map.get(binding.imported)
|
|
236
|
-
if (!member) return undefined
|
|
237
|
-
const specifier = leafSpecifier(root, entry, member)
|
|
238
|
-
if (!specifier) return undefined
|
|
239
|
-
const target = JSON.stringify(specifier)
|
|
240
|
-
if (member.imported === 'default') statements.push(`import ${binding.local} from ${target};`)
|
|
241
|
-
else if (member.imported === '*')
|
|
236
|
+
if (binding.type) continue
|
|
237
|
+
if (binding.imported === 'default' || binding.imported === '*') return undefined
|
|
238
|
+
const member = map.get(binding.imported)
|
|
239
|
+
if (!member) return undefined
|
|
240
|
+
const specifier = leafSpecifier(root, entry, member)
|
|
241
|
+
if (!specifier) return undefined
|
|
242
|
+
const target = JSON.stringify(specifier)
|
|
243
|
+
if (member.imported === 'default') statements.push(`import ${binding.local} from ${target};`)
|
|
244
|
+
else if (member.imported === '*')
|
|
245
|
+
statements.push(`import * as ${binding.local} from ${target};`)
|
|
242
246
|
else {
|
|
243
247
|
const named =
|
|
244
|
-
member.imported === binding.local ? binding.local : `${member.imported} as ${binding.local}
|
|
245
|
-
statements.push(`import { ${named} } from ${target};`)
|
|
248
|
+
member.imported === binding.local ? binding.local : `${member.imported} as ${binding.local}`
|
|
249
|
+
statements.push(`import { ${named} } from ${target};`)
|
|
246
250
|
}
|
|
247
251
|
}
|
|
248
|
-
return statements.length > 0 ? statements.join(' ') : undefined
|
|
252
|
+
return statements.length > 0 ? statements.join(' ') : undefined
|
|
249
253
|
}
|
|
250
254
|
|
|
251
255
|
/**
|
|
@@ -257,21 +261,21 @@ export function createOptimizePackageImportsTransform(
|
|
|
257
261
|
packages: readonly string[],
|
|
258
262
|
root: string,
|
|
259
263
|
): ServerSourceTransform {
|
|
260
|
-
if (packages.length === 0) return withSniff([], source => source)
|
|
261
|
-
const optimized = new Set(packages)
|
|
264
|
+
if (packages.length === 0) return withSniff([], source => source)
|
|
265
|
+
const optimized = new Set(packages)
|
|
262
266
|
return withSniff(specifierSniffTokens(packages), (source, file) => {
|
|
263
|
-
if (!source.includes('import')) return source
|
|
264
|
-
const edits: { start: number; end: number; value: string }[] = []
|
|
267
|
+
if (!source.includes('import')) return source
|
|
268
|
+
const edits: { start: number; end: number; value: string }[] = []
|
|
265
269
|
for (const statement of rewriteFacts(file, source).imports) {
|
|
266
|
-
if (!optimized.has(statement.specifier)) continue
|
|
267
|
-
const entry = barrelEntry(root, file, statement.specifier)
|
|
268
|
-
const map = entry && barrelMap(entry)
|
|
269
|
-
if (!map || !entry) continue
|
|
270
|
-
const expanded = expandBarrelImport(statement.bindings, map, root, entry)
|
|
270
|
+
if (!optimized.has(statement.specifier)) continue
|
|
271
|
+
const entry = barrelEntry(root, file, statement.specifier)
|
|
272
|
+
const map = entry && barrelMap(entry)
|
|
273
|
+
if (!map || !entry) continue
|
|
274
|
+
const expanded = expandBarrelImport(statement.bindings, map, root, entry)
|
|
271
275
|
if (expanded !== undefined) {
|
|
272
|
-
edits.push({ start: statement.start, end: statement.end, value: expanded })
|
|
276
|
+
edits.push({ start: statement.start, end: statement.end, value: expanded })
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
|
-
return edits.length > 0 ? spliceSource(source, edits) : source
|
|
276
|
-
})
|
|
279
|
+
return edits.length > 0 ? spliceSource(source, edits) : source
|
|
280
|
+
})
|
|
277
281
|
}
|