Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use server.useJsonScript instead ssr.inlineScript #6625

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/eleven-otters-cry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@modern-js/runtime': patch
'@modern-js/server-core': patch
---

feat: add server.useJsonScript , for instead ssr.inlineScript
feat: 添加 server.useJsonScript 配置,代替 ssr.inlineScript
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ When the value type is `Object`, the following properties can be configured:
| ---------------- | ------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| mode | `string` | `string` | which defaults to using `renderToString` for rendering. Configure `stream` to enable streaming rendering |
| forceCSR | `boolean` | `false` | which is off by default for forcing CSR rendering. Configure `true` to force CSR by adding `?csr=true` or adding `x-modern-ssr-fallback` header when accessing the page |
| inlineScript | `boolean` | `true` | By default, SSR data is injected into HTML as inline scripts and assigned directly to global variables. Configure `false` to distribute JSON instead of assigning to global variables, this configuration doesn't work in Streaming SSR |
| disablePrerender | `boolean` | `fasle` | To ensure compatibility with the old data request method (`useLoader`), by default, Modern.js performs pre-rendering of components.However, if developers want to reduce one rendering when there is no use of the useLoader API in your project, you can set the configuration `disablePrerender=true` |
| unsafeHeaders | `string[]` | `[]` | For safety reasons, Modern.js does not add excessive content to SSR_DATA. Developers can use this configuration to specify the headers that need to be injected |
| scriptLoading | `defer \| blocking \| module \| async` | `defer` | The configuration is the same as [html.scriptLoading](/configure/app/html/script-loading), supporting SSR injected script set to `async` loading. The priority is `ssr.scriptLoading` > `html.scriptLoading` |
Expand All @@ -42,7 +41,6 @@ export default defineConfig({
ssr: {
forceCSR: true,
mode: 'stream',
inlineScript: false,
unsafeHeaders: ['User-Agent'],
scriptLoading: 'async',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default defineConfig({
| ---------------- | ------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| mode | `string` | `string` | 默认为使用 `renderToString` 渲染。配置为 `stream` 开启流式渲染 |
| forceCSR | `boolean` | `false` | 默认关闭强制 CSR 渲染。配置为 `true` 后,在页面访问时添加 `?csr=true` 或添加请求头 `x-modern-ssr-fallback` 即可强制 CSR |
| inlineScript | `boolean` | `true` | 默认情况下,SSR 的数据会以内联脚本的方式注入到 HTML 中,并且直接赋值给全局变量。配置为 `false` 后,会下发 JSON,而不是赋值给全局变量,Streaming SSR 下,该配置不会生效 |
| disablePrerender | `boolean` | `fasle` | 为了兼容旧数据请求方式 - `useLoader`, 默认情况下 Modern.js 会对组件进行一次预渲染即有两次渲染 |
| unsafeHeaders | `string[]` | `[]` | 为了安全考虑,Modern.js 不会往 SSR_DATA 添加过多的内容。开发者可以通过该配置,对需要注入的 headers 进行配置 |
| scriptLoading | `defer \| blocking \| module \| async` | `defer` | 配置同 [html.scriptLoading](/configure/app/html/script-loading),支持 ssr 注入的 script 设置为 async 加载方式。优先级为 `ssr.scriptLoading` > `html.scriptLoading` |
Expand All @@ -42,7 +41,6 @@ export default defineConfig({
ssr: {
forceCSR: true,
mode: 'stream',
inlineScript: false,
disablePrerender: true,
unsafeHeaders: ['User-Agent'],
scriptLoading: 'async',
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/plugin-runtime/src/core/react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function createRoot(UserApp?: React.ComponentType | null) {
const App = UserApp || getGlobalApp();

if (isBrowser()) {
// we should get data from HTMLElement when set ssr.inlineScript = false
// we should get data from HTMLElement when set server.useJsonScript = true
window._SSR_DATA =
window._SSR_DATA || parsedJSONFromElement(SSR_DATA_JSON_ID);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getGlobalRunner } from '../plugin/runner';
import { createRoot } from '../react';
import type { SSRServerContext } from '../types';
import { CHUNK_CSS_PLACEHOLDER } from './constants';
import { getSSRConfigByEntry, getSSRInlineScript, getSSRMode } from './utils';
import { getSSRConfigByEntry, getSSRMode } from './utils';

export type { RequestHandlerConfig as HandleRequestConfig } from '@modern-js/app-tools';

Expand Down Expand Up @@ -62,7 +62,7 @@ function createSSRContext(
reporter,
} = options;

const { nonce } = config;
const { nonce, useJsonScript } = config;

const { entryName, route } = resource;

Expand Down Expand Up @@ -100,15 +100,14 @@ function createSSRContext(
config.ssr,
config.ssrByEntries,
);

const ssrMode = getSSRMode(ssrConfig);
const inlineScript = getSSRInlineScript(ssrConfig);

const loaderFailureMode =
typeof ssrConfig === 'object' ? ssrConfig.loaderFailureMode : undefined;

return {
nonce,
useJsonScript,
loaderContext,
redirection: {},
htmlModifiers: [],
Expand Down Expand Up @@ -138,7 +137,6 @@ function createSSRContext(
},
reporter,
mode: ssrMode,
inlineScript,
onError,
onTiming,
loaderFailureMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { SSRContainer } from '../../types';
import { SSR_DATA_PLACEHOLDER } from '../constants';
import type { HandleRequestConfig } from '../requestHandler';
import { type BuildHtmlCb, type SSRConfig, buildHtml } from '../shared';
import { attributesToString, getSSRInlineScript, safeReplace } from '../utils';
import { attributesToString, safeReplace } from '../utils';

export type BuildShellAfterTemplateOptions = {
runtimeContext: RuntimeContext;
Expand All @@ -29,6 +29,7 @@ export function buildShellAfterTemplate(
request,
ssrConfig,
nonce: config.nonce,
useJsonScript: config.useJsonScript,
runtimeContext,
renderLevel,
}),
Expand Down Expand Up @@ -62,9 +63,11 @@ function createReplaceSSRData(options: {
runtimeContext: RuntimeContext;
ssrConfig: SSRConfig;
nonce?: string;
useJsonScript?: boolean;
renderLevel: RenderLevel;
}) {
const { runtimeContext, nonce, renderLevel, ssrConfig } = options;
const { runtimeContext, nonce, renderLevel, useJsonScript, ssrConfig } =
options;

const { request, reporter } = runtimeContext.ssrContext!;

Expand Down Expand Up @@ -102,16 +105,11 @@ function createReplaceSSRData(options: {
renderLevel,
};
const attrsStr = attributesToString({ nonce });

const inlineScript = getSSRInlineScript(ssrConfig);
const useInlineScript = inlineScript !== false;
const serializeSSRData = serializeJson(ssrData);

const ssrDataScript = useInlineScript
? `
<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>
`
: `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>`;
const ssrDataScript = useJsonScript
? `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>`
: `<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>`;

return (template: string) =>
safeReplace(template, SSR_DATA_PLACEHOLDER, ssrDataScript);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const renderString: RenderString = async (
chunkSet,
routerContext,
nonce: config.nonce,
useJsonScript: config.useJsonScript,
}),
];

Expand Down
24 changes: 9 additions & 15 deletions packages/runtime/plugin-runtime/src/core/server/string/ssrData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import type { HeadersData } from '@modern-js/runtime-utils/universal/request';
import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID } from '../../constants';
import type { SSRContainer, SSRServerContext } from '../../types';
import type { SSRConfig } from '../shared';
import {
attributesToString,
getSSRInlineScript,
serializeErrors,
} from '../utils';
import { attributesToString, serializeErrors } from '../utils';
import type { ChunkSet, Collector } from './types';

export interface SSRDataCreatorOptions {
Expand All @@ -19,6 +15,7 @@ export interface SSRDataCreatorOptions {
ssrConfig?: SSRConfig;
routerContext?: StaticHandlerContext;
nonce?: string;
useJsonScript?: boolean;
}

export class SSRDataCollector implements Collector {
Expand Down Expand Up @@ -86,22 +83,19 @@ export class SSRDataCollector implements Collector {
ssrData: Record<string, any>,
routerData?: Record<string, any>,
) {
const { nonce, ssrConfig } = this.#options;
const inlineScript = getSSRInlineScript(ssrConfig);

const useInlineScript = inlineScript !== false;
const { nonce, useJsonScript = false } = this.#options;
const serializeSSRData = serializeJson(ssrData);
const attrsStr = attributesToString({ nonce });

let ssrDataScripts = useInlineScript
? `<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>`
: `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>`;
let ssrDataScripts = useJsonScript
? `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>`
: `<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>`;

if (routerData) {
const serializedRouterData = serializeJson(routerData);
ssrDataScripts += useInlineScript
? `\n<script${attrsStr}>window._ROUTER_DATA = ${serializedRouterData}</script>`
: `\n<script type="application/json" id="${ROUTER_DATA_JSON_ID}">${serializedRouterData}</script>`;
ssrDataScripts += useJsonScript
? `\n<script type="application/json" id="${ROUTER_DATA_JSON_ID}">${serializedRouterData}</script>`
: `\n<script${attrsStr}>window._ROUTER_DATA = ${serializedRouterData}</script>`;
}
return ssrDataScripts;
}
Expand Down
8 changes: 0 additions & 8 deletions packages/runtime/plugin-runtime/src/core/server/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,3 @@ export function getSSRMode(ssrConfig?: SSRConfig): 'string' | 'stream' | false {

return ssrConfig?.mode === 'stream' ? 'stream' : 'string';
}

export function getSSRInlineScript(ssrConfig?: SSRConfig): boolean {
if (typeof ssrConfig === 'object') {
return ssrConfig.inlineScript === undefined ? true : ssrConfig.inlineScript;
}

return true;
}
2 changes: 1 addition & 1 deletion packages/runtime/plugin-runtime/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export type SSRServerContext = Pick<
loaderFailureMode?: 'clientRender' | 'errorBoundary';
onError?: (e: unknown) => void;
onTiming?: (name: string, dur: number) => void;
inlineScript?: boolean;
useJsonScript?: boolean;
};

/* 通过 useRuntimeContext 获取的 SSRContext */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ import { serializeErrors } from './utils';
*/
const DeferredDataScripts = (props?: {
nonce?: string;
inlineScript?: boolean;
useJsonScript?: boolean;
context: StaticHandlerContext;
}) => {
const staticContext = props?.context;
const inlineScript = props?.inlineScript;
const useJsonScript = props?.useJsonScript;
const hydratedRef = useRef(false);

useEffect(() => {
Expand Down Expand Up @@ -52,12 +52,14 @@ const DeferredDataScripts = (props?: {
errors: serializeErrors(staticContext.errors),
};

const initialScript0 = inlineScript ? '' : `${serializeJson(_ROUTER_DATA)}`;
const initialScript1 = inlineScript
? [`_ROUTER_DATA = ${serializeJson(_ROUTER_DATA)};`, modernInline].join(
const initialScript0 = useJsonScript
? `${serializeJson(_ROUTER_DATA)}`
: '';
const initialScript1 = useJsonScript
? modernInline
: [`_ROUTER_DATA = ${serializeJson(_ROUTER_DATA)};`, modernInline].join(
'\n',
)
: modernInline;
);
const deferredDataScripts: JSX.Element[] = [];

const initialScripts = Object.entries(activeDeferreds).map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export const routerPlugin = (
const context = useContext(RuntimeReactContext);
const { remixRouter, routerContext, ssrContext } = context;

const { nonce, mode, inlineScript } = ssrContext!;
const { nonce, mode, useJsonScript } = ssrContext!;

const routerWrapper = (
<>
Expand All @@ -182,7 +182,7 @@ export const routerPlugin = (
<DeferredDataScripts
nonce={nonce}
context={routerContext!}
inlineScript={inlineScript}
useJsonScript={useJsonScript}
/>
)}
{mode === 'stream' && JSX_SHELL_STREAM_END_MARK}
Expand Down
1 change: 1 addition & 0 deletions packages/server/core/src/plugins/render/ssrRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,6 @@ function createRequestHandlerConfig(
enableInlineStyles: output?.enableInlineStyles,
crossorigin: html?.crossorigin,
scriptLoading: html?.scriptLoading,
useJsonScript: server?.useJsonScript,
};
}
7 changes: 5 additions & 2 deletions packages/server/core/src/types/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ export interface ServerUserConfig {
ssrByEntries?: SSRByEntries;
baseUrl?: string | string[];
port?: number;
enableMicroFrontendDebug?: boolean;
watchOptions?: WatchOptions;
compiler?: 'babel' | 'typescript';
enableFrameworkExt?: boolean;
/**
* @description use json script tag instead of inline script
* @default false
*/
useJsonScript?: boolean;
}

export type ServerNormalizedConfig = ServerUserConfig;
1 change: 1 addition & 0 deletions packages/server/core/src/types/requestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type RequestHandlerConfig = {
enableInlineScripts?: boolean | RegExp;
ssr?: ServerUserConfig['ssr'];
ssrByEntries?: ServerUserConfig['ssrByEntries'];
useJsonScript?: ServerUserConfig['useJsonScript'];
};

export type LoaderContext = Map<string, any>;
Expand Down
Loading
Loading