diff --git a/.changeset/clever-shrimps-sip.md b/.changeset/clever-shrimps-sip.md new file mode 100644 index 0000000000..e2838c3f51 --- /dev/null +++ b/.changeset/clever-shrimps-sip.md @@ -0,0 +1,5 @@ +--- +'@ice/webpack-config': patch +--- + +fix: redirect named import diff --git a/.changeset/gorgeous-rice-stare.md b/.changeset/gorgeous-rice-stare.md new file mode 100644 index 0000000000..50dcc0e674 --- /dev/null +++ b/.changeset/gorgeous-rice-stare.md @@ -0,0 +1,5 @@ +--- +'@ice/app': patch +--- + +fix: redirect request for data loader diff --git a/examples/with-request/src/pages/layout.tsx b/examples/with-request/src/pages/layout.tsx index 2460e127c7..e8466f2f00 100644 --- a/examples/with-request/src/pages/layout.tsx +++ b/examples/with-request/src/pages/layout.tsx @@ -1,6 +1,9 @@ -import { Outlet, defineDataLoader } from 'ice'; +import { Outlet, defineDataLoader, useData, request } from 'ice'; export default () => { + const data = useData(); + console.log(data); + return (

ICE 3.0 Layout

@@ -21,12 +24,12 @@ export function pageConfig() { }; } -export const dataLoader = defineDataLoader(() => { - return new Promise((resolve) => { - setTimeout(() => { - resolve({ - layout: true, - }); - }, 1 * 100); - }); +export const dataLoader = defineDataLoader(async () => { + try { + const data = await request('/data'); + return data; + } catch (e) { + console.error(e); + return {}; + } }); diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 4855ac9f36..31373ffff3 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -109,6 +109,9 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt declarationType: DeclarationType.NORMAL, }); }, + getExportList: (registerKey: string) => { + return generator.getExportList(registerKey); + }, render: generator.render, }; diff --git a/packages/ice/src/service/runtimeGenerator.ts b/packages/ice/src/service/runtimeGenerator.ts index c82941c963..4878c8d79c 100644 --- a/packages/ice/src/service/runtimeGenerator.ts +++ b/packages/ice/src/service/runtimeGenerator.ts @@ -231,6 +231,18 @@ export default class Generator { this.contentRegistration[registerKey].push(...content); }; + public getExportList = (registerKey: string, target?: string) => { + const exportList = this.contentRegistration[registerKey] || []; + + if (target) { + return exportList.filter(exports => { + return !(exports.target && exports.target !== target); + }); + } else { + return exportList; + } + }; + private getDeclarations: GetDeclarations = (registerKey, dataKeys) => { const exportList = this.contentRegistration[registerKey] || []; const { diff --git a/packages/ice/src/service/webpackCompiler.ts b/packages/ice/src/service/webpackCompiler.ts index 5dde9176f8..11d0a67beb 100644 --- a/packages/ice/src/service/webpackCompiler.ts +++ b/packages/ice/src/service/webpackCompiler.ts @@ -46,7 +46,7 @@ async function webpackCompiler(options: { // `commandArgs` doesn't guarantee target exists. const { target = WEB } = commandArgs; const { serverCompiler, serverRunner } = hooksAPI; - const { serverCompileTask, dataCache, watch } = context.extendsPluginAPI; + const { serverCompileTask, dataCache, watch, generator } = context.extendsPluginAPI; await applyHook(`before.${command}.run`, { urls, @@ -121,7 +121,16 @@ async function webpackCompiler(options: { // Add webpack plugin of data-loader. if (useDataLoader) { - webpackConfig.plugins.push(new DataLoaderPlugin({ serverCompiler, target, rootDir, dataCache, getAllPlugin })); + const frameworkExports = generator.getExportList('framework', target); + + webpackConfig.plugins.push(new DataLoaderPlugin({ + serverCompiler, + target, + rootDir, + dataCache, + getAllPlugin, + frameworkExports, + })); } } diff --git a/packages/ice/src/types/plugin.ts b/packages/ice/src/types/plugin.ts index 0b421efb0e..07baff6dce 100644 --- a/packages/ice/src/types/plugin.ts +++ b/packages/ice/src/types/plugin.ts @@ -16,6 +16,7 @@ type AddTargetExport = (exportData: TargetDeclarationData) => void; type AddEntryCode = (callback: (code: string) => string) => void; type RemoveExport = (removeSource: string | string[]) => void; type EventName = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'; +type GetExportList = (key: string, target?: string) => (DeclarationData | TargetDeclarationData)[]; type ServerCompilerBuildOptions = Pick< esbuild.BuildOptions, @@ -142,6 +143,7 @@ export interface ExtendsPluginAPI { render: Render; addDataLoaderImport: AddDataLoaderImport; addEntryCode: AddEntryCode; + getExportList: GetExportList; }; watch: { addEvent?: (watchEvent: WatchEvent) => void; diff --git a/packages/ice/src/webpack/DataLoaderPlugin.ts b/packages/ice/src/webpack/DataLoaderPlugin.ts index 7aa165d740..6a517f3af7 100644 --- a/packages/ice/src/webpack/DataLoaderPlugin.ts +++ b/packages/ice/src/webpack/DataLoaderPlugin.ts @@ -4,7 +4,8 @@ import type { Compiler } from 'webpack'; import webpack from '@ice/bundles/compiled/webpack/index.js'; import type { Context } from 'build-scripts'; import type { ServerCompiler, PluginData } from '../types/plugin.js'; -import { IMPORT_META_RENDERER, IMPORT_META_TARGET, RUNTIME_TMP_DIR, RUNTIME_EXPORTS } from '../constant.js'; +import type { DeclarationData } from '../types/generator.js'; +import { IMPORT_META_RENDERER, IMPORT_META_TARGET, RUNTIME_TMP_DIR } from '../constant.js'; import { getRoutePathsFromCache } from '../utils/getRoutePaths.js'; const pluginName = 'DataLoaderPlugin'; @@ -16,6 +17,7 @@ export default class DataLoaderPlugin { private target: string; private dataCache: Map; private getAllPlugin: Context['getAllPlugin']; + private frameworkExports: DeclarationData[]; public constructor(options: { serverCompiler: ServerCompiler; @@ -23,13 +25,15 @@ export default class DataLoaderPlugin { target: string; dataCache: Map; getAllPlugin?: Context['getAllPlugin']; + frameworkExports: DeclarationData[]; }) { - const { serverCompiler, rootDir, dataCache, getAllPlugin, target } = options; + const { serverCompiler, rootDir, dataCache, getAllPlugin, target, frameworkExports } = options; this.serverCompiler = serverCompiler; this.rootDir = rootDir; this.dataCache = dataCache; this.getAllPlugin = getAllPlugin; this.target = target; + this.frameworkExports = frameworkExports; } public apply(compiler: Compiler) { @@ -74,7 +78,7 @@ export default class DataLoaderPlugin { transformEnv: false, enableEnv: true, // Redirect imports to @ice/runtime to avoid build plugin side effect code. - redirectImports: RUNTIME_EXPORTS, + redirectImports: this.frameworkExports, isServer: false, }, ); diff --git a/packages/webpack-config/src/unPlugins/redirectImport.ts b/packages/webpack-config/src/unPlugins/redirectImport.ts index d51c8353ca..ad54a07017 100644 --- a/packages/webpack-config/src/unPlugins/redirectImport.ts +++ b/packages/webpack-config/src/unPlugins/redirectImport.ts @@ -63,13 +63,13 @@ export function parseRedirectData(data: DeclarationData[]): RedirectData { } export function generateImport(matchedImports: MatchedImports): string { - let defaultImport = ''; - let namedImports = []; function parseLocalIdentifier(identifier: string, alias: Record): string { return alias[identifier] ? `${alias[identifier]} as ${identifier}` : identifier; } const importStatements = Object.keys(matchedImports).map((source) => { const importStatements = matchedImports[source]; + let defaultImport = ''; + const namedImports = []; importStatements.forEach(({ isDefault, identifier, alias }) => { if (isDefault) { defaultImport = parseLocalIdentifier(identifier, alias); diff --git a/packages/webpack-config/tests/fixtures/redirectImport/multiple.js b/packages/webpack-config/tests/fixtures/redirectImport/multiple.js index 41f0748e2e..aa943afebb 100644 --- a/packages/webpack-config/tests/fixtures/redirectImport/multiple.js +++ b/packages/webpack-config/tests/fixtures/redirectImport/multiple.js @@ -1 +1 @@ -import { request, store } from 'ice'; \ No newline at end of file +import { request, store, test } from 'ice'; \ No newline at end of file diff --git a/packages/webpack-config/tests/redirectImport.test.ts b/packages/webpack-config/tests/redirectImport.test.ts index aacb98cafd..6518edb182 100644 --- a/packages/webpack-config/tests/redirectImport.test.ts +++ b/packages/webpack-config/tests/redirectImport.test.ts @@ -20,7 +20,7 @@ describe('redirect import', () => { specifier: 'store', source: '@ice/store', }, { - specifier: 'request', + specifier: ['request', 'test'], source: 'axios', }]; @@ -52,7 +52,7 @@ describe('redirect import', () => { it('multiple transform', async () => { const code = fs.readFileSync(path.join(__dirname, './fixtures/redirectImport/multiple.js'), 'utf-8'); const transformed = await redirectImport(code, { exportData, targetSource: 'ice' }); - expect(transformed).toBe('import request from \'axios\';\nimport store from \'@ice/store\';'); + expect(transformed).toBe('import { request, test } from \'axios\';\nimport store from \'@ice/store\';'); }); it('matched transform', async () => { const code = fs.readFileSync(path.join(__dirname, './fixtures/redirectImport/matched.js'), 'utf-8'); @@ -64,4 +64,4 @@ describe('redirect import', () => { const transformed = await redirectImport(code, { exportData, targetSource: 'ice' }); expect(transformed).toBe('import { defineDataLoader } from \'ice\';'); }); -}); \ No newline at end of file +}); diff --git a/tests/integration/with-request.test.ts b/tests/integration/with-request.test.ts new file mode 100644 index 0000000000..8366a77534 --- /dev/null +++ b/tests/integration/with-request.test.ts @@ -0,0 +1,17 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { expect, test, describe } from 'vitest'; +import { buildFixture } from '../utils/build'; + +// @ts-ignore +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const example = 'with-request'; + +describe(`build ${example}`, () => { + test('data-loader build file', async () => { + await buildFixture(example); + const content = fs.readFileSync(path.join(__dirname, `../../examples/${example}/build/js/data-loader.js`), 'utf-8'); + expect(content.includes('react.element')).toBe(false); + }); +});