From d592d20673c0cc9a7eaa36f8818ff815608bd2e8 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 28 Aug 2022 20:36:42 +0200 Subject: [PATCH] Avoid bundling `next/script` in the server build by default (#40013) We only use `if (child.type === Script)` on the server side to check the element type, that's unnecessary because we can add a special flag for that (`__nextScript` in this PR). This reduces the server bundle by ~13kb if `next/script` is not imported by the user. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples) --- packages/next/client/script.tsx | 2 ++ packages/next/pages/_document.tsx | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/next/client/script.tsx b/packages/next/client/script.tsx index 5162fbe30609..c1adef2378bd 100644 --- a/packages/next/client/script.tsx +++ b/packages/next/client/script.tsx @@ -215,4 +215,6 @@ function Script(props: ScriptProps): JSX.Element | null { return null } +Object.defineProperty(Script, '__nextScript', { value: true }) + export default Script diff --git a/packages/next/pages/_document.tsx b/packages/next/pages/_document.tsx index b0a4a65f38a7..9d601b89bd55 100644 --- a/packages/next/pages/_document.tsx +++ b/packages/next/pages/_document.tsx @@ -10,10 +10,10 @@ import type { DocumentType, NEXT_DATA, } from '../shared/lib/utils' +import type { ScriptProps } from '../client/script' + import { BuildManifest, getPageFiles } from '../server/get-page-files' -import { cleanAmpPath } from '../server/utils' import { htmlEscapeJsonString } from '../server/htmlescape' -import Script, { ScriptProps } from '../client/script' import isError from '../lib/is-error' import { HtmlContext } from '../shared/lib/html-context' @@ -765,7 +765,10 @@ export class Head extends Component { {!hasCanonicalRel && ( )} {/* https://www.ampproject.org/docs/fundamentals/optimize_amp#optimize-the-amp-runtime-loading */} @@ -871,7 +874,8 @@ function handleDocumentScriptLoaderItems( React.Children.forEach(combinedChildren, (child: any) => { if (!child) return - if (child.type === Script) { + // When using the `next/script` component, register it in script loader. + if (child.type?.__nextScript) { if (child.props.strategy === 'beforeInteractive') { scriptLoader.beforeInteractive = ( scriptLoader.beforeInteractive || []