From 99469d6517c8a1815c3091f4860dc9a3c24f470a Mon Sep 17 00:00:00 2001 From: clchenliang Date: Tue, 12 Nov 2024 10:26:12 +0800 Subject: [PATCH] feat: support Script with script properties (#6528) --- .changeset/curvy-buttons-march.md | 8 ++++++ .../plugin-runtime/src/document/Script.tsx | 26 +++++++++++++++---- .../plugin-runtime/src/document/cli/index.ts | 11 +++++--- .../plugin-runtime/src/document/constants.ts | 6 +++++ .../app-document/src/sub/Document.tsx | 12 +++++++-- .../app-document/tests/index.test.ts | 14 ++++++++++ 6 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 .changeset/curvy-buttons-march.md diff --git a/.changeset/curvy-buttons-march.md b/.changeset/curvy-buttons-march.md new file mode 100644 index 000000000000..e07bba2554b2 --- /dev/null +++ b/.changeset/curvy-buttons-march.md @@ -0,0 +1,8 @@ +--- +'@modern-js/runtime': patch +'app-docmuent': patch +--- + +feat: support script properties with Script + +feat: 支持 script 原生属性 diff --git a/packages/runtime/plugin-runtime/src/document/Script.tsx b/packages/runtime/plugin-runtime/src/document/Script.tsx index 56b752917de7..9e53dbd0b2cf 100644 --- a/packages/runtime/plugin-runtime/src/document/Script.tsx +++ b/packages/runtime/plugin-runtime/src/document/Script.tsx @@ -1,18 +1,34 @@ -import React from 'react'; +import { renderToString } from 'react-dom/server'; import { + DOCUMENT_SCRIPT_ATTRIBUTES_END, + DOCUMENT_SCRIPT_ATTRIBUTES_START, DOCUMENT_SCRIPT_PLACEHOLDER_END, DOCUMENT_SCRIPT_PLACEHOLDER_START, } from './constants'; -export function Script(props: { content: () => void }) { - const { content } = props; - const contentStr = content.toString(); - const contentIIFE = encodeURIComponent(`(${contentStr})()`); +export function Script(props: DocumentScriptProps) { + const { content, ...rests } = props; + const contentStr = content?.toString(); + const contentIIFE = contentStr?.length + ? encodeURIComponent(`(${contentStr})()`) + : ''; + const scriptProperties = renderToString(', ''), + ); + return ( <> {`${DOCUMENT_SCRIPT_PLACEHOLDER_START}`} + {`${DOCUMENT_SCRIPT_ATTRIBUTES_START}${scriptpPropertiesStr}${DOCUMENT_SCRIPT_ATTRIBUTES_END}`} {`${contentIIFE}`} {`${DOCUMENT_SCRIPT_PLACEHOLDER_END}`} ); } + +// tofix: 之前错误的给了 content 作为 Script 组件的 IIFE 载体,但 content 在 htmlelement.meta 上有含义 +export interface DocumentScriptProps + extends Omit, 'content'> { + content?: () => void; +} diff --git a/packages/runtime/plugin-runtime/src/document/cli/index.ts b/packages/runtime/plugin-runtime/src/document/cli/index.ts index 21ba2cb54d61..3d14c489ae88 100644 --- a/packages/runtime/plugin-runtime/src/document/cli/index.ts +++ b/packages/runtime/plugin-runtime/src/document/cli/index.ts @@ -11,6 +11,7 @@ import React from 'react'; import ReactDomServer from 'react-dom/server'; import { DocumentContext } from '../DocumentContext'; + import { BODY_PARTICALS_SEPARATOR, DOCUMENT_CHUNKSMAP_PLACEHOLDER, @@ -20,6 +21,8 @@ import { DOCUMENT_LINKS_PLACEHOLDER, DOCUMENT_META_PLACEHOLDER, DOCUMENT_SCRIPTS_PLACEHOLDER, + DOCUMENT_SCRIPT_ATTRIBUTES_END, + DOCUMENT_SCRIPT_ATTRIBUTES_START, DOCUMENT_SCRIPT_PLACEHOLDER_END, DOCUMENT_SCRIPT_PLACEHOLDER_START, DOCUMENT_SSRDATASCRIPT_PLACEHOLDER, @@ -240,16 +243,16 @@ export const documentPlugin = (): CliPlugin => ({ html.includes(DOCUMENT_SCRIPT_PLACEHOLDER_START) && html.includes(DOCUMENT_SCRIPT_PLACEHOLDER_END) ) { - const { nonce } = config.security; + const { nonce } = config.security || {}; const nonceAttr = nonce ? `nonce=${nonce}` : ''; html = html.replace( new RegExp( - `${DOCUMENT_SCRIPT_PLACEHOLDER_START}(.*?)${DOCUMENT_SCRIPT_PLACEHOLDER_END}`, + `${DOCUMENT_SCRIPT_PLACEHOLDER_START}${DOCUMENT_SCRIPT_ATTRIBUTES_START}(.*)${DOCUMENT_SCRIPT_ATTRIBUTES_END}(.*?)${DOCUMENT_SCRIPT_PLACEHOLDER_END}`, 'g', ), - (_scriptStr, $1) => - ``, + (_scriptStr, $1, $2) => + ``, ); } // if the Document.tsx has a style, replace to convert it diff --git a/packages/runtime/plugin-runtime/src/document/constants.ts b/packages/runtime/plugin-runtime/src/document/constants.ts index 01aadecb6fdb..f16d670f8510 100644 --- a/packages/runtime/plugin-runtime/src/document/constants.ts +++ b/packages/runtime/plugin-runtime/src/document/constants.ts @@ -37,6 +37,12 @@ export const DOCUMENT_SCRIPT_PLACEHOLDER_START = encodeURIComponent( export const DOCUMENT_SCRIPT_PLACEHOLDER_END = encodeURIComponent( '', ); +export const DOCUMENT_SCRIPT_ATTRIBUTES_START = encodeURIComponent( + '', +); +export const DOCUMENT_SCRIPT_ATTRIBUTES_END = encodeURIComponent( + '', +); export const DOCUMENT_STYLE_PLACEHOLDER_START = encodeURIComponent( '', ); diff --git a/tests/integration/app-document/src/sub/Document.tsx b/tests/integration/app-document/src/sub/Document.tsx index 6226a2c55526..966ae4d841c3 100644 --- a/tests/integration/app-document/src/sub/Document.tsx +++ b/tests/integration/app-document/src/sub/Document.tsx @@ -5,11 +5,11 @@ import { Head, Html, Root, + Script, Style, } from '@modern-js/runtime/document'; // biome-ignore lint/style/useImportType: -import React from 'react'; -import { useContext } from 'react'; +import React, { useContext } from 'react'; export default function Document(): React.ReactElement { // props: Record, @@ -46,6 +46,14 @@ export default function Document(): React.ReactElement { __html: `var a = function() {console.log('sss')}; a();`, }} /> +