From aa212d2a1554931edf298a6464d40428fc6e07fb Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Mon, 1 Apr 2024 11:06:34 +0800 Subject: [PATCH 1/3] fix: optimize runtime code when dataLoader is not defined --- .changeset/wicked-points-fetch.md | 6 ++++++ packages/ice/src/createService.ts | 5 +++-- packages/ice/src/utils/runtimeEnv.ts | 21 +++++++++++++++++---- packages/runtime/src/appData.ts | 18 ++++++++++-------- packages/runtime/src/routes.tsx | 10 ++++++---- packages/runtime/src/runClientApp.tsx | 6 ++++-- 6 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 .changeset/wicked-points-fetch.md diff --git a/.changeset/wicked-points-fetch.md b/.changeset/wicked-points-fetch.md new file mode 100644 index 0000000000..481c6e0fa4 --- /dev/null +++ b/.changeset/wicked-points-fetch.md @@ -0,0 +1,6 @@ +--- +'@ice/runtime': patch +'@ice/app': patch +--- + +feat: remove runtime code when loaders is not export diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index f37ee2bad6..1da0e66db9 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -295,7 +295,8 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt dataCache.set('routes', JSON.stringify(routesInfo)); dataCache.set('hasExportAppData', hasExportAppData ? 'true' : ''); - const hasDataLoader = Boolean(userConfig.dataLoader) && (hasExportAppData || Boolean(routesInfo.loaders)); + const loaderExports = hasExportAppData || Boolean(routesInfo.loaders); + const hasDataLoader = Boolean(userConfig.dataLoader) && loaderExports; // Render exports files if route component export dataLoader / pageConfig. renderExportsTemplate( { @@ -379,7 +380,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const appConfig: AppConfig = (await getAppConfig()).default; - updateRuntimeEnv(appConfig, { disableRouter }); + updateRuntimeEnv(appConfig, { disableRouter, dataLoader: loaderExports }); return { run: async () => { diff --git a/packages/ice/src/utils/runtimeEnv.ts b/packages/ice/src/utils/runtimeEnv.ts index 74f1eb3373..a3dd17cb6e 100644 --- a/packages/ice/src/utils/runtimeEnv.ts +++ b/packages/ice/src/utils/runtimeEnv.ts @@ -10,6 +10,7 @@ export interface Envs { } interface EnvOptions { disableRouter: boolean; + dataLoader: boolean; } const expandedEnvs = {}; @@ -50,6 +51,8 @@ export async function setEnv( process.env.ICE_CORE_ROUTER = 'true'; process.env.ICE_CORE_ERROR_BOUNDARY = 'true'; process.env.ICE_CORE_INITIAL_DATA = 'true'; + // Set to false for compatibility with the old version. + process.env.ICE_CORE_REMOVE_DATA_LOADER = 'false'; // set ssr and ssg env to false, for remove dead code in CSR. process.env.ICE_CORE_SSG = 'false'; @@ -57,17 +60,27 @@ export async function setEnv( } export const updateRuntimeEnv = (appConfig: AppConfig, options: EnvOptions) => { - const { disableRouter } = options; + const { disableRouter, dataLoader } = options; if (!appConfig?.app?.errorBoundary) { - process.env['ICE_CORE_ERROR_BOUNDARY'] = 'false'; + process.env.ICE_CORE_ERROR_BOUNDARY = 'false'; } if (disableRouter) { - process.env['ICE_CORE_ROUTER'] = 'false'; + process.env.ICE_CORE_ROUTER = 'false'; + } + if (!dataLoader) { + process.env.ICE_CORE_REMOVE_DATA_LOADER = 'true'; } }; export function getCoreEnvKeys() { - return ['ICE_CORE_MODE', 'ICE_CORE_ROUTER', 'ICE_CORE_ERROR_BOUNDARY', 'ICE_CORE_INITIAL_DATA', 'ICE_CORE_DEV_PORT']; + return [ + 'ICE_CORE_MODE', + 'ICE_CORE_ROUTER', + 'ICE_CORE_ERROR_BOUNDARY', + 'ICE_CORE_INITIAL_DATA', + 'ICE_CORE_DEV_PORT', + 'ICE_CORE_REMOVE_DATA_LOADER', + ]; } export function getExpandedEnvs(): Record { diff --git a/packages/runtime/src/appData.ts b/packages/runtime/src/appData.ts index 57fb28e2f5..de9a3cea37 100644 --- a/packages/runtime/src/appData.ts +++ b/packages/runtime/src/appData.ts @@ -1,4 +1,4 @@ -import type { AppExport, AppData, RequestContext } from './types.js'; +import type { AppExport, AppData, RequestContext, Loader } from './types.js'; import { callDataLoader } from './dataLoader.js'; /** @@ -18,15 +18,17 @@ async function getAppData(appExport: AppExport, requestContext?: RequestContext) return null; } - let loader; + if (process.env.ICE_CORE_REMOVE_DATA_LOADER !== 'true') { + let loader: Loader; - if (typeof appDataLoaderConfig === 'function' || Array.isArray(appDataLoaderConfig)) { - loader = appDataLoaderConfig; - } else { - loader = appDataLoaderConfig.loader; - } + if (typeof appDataLoaderConfig === 'function' || Array.isArray(appDataLoaderConfig)) { + loader = appDataLoaderConfig; + } else { + loader = appDataLoaderConfig.loader; + } - return await callDataLoader(loader, requestContext); + return await callDataLoader(loader, requestContext); + } } export { diff --git a/packages/runtime/src/routes.tsx b/packages/runtime/src/routes.tsx index 716f2147d4..39ad9f7e4b 100644 --- a/packages/runtime/src/routes.tsx +++ b/packages/runtime/src/routes.tsx @@ -185,10 +185,12 @@ export function createRouteLoader(options: RouteLoaderOptions): LoaderFunction { const getData = (requestContext: RequestContext) => { let routeData: any; - if (globalLoader) { - routeData = globalLoader.getData(routeId, { renderMode, requestContext }); - } else { - routeData = callDataLoader(loader, requestContext); + if (process.env.ICE_CORE_REMOVE_DATA_LOADER !== 'true') { + if (globalLoader) { + routeData = globalLoader.getData(routeId, { renderMode, requestContext }); + } else { + routeData = callDataLoader(loader, requestContext); + } } return routeData; }; diff --git a/packages/runtime/src/runClientApp.tsx b/packages/runtime/src/runClientApp.tsx index 4a25fc3b59..d354be4210 100644 --- a/packages/runtime/src/runClientApp.tsx +++ b/packages/runtime/src/runClientApp.tsx @@ -101,8 +101,10 @@ export default async function runClientApp(options: RunClientAppOptions) { await Promise.all(runtimeModules.statics.map(m => runtime.loadModule(m)).filter(Boolean)); } - dataLoaderFetcher && setFetcher(dataLoaderFetcher); - dataLoaderDecorator && setDecorator(dataLoaderDecorator); + if (process.env.ICE_CORE_REMOVE_DATA_LOADER !== 'true') { + dataLoaderFetcher && setFetcher(dataLoaderFetcher); + dataLoaderDecorator && setDecorator(dataLoaderDecorator); + } if (!appData) { appData = await getAppData(app, requestContext); From e6830c0e8683b4f736fdbe8fde46b2ddc468f7fe Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Mon, 1 Apr 2024 11:30:38 +0800 Subject: [PATCH 2/3] fix: optimize options --- packages/ice/src/createService.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 1da0e66db9..2e657e17f8 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -380,7 +380,11 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const appConfig: AppConfig = (await getAppConfig()).default; - updateRuntimeEnv(appConfig, { disableRouter, dataLoader: loaderExports }); + updateRuntimeEnv(appConfig, { + disableRouter, + // The optimization for runtime size should only be enabled in production mode. + dataLoader: command !== 'build' || loaderExports, + }); return { run: async () => { From 82bd6d4421c5d428caf8becab51c1069bfaea4eb Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Mon, 8 Apr 2024 14:32:43 +0800 Subject: [PATCH 3/3] fix: remove dataloader import in entry --- packages/ice/src/createService.ts | 5 +++-- packages/ice/templates/core/entry.client.tsx.ejs | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 2e657e17f8..0050750b20 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -270,6 +270,8 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt // Only when code splitting use the default strategy or set to `router`, the router will be lazy loaded. const lazy = [true, 'chunks', 'page', 'page-vendors'].includes(userConfig.codeSplitting); const { routeImports, routeDefinition } = getRoutesDefinition(routesInfo.routes, lazy); + const loaderExports = hasExportAppData || Boolean(routesInfo.loaders); + const hasDataLoader = Boolean(userConfig.dataLoader) && loaderExports; // add render data generator.setRenderData({ ...routesInfo, @@ -289,14 +291,13 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt jsOutput: distType.includes('javascript'), hasDocument: fse.existsSync(path.join(rootDir, 'src/document.tsx')) || fse.existsSync(path.join(rootDir, 'src/document.jsx')) || fse.existsSync(path.join(rootDir, 'src/document.js')), dataLoader: userConfig.dataLoader, + hasDataLoader, routeImports, routeDefinition, }); dataCache.set('routes', JSON.stringify(routesInfo)); dataCache.set('hasExportAppData', hasExportAppData ? 'true' : ''); - const loaderExports = hasExportAppData || Boolean(routesInfo.loaders); - const hasDataLoader = Boolean(userConfig.dataLoader) && loaderExports; // Render exports files if route component export dataLoader / pageConfig. renderExportsTemplate( { diff --git a/packages/ice/templates/core/entry.client.tsx.ejs b/packages/ice/templates/core/entry.client.tsx.ejs index 2fd1cb89bb..0e52e5a325 100644 --- a/packages/ice/templates/core/entry.client.tsx.ejs +++ b/packages/ice/templates/core/entry.client.tsx.ejs @@ -8,7 +8,7 @@ import * as app from '@/app'; import createRoutes from './routes'; <% } -%> <%- runtimeOptions.imports %> -<% if (dataLoaderImport.imports) {-%><%-dataLoaderImport.imports%><% } -%> +<% if (dataLoaderImport.imports && hasDataLoader) {-%><%-dataLoaderImport.imports%><% } -%> import type { RunClientAppOptions } from '@ice/runtime'; const getRouterBasename = () => { @@ -19,7 +19,7 @@ const getRouterBasename = () => { // Otherwise chunk of route component will pack @ice/jsx-runtime and depend on framework bundle. const App = <>; -<% if (!dataLoaderImport.imports) {-%> +<% if (!dataLoaderImport.imports && hasDataLoader) {-%> let dataLoaderFetcher = (options) => { return window.fetch(options.url, options); } @@ -39,8 +39,9 @@ const renderOptions: RunClientAppOptions = { basename: getRouterBasename(), hydrate: <%- hydrate %>, memoryRouter: <%- memoryRouter || false %>, +<% if (hasDataLoader) { -%> dataLoaderFetcher, - dataLoaderDecorator, + dataLoaderDecorator,<% } -%> runtimeOptions: { <% if (runtimeOptions.exports) { -%> <%- runtimeOptions.exports %>