From 6f3427e3d02656916c5f787f6e2204c750e13695 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Thu, 31 Mar 2022 19:09:41 +0800 Subject: [PATCH 01/36] feat: support define routes --- examples/basic-project/ice.config.ts | 6 + examples/basic-project/src/layout.tsx | 11 -- examples/basic-project/src/pages/index.tsx | 2 +- packages/ice/src/createService.ts | 14 ++- packages/ice/src/routes.ts | 5 +- packages/ice/src/service/runtimeGenerator.ts | 4 +- packages/plugin-app/src/userConfig.ts | 4 + packages/route-manifest/src/index.ts | 37 ++++-- packages/route-manifest/src/routes.ts | 9 +- .../generateRouteManifest.spec.ts.snap | 116 +++++++++++++++--- .../tests/generateRouteManifest.spec.ts | 18 ++- packages/runtime/src/transition.ts | 4 +- packages/runtime/src/types.ts | 2 +- packages/types/src/userConfig.ts | 5 + 14 files changed, 177 insertions(+), 60 deletions(-) delete mode 100644 examples/basic-project/src/layout.tsx diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index 26d34bc64..aa521fd49 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -9,4 +9,10 @@ export default defineUserConfig({ } return webpackConfig; }, + routes: { + ignoreFiles: ['about.tsx'], + defineRoutes: (route) => { + route('/about-me', 'about.tsx'); + }, + }, }); \ No newline at end of file diff --git a/examples/basic-project/src/layout.tsx b/examples/basic-project/src/layout.tsx deleted file mode 100644 index 45c897cd4..000000000 --- a/examples/basic-project/src/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from 'react'; -import { Outlet } from 'ice'; - -export default () => { - return ( -
-

Layout

- -
- ); -}; \ No newline at end of file diff --git a/examples/basic-project/src/pages/index.tsx b/examples/basic-project/src/pages/index.tsx index 1896c514b..b0182901d 100644 --- a/examples/basic-project/src/pages/index.tsx +++ b/examples/basic-project/src/pages/index.tsx @@ -9,7 +9,7 @@ export default function Home() { return ( <>

Home Page

- about + about ); } diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 29f92a46d..f0e1401ee 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -31,15 +31,9 @@ async function createService({ rootDir, command, commandArgs, getBuiltInPlugins const configFile = 'ice.config.(mts|mjs|ts|js|cjs|json)'; const dataCache = new Map(); - const routesRenderData = generateRoutesInfo(rootDir); - dataCache.set('routes', JSON.stringify(routesRenderData)); - const generator = new Generator({ rootDir, targetDir, - defaultRenderData: { - ...routesRenderData, - }, // add default template of ice templates: [templateDir], }); @@ -86,6 +80,14 @@ async function createService({ rootDir, command, commandArgs, getBuiltInPlugins getBuiltInPlugins, }); await ctx.resolveConfig(); + const { userConfig: { routes: routesConfig } } = ctx; + const routesRenderData = generateRoutesInfo(rootDir, routesConfig); + generator.modifyRenderData((renderData) => ({ + ...renderData, + ...routesRenderData, + })); + dataCache.set('routes', JSON.stringify(routesRenderData)); + generator.setPlugins(ctx.getAllPlugin()); await ctx.setup(); // render template before webpack compile diff --git a/packages/ice/src/routes.ts b/packages/ice/src/routes.ts index 48dce9008..64bde6cae 100644 --- a/packages/ice/src/routes.ts +++ b/packages/ice/src/routes.ts @@ -1,9 +1,10 @@ import * as path from 'path'; import { formatNestedRouteManifest, generateRouteManifest } from '@ice/route-manifest'; import type { NestedRouteManifest } from '@ice/route-manifest'; +import type { UserConfig } from '@ice/types'; -export function generateRoutesInfo(rootDir: string) { - const routeManifest = generateRouteManifest(rootDir); +export function generateRoutesInfo(rootDir: string, routesConfig?: UserConfig['routes']) { + const routeManifest = generateRouteManifest(rootDir, routesConfig.ignoreFiles, routesConfig.defineRoutes); const routes = formatNestedRouteManifest(routeManifest); const str = generateNestRoutesStr(routes); diff --git a/packages/ice/src/service/runtimeGenerator.ts b/packages/ice/src/service/runtimeGenerator.ts index df616b5d5..8d84eba7d 100644 --- a/packages/ice/src/service/runtimeGenerator.ts +++ b/packages/ice/src/service/runtimeGenerator.ts @@ -36,7 +36,7 @@ const RENDER_WAIT = 150; interface Options { rootDir: string; targetDir: string; - defaultRenderData: RenderData; + defaultRenderData?: RenderData; templates?: (string | TemplateOptions)[]; } @@ -114,7 +114,7 @@ export default class Generator { private plugins: any[]; public constructor(options: Options) { - const { rootDir, targetDir, defaultRenderData, templates } = options; + const { rootDir, targetDir, defaultRenderData = {}, templates } = options; this.rootDir = rootDir; this.targetDir = targetDir; this.renderData = defaultRenderData; diff --git a/packages/plugin-app/src/userConfig.ts b/packages/plugin-app/src/userConfig.ts index 33de22aa0..0068e8b2f 100644 --- a/packages/plugin-app/src/userConfig.ts +++ b/packages/plugin-app/src/userConfig.ts @@ -108,6 +108,10 @@ const userConfig = [ } }, }, + { + name: 'routes', + validation: 'object', + }, ]; export default userConfig; diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 32a86bed9..b2b59938e 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -5,9 +5,10 @@ import minimatch from 'minimatch'; import { createRouteId, defineRoutes } from './routes.js'; import type { RouteManifest, DefineRouteFunction, NestedRouteManifest } from './routes.js'; -export { +export type { RouteManifest, NestedRouteManifest, + DefineRouteFunction, }; const validRouteChar = ['-', '\\w', '/', ':', '*']; @@ -26,7 +27,11 @@ export function isRouteModuleFile(filename: string): boolean { return routeModuleExts.includes(path.extname(filename)); } -export function generateRouteManifest(rootDir: string) { +export function generateRouteManifest( + rootDir: string, + ignoreFiles: string[] = [], + defineExtraRoutes?: (defineRoute: DefineRouteFunction) => void, + ) { const srcDir = path.join(rootDir, 'src'); const routeManifest: RouteManifest = {}; // 1. find global layout @@ -43,7 +48,7 @@ export function generateRouteManifest(rootDir: string) { if (fs.existsSync(path.resolve(srcDir, 'pages'))) { const conventionalRoutes = defineConventionalRoutes( rootDir, - [], // TODO: add ignoredFilePatterns defined in ice.config.js + ignoreFiles, ); for (const key of Object.keys(conventionalRoutes)) { @@ -54,7 +59,19 @@ export function generateRouteManifest(rootDir: string) { }; } } - + // 3. add custom routes + // TODO: + if (defineExtraRoutes) { + const extraRoutes = defineRoutes(defineExtraRoutes); + console.log(extraRoutes); + for (const key of Object.keys(extraRoutes)) { + const route = extraRoutes[key]; + routeManifest[route.id] = { + ...route, + parentId: route.parentId || (globalLayoutFile && 'layout') || undefined, + }; + } + } return routeManifest; } @@ -76,7 +93,6 @@ function defineConventionalRoutes( ignoredFilePatterns?: string[], ): RouteManifest { const files: { [routeId: string]: string } = {}; - // 1. find all route components in src/pages visitFiles( path.join(rootDir, 'src', 'pages'), @@ -88,10 +104,9 @@ function defineConventionalRoutes( return; } - const filePath = path.join('pages', file); if (isRouteModuleFile(file)) { - let routeId = createRouteId(filePath); - files[routeId] = filePath; + let routeId = createRouteId(file); + files[routeId] = file; return; } }, @@ -113,13 +128,13 @@ function defineConventionalRoutes( for (let routeId of childRouteIds) { const routePath: string | undefined = createRoutePath( - routeId.slice((removeLayoutStrFromId(parentId) || 'pages').length), + routeId.slice((removeLayoutStrFromId(parentId) || '').length), ); if (RegExp(`[^${validRouteChar.join(',')}]`).test(routePath)) { - throw new Error(`invalid character in '${routeId}'. Only support char: ${validRouteChar.join(', ')}`); + throw new Error(`invalid character in '${path.join('src', 'pages', files[routeId])}'. Only support char: ${validRouteChar.join(', ')}`); } const isIndexRoute = routeId.endsWith('/index'); - let fullPath = createRoutePath(routeId.slice('pages'.length + 1)); + let fullPath = createRoutePath(routeId); let uniqueRouteId = (fullPath || '') + (isIndexRoute ? '?index' : ''); if (uniqueRouteId) { diff --git a/packages/route-manifest/src/routes.ts b/packages/route-manifest/src/routes.ts index 2d684ec66..5e1c1874c 100644 --- a/packages/route-manifest/src/routes.ts +++ b/packages/route-manifest/src/routes.ts @@ -1,6 +1,6 @@ // based on https://github.com/remix-run/remix/blob/main/packages/remix-dev/config/routes.ts -import { win32 } from 'path'; +import { win32, join } from 'path'; export interface ConfigRoute { /** @@ -100,16 +100,17 @@ export function defineRoutes( // route(path, file, options) options = optionsOrChildren || {}; } - const id = createRouteId(file); + const pageFilePath = join('pages', file); + const id = createRouteId(pageFilePath); const route: ConfigRoute = { - path: path || undefined, + path: path || '/', index: options.index ? true : undefined, id, parentId: parentRoutes.length > 0 ? parentRoutes[parentRoutes.length - 1].id : undefined, - file, + file: pageFilePath, componentName: createComponentName(id), }; diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap index 3b5b3dcd1..74c9a6aa1 100644 --- a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -14,7 +14,7 @@ Object { "id": "pages/About/index", "index": true, "parentId": "layout", - "path": "/About", + "path": "About", }, "pages/About/me/index": Object { "componentName": "PagesAboutMeIndex", @@ -22,7 +22,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "/About/me", + "path": "About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -30,15 +30,58 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", + "index": undefined, + "parentId": "layout", + "path": "/", + }, +} +`; + +exports[`generateRouteManifest function define-extra-routes 1`] = ` +Object { + "layout": Object { + "componentName": "Layout", + "file": "layout.tsx", + "id": "layout", + "path": "", + }, + "pages/About/index": Object { + "componentName": "PagesAboutIndex", + "file": "pages/About/index.tsx", + "id": "pages/About/index", + "index": undefined, + "parentId": "layout", + "path": "/about-me", + }, + "pages/About/me/index": Object { + "componentName": "PagesAboutMeIndex", + "file": "pages/About/me/index.tsx", + "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": undefined, + "path": "About/me", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": "layout", + "path": "home", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": undefined, + "parentId": "layout", + "path": "/", }, } `; @@ -57,7 +100,7 @@ Object { "id": "pages/home.news", "index": undefined, "parentId": "layout", - "path": "/home/news", + "path": "home/news", }, } `; @@ -70,7 +113,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": undefined, - "path": "/about", + "path": "about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -78,7 +121,7 @@ Object { "id": "pages/blog/$id", "index": undefined, "parentId": undefined, - "path": "/blog/:id", + "path": "blog/:id", }, "pages/blog/index": Object { "componentName": "PagesBlogIndex", @@ -86,15 +129,50 @@ Object { "id": "pages/blog/index", "index": true, "parentId": undefined, - "path": "/blog", + "path": "blog", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": true, + "index": undefined, "parentId": undefined, - "path": undefined, + "path": "/", + }, +} +`; + +exports[`generateRouteManifest function ignore-routes 1`] = ` +Object { + "layout": Object { + "componentName": "Layout", + "file": "layout.tsx", + "id": "layout", + "path": "", + }, + "pages/About/me/index": Object { + "componentName": "PagesAboutMeIndex", + "file": "pages/About/me/index.tsx", + "id": "pages/About/me/index", + "index": true, + "parentId": "layout", + "path": "About/me", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": "layout", + "path": "home", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": undefined, + "parentId": "layout", + "path": "/", }, } `; @@ -113,7 +191,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": "layout", - "path": "/about", + "path": "about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -129,7 +207,7 @@ Object { "id": "pages/blog/index", "index": true, "parentId": "pages/blog/layout", - "path": undefined, + "path": "/", }, "pages/blog/layout": Object { "componentName": "PagesBlogLayout", @@ -137,7 +215,7 @@ Object { "id": "pages/blog/layout", "index": undefined, "parentId": "layout", - "path": "/blog", + "path": "blog", }, "pages/home/index": Object { "componentName": "PagesHomeIndex", @@ -145,7 +223,7 @@ Object { "id": "pages/home/index", "index": true, "parentId": "pages/home/layout", - "path": undefined, + "path": "/", }, "pages/home/layout": Object { "componentName": "PagesHomeLayout", @@ -153,7 +231,7 @@ Object { "id": "pages/home/layout", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/home/layout/index": Object { "componentName": "PagesHomeLayoutIndex", @@ -167,9 +245,9 @@ Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": true, + "index": undefined, "parentId": "layout", - "path": undefined, + "path": "/", }, } `; @@ -188,7 +266,7 @@ Object { "id": "pages/$", "index": undefined, "parentId": "layout", - "path": "/*", + "path": "*", }, "pages/home": Object { "componentName": "PagesHome", @@ -196,7 +274,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, } `; diff --git a/packages/route-manifest/tests/generateRouteManifest.spec.ts b/packages/route-manifest/tests/generateRouteManifest.spec.ts index d3a82442c..4393e9289 100644 --- a/packages/route-manifest/tests/generateRouteManifest.spec.ts +++ b/packages/route-manifest/tests/generateRouteManifest.spec.ts @@ -32,6 +32,22 @@ describe('generateRouteManifest function', () => { }); test('invalid-routes', () => { - expect(() => generateRouteManifest(path.join(fixturesDir, 'invalid-routes'))).toThrow(`invalid character in 'pages/[a.pdf]'. Only support char: -, \\w, /`); + expect(() => generateRouteManifest(path.join(fixturesDir, 'invalid-routes'))).toThrow(`invalid character in 'src/pages/[a.pdf].tsx'. Only support char: -, \\w, /`); + }); + + test('ignore-routes', () => { + const routeManifest = generateRouteManifest(path.join(fixturesDir, 'basic-routes'), ['About/index.tsx']); + expect(routeManifest).toMatchSnapshot(); + }); + + test('define-extra-routes', () => { + const routeManifest = generateRouteManifest( + path.join(fixturesDir, 'basic-routes'), + ['About/index.tsx'], + (defineRoute) => { + defineRoute('/about-me', 'About/index.tsx'); + } + ); + expect(routeManifest).toMatchSnapshot(); }); }); diff --git a/packages/runtime/src/transition.ts b/packages/runtime/src/transition.ts index 58b9db405..8fd9ea17b 100644 --- a/packages/runtime/src/transition.ts +++ b/packages/runtime/src/transition.ts @@ -34,8 +34,8 @@ export function createTransitionManager(options: TransitionOptions) { async function handleLoad(location: Location) { const matches = matchRoutes(routes, location); - if (!matches) { - throw new Error(`Routes not found in location ${location}.`); + if (!matches.length) { + throw new Error(`Routes not found in location ${location.pathname}.`); } const routeModules = await loadRouteModules(matches.map(match => match.route as RouteItem)); diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index c3a841e8f..2d24cccbb 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -47,8 +47,8 @@ export interface PageComponent { export interface RouteItem { id: string; path: string; - element: ReactNode; componentName: string; + element?: ReactNode; index?: false; exact?: boolean; strict?: boolean; diff --git a/packages/types/src/userConfig.ts b/packages/types/src/userConfig.ts index 8e0bd04f8..b1d4635bd 100644 --- a/packages/types/src/userConfig.ts +++ b/packages/types/src/userConfig.ts @@ -1,3 +1,4 @@ +import type { DefineRouteFunction } from '@ice/route-manifest'; import type { Config, ModifyWebpackConfig } from './config'; export interface UserConfig { @@ -11,4 +12,8 @@ export interface UserConfig { proxy?: Config['proxy']; filename?: string; webpack?: ModifyWebpackConfig; + routes?: { + ignoreFiles?: string[]; + defineRoutes?: (defineRoute: DefineRouteFunction) => void; + }; } From 6129d183a0319dca3e299c5f3836d61f79482ca2 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Thu, 31 Mar 2022 20:25:09 +0800 Subject: [PATCH 02/36] fix: test --- packages/route-manifest/src/index.ts | 28 ++++++------- packages/route-manifest/src/routes.ts | 2 +- .../formatNestedRouteManifest.spec.ts.snap | 2 +- .../generateRouteManifest.spec.ts.snap | 42 +++++++++---------- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index ab6ac4f89..aed9e0342 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -125,24 +125,22 @@ function defineConventionalRoutes( }); for (let routeId of childRouteIds) { - const routePath: string | undefined = createRoutePath( - routeId.slice((removeLayoutStrFromId(parentId) || '').length), + const routePath: string = createRoutePath( + routeId.slice((removeLastLayoutStrFromId(parentId) || '').length), ); + const routeFilePath = path.join('src', 'pages', files[routeId]); if (RegExp(`[^${validRouteChar.join(',')}]`).test(routePath)) { - throw new Error(`invalid character in '${path.join('src', 'pages', files[routeId])}'. Only support char: ${validRouteChar.join(', ')}`); + throw new Error(`invalid character in '${routeFilePath}'. Only support char: ${validRouteChar.join(', ')}`); } - const isIndexRoute = routeId.endsWith('/index'); - let fullPath = createRoutePath(routeId); - let uniqueRouteId = (fullPath || '') + (isIndexRoute ? '?index' : ''); + const isIndexRoute = routeId === 'index' || routeId.endsWith('/index'); + const fullPath = createRoutePath(routeId); + const uniqueRouteId = fullPath + (isIndexRoute ? '?index' : ''); if (uniqueRouteId) { if (uniqueRoutes.has(uniqueRouteId)) { throw new Error( - `Path ${JSON.stringify(fullPath)} defined by route ${JSON.stringify( - routeId, - )} conflicts with route ${JSON.stringify( - uniqueRoutes.get(uniqueRouteId), - )}`, + `Path ${JSON.stringify(fullPath)} defined by route ${JSON.stringify(routeFilePath)} + conflicts with route ${JSON.stringify(uniqueRoutes.get(uniqueRouteId))}`, ); } else { uniqueRoutes.set(uniqueRouteId, routeId); @@ -178,7 +176,7 @@ export function createRoutePath(routeId: string): string | undefined { let result = ''; let rawSegmentBuffer = ''; - const partialRouteId = removeLayoutStrFromId(routeId); + const partialRouteId = removeLastLayoutStrFromId(routeId); for (let i = 0; i < partialRouteId.length; i++) { const char = partialRouteId.charAt(i); @@ -208,8 +206,8 @@ export function createRoutePath(routeId: string): string | undefined { if (rawSegmentBuffer === 'index' && result.endsWith('index')) { result = result.replace(/\/?index$/, ''); } - - return result || undefined; + result = result.startsWith('/') ? result : `/${result}`; + return result; } function findParentRouteId( @@ -259,6 +257,6 @@ function findGlobalLayout(srcDir: string, basename: string): string | undefined * /About/layout -> /About * /About/layout/index -> /About/layout/index */ -function removeLayoutStrFromId(id?: string) { +function removeLastLayoutStrFromId(id?: string) { return id?.endsWith('/layout') ? id.slice(0, id.length - '/layout'.length) : id; } diff --git a/packages/route-manifest/src/routes.ts b/packages/route-manifest/src/routes.ts index 5e1c1874c..190886bf3 100644 --- a/packages/route-manifest/src/routes.ts +++ b/packages/route-manifest/src/routes.ts @@ -103,7 +103,7 @@ export function defineRoutes( const pageFilePath = join('pages', file); const id = createRouteId(pageFilePath); const route: ConfigRoute = { - path: path || '/', + path, index: options.index ? true : undefined, id, parentId: diff --git a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap index 94f5f0f42..9c40b410d 100644 --- a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap @@ -32,7 +32,7 @@ Array [ "id": "pages/index", "index": true, "parentId": undefined, - "path": undefined, + "path": "/", }, ] `; diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap index 74c9a6aa1..5d269b7ec 100644 --- a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -14,7 +14,7 @@ Object { "id": "pages/About/index", "index": true, "parentId": "layout", - "path": "About", + "path": "/About", }, "pages/About/me/index": Object { "componentName": "PagesAboutMeIndex", @@ -22,7 +22,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "About/me", + "path": "/About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -30,13 +30,13 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "home", + "path": "/home", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": undefined, + "index": true, "parentId": "layout", "path": "/", }, @@ -65,7 +65,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "About/me", + "path": "/About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -73,13 +73,13 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "home", + "path": "/home", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": undefined, + "index": true, "parentId": "layout", "path": "/", }, @@ -100,7 +100,7 @@ Object { "id": "pages/home.news", "index": undefined, "parentId": "layout", - "path": "home/news", + "path": "/home/news", }, } `; @@ -113,7 +113,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": undefined, - "path": "about", + "path": "/about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -121,7 +121,7 @@ Object { "id": "pages/blog/$id", "index": undefined, "parentId": undefined, - "path": "blog/:id", + "path": "/blog/:id", }, "pages/blog/index": Object { "componentName": "PagesBlogIndex", @@ -129,13 +129,13 @@ Object { "id": "pages/blog/index", "index": true, "parentId": undefined, - "path": "blog", + "path": "/blog", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": undefined, + "index": true, "parentId": undefined, "path": "/", }, @@ -156,7 +156,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "About/me", + "path": "/About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -164,13 +164,13 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "home", + "path": "/home", }, "pages/index": Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": undefined, + "index": true, "parentId": "layout", "path": "/", }, @@ -191,7 +191,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": "layout", - "path": "about", + "path": "/about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -215,7 +215,7 @@ Object { "id": "pages/blog/layout", "index": undefined, "parentId": "layout", - "path": "blog", + "path": "/blog", }, "pages/home/index": Object { "componentName": "PagesHomeIndex", @@ -231,7 +231,7 @@ Object { "id": "pages/home/layout", "index": undefined, "parentId": "layout", - "path": "home", + "path": "/home", }, "pages/home/layout/index": Object { "componentName": "PagesHomeLayoutIndex", @@ -245,7 +245,7 @@ Object { "componentName": "PagesIndex", "file": "pages/index.tsx", "id": "pages/index", - "index": undefined, + "index": true, "parentId": "layout", "path": "/", }, @@ -266,7 +266,7 @@ Object { "id": "pages/$", "index": undefined, "parentId": "layout", - "path": "*", + "path": "/*", }, "pages/home": Object { "componentName": "PagesHome", @@ -274,7 +274,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "home", + "path": "/home", }, } `; From b1d185ecf777da24188eab698fa6fa4b254a80d8 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Thu, 31 Mar 2022 20:34:35 +0800 Subject: [PATCH 03/36] fix: test --- packages/route-manifest/src/index.ts | 4 +- .../formatNestedRouteManifest.spec.ts.snap | 8 ++-- .../generateRouteManifest.spec.ts.snap | 46 +++++++++---------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index aed9e0342..2bbf4bf73 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -206,8 +206,8 @@ export function createRoutePath(routeId: string): string | undefined { if (rawSegmentBuffer === 'index' && result.endsWith('index')) { result = result.replace(/\/?index$/, ''); } - result = result.startsWith('/') ? result : `/${result}`; - return result; + + return result || undefined; } function findParentRouteId( diff --git a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap index 9c40b410d..a56ffa0c9 100644 --- a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap @@ -8,7 +8,7 @@ Array [ "id": "pages/blog/index", "index": true, "parentId": undefined, - "path": "/blog", + "path": "blog", }, Object { "componentName": "PagesBlog$id", @@ -16,7 +16,7 @@ Array [ "id": "pages/blog/$id", "index": undefined, "parentId": undefined, - "path": "/blog/:id", + "path": "blog/:id", }, Object { "componentName": "PagesAbout", @@ -24,7 +24,7 @@ Array [ "id": "pages/about", "index": undefined, "parentId": undefined, - "path": "/about", + "path": "about", }, Object { "componentName": "PagesIndex", @@ -32,7 +32,7 @@ Array [ "id": "pages/index", "index": true, "parentId": undefined, - "path": "/", + "path": undefined, }, ] `; diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap index 5d269b7ec..98349ae96 100644 --- a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -14,7 +14,7 @@ Object { "id": "pages/About/index", "index": true, "parentId": "layout", - "path": "/About", + "path": "About", }, "pages/About/me/index": Object { "componentName": "PagesAboutMeIndex", @@ -22,7 +22,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "/About/me", + "path": "About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -30,7 +30,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/index": Object { "componentName": "PagesIndex", @@ -38,7 +38,7 @@ Object { "id": "pages/index", "index": true, "parentId": "layout", - "path": "/", + "path": undefined, }, } `; @@ -65,7 +65,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "/About/me", + "path": "About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -73,7 +73,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/index": Object { "componentName": "PagesIndex", @@ -81,7 +81,7 @@ Object { "id": "pages/index", "index": true, "parentId": "layout", - "path": "/", + "path": undefined, }, } `; @@ -100,7 +100,7 @@ Object { "id": "pages/home.news", "index": undefined, "parentId": "layout", - "path": "/home/news", + "path": "home/news", }, } `; @@ -113,7 +113,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": undefined, - "path": "/about", + "path": "about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -121,7 +121,7 @@ Object { "id": "pages/blog/$id", "index": undefined, "parentId": undefined, - "path": "/blog/:id", + "path": "blog/:id", }, "pages/blog/index": Object { "componentName": "PagesBlogIndex", @@ -129,7 +129,7 @@ Object { "id": "pages/blog/index", "index": true, "parentId": undefined, - "path": "/blog", + "path": "blog", }, "pages/index": Object { "componentName": "PagesIndex", @@ -137,7 +137,7 @@ Object { "id": "pages/index", "index": true, "parentId": undefined, - "path": "/", + "path": undefined, }, } `; @@ -156,7 +156,7 @@ Object { "id": "pages/About/me/index", "index": true, "parentId": "layout", - "path": "/About/me", + "path": "About/me", }, "pages/home": Object { "componentName": "PagesHome", @@ -164,7 +164,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/index": Object { "componentName": "PagesIndex", @@ -172,7 +172,7 @@ Object { "id": "pages/index", "index": true, "parentId": "layout", - "path": "/", + "path": undefined, }, } `; @@ -191,7 +191,7 @@ Object { "id": "pages/about", "index": undefined, "parentId": "layout", - "path": "/about", + "path": "about", }, "pages/blog/$id": Object { "componentName": "PagesBlog$id", @@ -207,7 +207,7 @@ Object { "id": "pages/blog/index", "index": true, "parentId": "pages/blog/layout", - "path": "/", + "path": undefined, }, "pages/blog/layout": Object { "componentName": "PagesBlogLayout", @@ -215,7 +215,7 @@ Object { "id": "pages/blog/layout", "index": undefined, "parentId": "layout", - "path": "/blog", + "path": "blog", }, "pages/home/index": Object { "componentName": "PagesHomeIndex", @@ -223,7 +223,7 @@ Object { "id": "pages/home/index", "index": true, "parentId": "pages/home/layout", - "path": "/", + "path": undefined, }, "pages/home/layout": Object { "componentName": "PagesHomeLayout", @@ -231,7 +231,7 @@ Object { "id": "pages/home/layout", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, "pages/home/layout/index": Object { "componentName": "PagesHomeLayoutIndex", @@ -247,7 +247,7 @@ Object { "id": "pages/index", "index": true, "parentId": "layout", - "path": "/", + "path": undefined, }, } `; @@ -266,7 +266,7 @@ Object { "id": "pages/$", "index": undefined, "parentId": "layout", - "path": "/*", + "path": "*", }, "pages/home": Object { "componentName": "PagesHome", @@ -274,7 +274,7 @@ Object { "id": "pages/home", "index": undefined, "parentId": "layout", - "path": "/home", + "path": "home", }, } `; From 2ed8e698be33b6ab82da1231b710ca01c77887cc Mon Sep 17 00:00:00 2001 From: luhc228 Date: Thu, 31 Mar 2022 20:37:14 +0800 Subject: [PATCH 04/36] chore: undefined type --- packages/route-manifest/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 2bbf4bf73..1275141ae 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -125,7 +125,7 @@ function defineConventionalRoutes( }); for (let routeId of childRouteIds) { - const routePath: string = createRoutePath( + const routePath: string | undefined = createRoutePath( routeId.slice((removeLastLayoutStrFromId(parentId) || '').length), ); const routeFilePath = path.join('src', 'pages', files[routeId]); @@ -134,7 +134,7 @@ function defineConventionalRoutes( } const isIndexRoute = routeId === 'index' || routeId.endsWith('/index'); const fullPath = createRoutePath(routeId); - const uniqueRouteId = fullPath + (isIndexRoute ? '?index' : ''); + const uniqueRouteId = (fullPath || '') + (isIndexRoute ? '?index' : ''); if (uniqueRouteId) { if (uniqueRoutes.has(uniqueRouteId)) { From 6b14c4fd4d9f8d906bbbac4afa3b95ce9d02f172 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 11:15:47 +0800 Subject: [PATCH 05/36] fix: conflict --- examples/basic-project/ice.config.ts | 14 +- packages/route-manifest/src/index.ts | 4 +- .../generateRouteManifest.spec.ts.snap | 292 ++++++++++++++++++ 3 files changed, 301 insertions(+), 9 deletions(-) create mode 100644 packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index f245e2526..d31d0a678 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -1,14 +1,14 @@ import { defineUserConfig } from '@ice/app'; -import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; +// import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; export default defineUserConfig({ publicPath: '/', - webpack: (webpackConfig) => { - if (process.env.NODE_ENV !== 'test') { - webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); - } - return webpackConfig; - }, + // webpack: (webpackConfig) => { + // if (process.env.NODE_ENV !== 'test') { + // webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); + // } + // return webpackConfig; + // }, routes: { ignoreFiles: ['about.tsx'], defineRoutes: (route) => { diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 99ff39364..927f9f9af 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -49,14 +49,14 @@ export function generateRouteManifest( }; } } - // 3. add extra routes from ice.config + // 3. add extra routes from user config if (defineExtraRoutes) { const extraRoutes = defineRoutes(defineExtraRoutes); for (const key of Object.keys(extraRoutes)) { const route = extraRoutes[key]; routeManifest[route.id] = { ...route, - parentId: route.parentId || (globalLayoutFile && 'layout') || undefined, + parentId: route.parentId || undefined, }; } } diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap new file mode 100644 index 000000000..b7fd3df66 --- /dev/null +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -0,0 +1,292 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generateRouteManifest function basic-routes 1`] = ` +Object { + "pages/About/index": Object { + "componentName": "PagesAboutIndex", + "file": "pages/About/index.tsx", + "id": "pages/About/index", + "index": true, + "parentId": undefined, + "path": "About", + }, + "pages/About/me/index": Object { + "componentName": "PagesAboutMeIndex", + "file": "pages/About/me/index.tsx", + "id": "pages/About/me/index", + "index": true, + "parentId": undefined, + "path": "About/me", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": undefined, + "path": "home", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": true, + "parentId": undefined, + "path": undefined, + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; + +exports[`generateRouteManifest function define-extra-routes 1`] = ` +Object { + "pages/About/index": Object { + "componentName": "PagesAboutIndex", + "file": "pages/About/index.tsx", + "id": "pages/About/index", + "index": undefined, + "parentId": undefined, + "path": "/about-me", + }, + "pages/About/me/index": Object { + "componentName": "PagesAboutMeIndex", + "file": "pages/About/me/index.tsx", + "id": "pages/About/me/index", + "index": true, + "parentId": undefined, + "path": "About/me", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": undefined, + "path": "home", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": true, + "parentId": undefined, + "path": undefined, + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; + +exports[`generateRouteManifest function doc-delimeters-routes 1`] = ` +Object { + "pages/home.news": Object { + "componentName": "PagesHomeNews", + "file": "pages/home.news.tsx", + "id": "pages/home.news", + "index": undefined, + "parentId": undefined, + "path": "home/news", + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; + +exports[`generateRouteManifest function dynamic-routes 1`] = ` +Object { + "pages/about": Object { + "componentName": "PagesAbout", + "file": "pages/about.tsx", + "id": "pages/about", + "index": undefined, + "parentId": undefined, + "path": "about", + }, + "pages/blog/$id": Object { + "componentName": "PagesBlog$id", + "file": "pages/blog/$id.tsx", + "id": "pages/blog/$id", + "index": undefined, + "parentId": undefined, + "path": "blog/:id", + }, + "pages/blog/index": Object { + "componentName": "PagesBlogIndex", + "file": "pages/blog/index.tsx", + "id": "pages/blog/index", + "index": true, + "parentId": undefined, + "path": "blog", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": true, + "parentId": undefined, + "path": undefined, + }, +} +`; + +exports[`generateRouteManifest function ignore-routes 1`] = ` +Object { + "pages/About/me/index": Object { + "componentName": "PagesAboutMeIndex", + "file": "pages/About/me/index.tsx", + "id": "pages/About/me/index", + "index": true, + "parentId": undefined, + "path": "About/me", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": undefined, + "path": "home", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": true, + "parentId": undefined, + "path": undefined, + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; + +exports[`generateRouteManifest function layout-routes 1`] = ` +Object { + "pages/about": Object { + "componentName": "PagesAbout", + "file": "pages/about.tsx", + "id": "pages/about", + "index": undefined, + "parentId": undefined, + "path": "about", + }, + "pages/blog/$id": Object { + "componentName": "PagesBlog$id", + "file": "pages/blog/$id.tsx", + "id": "pages/blog/$id", + "index": undefined, + "parentId": "pages/blog/layout", + "path": "/:id", + }, + "pages/blog/index": Object { + "componentName": "PagesBlogIndex", + "file": "pages/blog/index.tsx", + "id": "pages/blog/index", + "index": true, + "parentId": "pages/blog/layout", + "path": undefined, + }, + "pages/blog/layout": Object { + "componentName": "PagesBlogLayout", + "file": "pages/blog/layout.tsx", + "id": "pages/blog/layout", + "index": undefined, + "parentId": undefined, + "path": "blog", + }, + "pages/home/index": Object { + "componentName": "PagesHomeIndex", + "file": "pages/home/index.tsx", + "id": "pages/home/index", + "index": true, + "parentId": "pages/home/layout", + "path": undefined, + }, + "pages/home/layout": Object { + "componentName": "PagesHomeLayout", + "file": "pages/home/layout.tsx", + "id": "pages/home/layout", + "index": undefined, + "parentId": undefined, + "path": "home", + }, + "pages/home/layout/index": Object { + "componentName": "PagesHomeLayoutIndex", + "file": "pages/home/layout/index.tsx", + "id": "pages/home/layout/index", + "index": true, + "parentId": "pages/home/layout", + "path": "/layout", + }, + "pages/index": Object { + "componentName": "PagesIndex", + "file": "pages/index.tsx", + "id": "pages/index", + "index": true, + "parentId": undefined, + "path": undefined, + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; + +exports[`generateRouteManifest function splat-routes 1`] = ` +Object { + "pages/$": Object { + "componentName": "Pages$", + "file": "pages/$.tsx", + "id": "pages/$", + "index": undefined, + "parentId": undefined, + "path": "*", + }, + "pages/home": Object { + "componentName": "PagesHome", + "file": "pages/home.tsx", + "id": "pages/home", + "index": undefined, + "parentId": undefined, + "path": "home", + }, + "pages/layout": Object { + "componentName": "PagesLayout", + "file": "pages/layout.tsx", + "id": "pages/layout", + "index": undefined, + "parentId": undefined, + "path": "layout", + }, +} +`; From fe2a872dc18343069eab70563ee78a946a4ad715 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 12:06:08 +0800 Subject: [PATCH 06/36] chore: remove pages str from route id --- packages/build-webpack-config/src/index.ts | 2 +- packages/ice/src/routes.ts | 2 +- packages/route-manifest/src/index.ts | 4 +- packages/route-manifest/src/routes.ts | 12 +- .../generateRouteManifest.spec.ts.snap | 318 +++++++++--------- 5 files changed, 169 insertions(+), 169 deletions(-) diff --git a/packages/build-webpack-config/src/index.ts b/packages/build-webpack-config/src/index.ts index 1187f3720..2f8c46cc2 100644 --- a/packages/build-webpack-config/src/index.ts +++ b/packages/build-webpack-config/src/index.ts @@ -41,7 +41,7 @@ function getEntry(rootDir: string) { } return { runtime: ['react', 'react-dom', '@ice/runtime'], - index: { + main: { import: [entryFile], dependOn: 'runtime', }, diff --git a/packages/ice/src/routes.ts b/packages/ice/src/routes.ts index 64bde6cae..355c90e52 100644 --- a/packages/ice/src/routes.ts +++ b/packages/ice/src/routes.ts @@ -24,7 +24,7 @@ function generateNestRoutesStr(nestRouteManifest: NestedRouteManifest[]) { let str = `{ path: '${routePath || ''}', - load: () => import(/* webpackChunkName: "${componentName}" */ '@/${componentFile}'), + load: () => import(/* webpackChunkName: "${componentName}" */ '@/pages/${componentFile}'), componentName: '${componentName}', index: ${index}, id: '${id}', diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 927f9f9af..c1301d296 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -207,7 +207,7 @@ function findParentRouteId( return routeIds.find((id) => { // childRouteId is `pages/about` and id is `pages/layout` will match // childRouteId is `pages/about/index` and id is `pages/about/layout` will match - return childRouteId !== id && id.endsWith('layout') && childRouteId.startsWith(`${id.slice(0, id.length - '/layout'.length)}`); + return childRouteId !== id && id.endsWith('layout') && childRouteId.startsWith(`${id.slice(0, id.length - 'layout'.length)}`); }); } @@ -239,5 +239,5 @@ function visitFiles( * /About/layout/index -> /About/layout/index */ function removeLastLayoutStrFromId(id?: string) { - return id?.endsWith('/layout') ? id.slice(0, id.length - '/layout'.length) : id; + return id?.endsWith('layout') ? id.slice(0, id.length - 'layout'.length) : id; } diff --git a/packages/route-manifest/src/routes.ts b/packages/route-manifest/src/routes.ts index 190886bf3..ec7c88422 100644 --- a/packages/route-manifest/src/routes.ts +++ b/packages/route-manifest/src/routes.ts @@ -100,8 +100,8 @@ export function defineRoutes( // route(path, file, options) options = optionsOrChildren || {}; } - const pageFilePath = join('pages', file); - const id = createRouteId(pageFilePath); + + const id = createRouteId(file); const route: ConfigRoute = { path, index: options.index ? true : undefined, @@ -110,7 +110,7 @@ export function defineRoutes( parentRoutes.length > 0 ? parentRoutes[parentRoutes.length - 1].id : undefined, - file: pageFilePath, + file, componentName: createComponentName(id), }; @@ -144,7 +144,7 @@ function stripFileExtension(file: string) { function createComponentName(id: string) { return id.replace('.', '/') // 'pages/home.news' -> pages/home/news - .split('/') - .map((item: string) => item[0].toUpperCase() + item.slice(1, item.length)) - .join(''); + .split('/') + .map((item: string) => item.toLowerCase()) + .join('-'); } \ No newline at end of file diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap index b7fd3df66..40223c04b 100644 --- a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -2,145 +2,145 @@ exports[`generateRouteManifest function basic-routes 1`] = ` Object { - "pages/About/index": Object { - "componentName": "PagesAboutIndex", - "file": "pages/About/index.tsx", - "id": "pages/About/index", + "About/index": Object { + "componentName": "about-index", + "file": "About/index.tsx", + "id": "About/index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": "About", }, - "pages/About/me/index": Object { - "componentName": "PagesAboutMeIndex", - "file": "pages/About/me/index.tsx", - "id": "pages/About/me/index", + "About/me/index": Object { + "componentName": "about-me-index", + "file": "About/me/index.tsx", + "id": "About/me/index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": "About/me", }, - "pages/home": Object { - "componentName": "PagesHome", - "file": "pages/home.tsx", - "id": "pages/home", + "home": Object { + "componentName": "home", + "file": "home.tsx", + "id": "home", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "home", }, - "pages/index": Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "index": Object { + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": undefined, }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; exports[`generateRouteManifest function define-extra-routes 1`] = ` Object { - "pages/About/index": Object { - "componentName": "PagesAboutIndex", - "file": "pages/About/index.tsx", - "id": "pages/About/index", + "About/index": Object { + "componentName": "about-index", + "file": "About/index.tsx", + "id": "About/index", "index": undefined, "parentId": undefined, "path": "/about-me", }, - "pages/About/me/index": Object { - "componentName": "PagesAboutMeIndex", - "file": "pages/About/me/index.tsx", - "id": "pages/About/me/index", + "About/me/index": Object { + "componentName": "about-me-index", + "file": "About/me/index.tsx", + "id": "About/me/index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": "About/me", }, - "pages/home": Object { - "componentName": "PagesHome", - "file": "pages/home.tsx", - "id": "pages/home", + "home": Object { + "componentName": "home", + "file": "home.tsx", + "id": "home", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "home", }, - "pages/index": Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "index": Object { + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": undefined, }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; exports[`generateRouteManifest function doc-delimeters-routes 1`] = ` Object { - "pages/home.news": Object { - "componentName": "PagesHomeNews", - "file": "pages/home.news.tsx", - "id": "pages/home.news", + "home.news": Object { + "componentName": "home-news", + "file": "home.news.tsx", + "id": "home.news", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "home/news", }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; exports[`generateRouteManifest function dynamic-routes 1`] = ` Object { - "pages/about": Object { - "componentName": "PagesAbout", - "file": "pages/about.tsx", - "id": "pages/about", + "about": Object { + "componentName": "about", + "file": "about.tsx", + "id": "about", "index": undefined, "parentId": undefined, "path": "about", }, - "pages/blog/$id": Object { - "componentName": "PagesBlog$id", - "file": "pages/blog/$id.tsx", - "id": "pages/blog/$id", + "blog/$id": Object { + "componentName": "blog-$id", + "file": "blog/$id.tsx", + "id": "blog/$id", "index": undefined, "parentId": undefined, "path": "blog/:id", }, - "pages/blog/index": Object { - "componentName": "PagesBlogIndex", - "file": "pages/blog/index.tsx", - "id": "pages/blog/index", + "blog/index": Object { + "componentName": "blog-index", + "file": "blog/index.tsx", + "id": "blog/index", "index": true, "parentId": undefined, "path": "blog", }, - "pages/index": Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "index": Object { + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, "parentId": undefined, "path": undefined, @@ -150,143 +150,143 @@ Object { exports[`generateRouteManifest function ignore-routes 1`] = ` Object { - "pages/About/me/index": Object { - "componentName": "PagesAboutMeIndex", - "file": "pages/About/me/index.tsx", - "id": "pages/About/me/index", + "About/me/index": Object { + "componentName": "about-me-index", + "file": "About/me/index.tsx", + "id": "About/me/index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": "About/me", }, - "pages/home": Object { - "componentName": "PagesHome", - "file": "pages/home.tsx", - "id": "pages/home", + "home": Object { + "componentName": "home", + "file": "home.tsx", + "id": "home", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "home", }, - "pages/index": Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "index": Object { + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": undefined, }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; exports[`generateRouteManifest function layout-routes 1`] = ` Object { - "pages/about": Object { - "componentName": "PagesAbout", - "file": "pages/about.tsx", - "id": "pages/about", + "about": Object { + "componentName": "about", + "file": "about.tsx", + "id": "about", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "about", }, - "pages/blog/$id": Object { - "componentName": "PagesBlog$id", - "file": "pages/blog/$id.tsx", - "id": "pages/blog/$id", + "blog/$id": Object { + "componentName": "blog-$id", + "file": "blog/$id.tsx", + "id": "blog/$id", "index": undefined, - "parentId": "pages/blog/layout", - "path": "/:id", + "parentId": "blog/layout", + "path": ":id", }, - "pages/blog/index": Object { - "componentName": "PagesBlogIndex", - "file": "pages/blog/index.tsx", - "id": "pages/blog/index", + "blog/index": Object { + "componentName": "blog-index", + "file": "blog/index.tsx", + "id": "blog/index", "index": true, - "parentId": "pages/blog/layout", + "parentId": "blog/layout", "path": undefined, }, - "pages/blog/layout": Object { - "componentName": "PagesBlogLayout", - "file": "pages/blog/layout.tsx", - "id": "pages/blog/layout", + "blog/layout": Object { + "componentName": "blog-layout", + "file": "blog/layout.tsx", + "id": "blog/layout", "index": undefined, - "parentId": undefined, - "path": "blog", + "parentId": "layout", + "path": "blog/", }, - "pages/home/index": Object { - "componentName": "PagesHomeIndex", - "file": "pages/home/index.tsx", - "id": "pages/home/index", + "home/index": Object { + "componentName": "home-index", + "file": "home/index.tsx", + "id": "home/index", "index": true, - "parentId": "pages/home/layout", + "parentId": "home/layout", "path": undefined, }, - "pages/home/layout": Object { - "componentName": "PagesHomeLayout", - "file": "pages/home/layout.tsx", - "id": "pages/home/layout", + "home/layout": Object { + "componentName": "home-layout", + "file": "home/layout.tsx", + "id": "home/layout", "index": undefined, - "parentId": undefined, - "path": "home", + "parentId": "layout", + "path": "home/", }, - "pages/home/layout/index": Object { - "componentName": "PagesHomeLayoutIndex", - "file": "pages/home/layout/index.tsx", - "id": "pages/home/layout/index", + "home/layout/index": Object { + "componentName": "home-layout-index", + "file": "home/layout/index.tsx", + "id": "home/layout/index", "index": true, - "parentId": "pages/home/layout", - "path": "/layout", + "parentId": "home/layout", + "path": "layout", }, - "pages/index": Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "index": Object { + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, - "parentId": undefined, + "parentId": "layout", "path": undefined, }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; exports[`generateRouteManifest function splat-routes 1`] = ` Object { - "pages/$": Object { - "componentName": "Pages$", - "file": "pages/$.tsx", - "id": "pages/$", + "$": Object { + "componentName": "$", + "file": "$.tsx", + "id": "$", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "*", }, - "pages/home": Object { - "componentName": "PagesHome", - "file": "pages/home.tsx", - "id": "pages/home", + "home": Object { + "componentName": "home", + "file": "home.tsx", + "id": "home", "index": undefined, - "parentId": undefined, + "parentId": "layout", "path": "home", }, - "pages/layout": Object { - "componentName": "PagesLayout", - "file": "pages/layout.tsx", - "id": "pages/layout", + "layout": Object { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", "index": undefined, "parentId": undefined, - "path": "layout", + "path": undefined, }, } `; From 808b00a794cd1d412102da468c381cdd936e0cbf Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 15:12:33 +0800 Subject: [PATCH 07/36] fix: watch route change --- .../src/pages/dashboard/data.tsx | 7 +++++ .../src/pages/dashboard/index.tsx | 7 +++++ .../src/pages/dashboard/layout.tsx | 12 ++++++++ .../basic-project/src/pages/detail/$id.tsx | 13 +++++++++ .../basic-project/src/pages/detail/index.tsx | 14 +++++++++ examples/basic-project/src/pages/index.tsx | 5 +++- packages/ice/src/createService.ts | 29 +++++++++++++------ packages/ice/src/getWatchEvents.ts | 15 ++++++---- packages/ice/src/service/watchSource.ts | 4 +-- packages/ice/template/index.ts.ejs | 4 +++ packages/route-manifest/src/index.ts | 5 ++-- packages/runtime/src/index.ts | 15 +++++++--- 12 files changed, 106 insertions(+), 24 deletions(-) create mode 100644 examples/basic-project/src/pages/dashboard/data.tsx create mode 100644 examples/basic-project/src/pages/dashboard/index.tsx create mode 100644 examples/basic-project/src/pages/dashboard/layout.tsx create mode 100644 examples/basic-project/src/pages/detail/$id.tsx create mode 100644 examples/basic-project/src/pages/detail/index.tsx diff --git a/examples/basic-project/src/pages/dashboard/data.tsx b/examples/basic-project/src/pages/dashboard/data.tsx new file mode 100644 index 000000000..73244ecd1 --- /dev/null +++ b/examples/basic-project/src/pages/dashboard/data.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default () => { + return ( +
data
+ ); +}; \ No newline at end of file diff --git a/examples/basic-project/src/pages/dashboard/index.tsx b/examples/basic-project/src/pages/dashboard/index.tsx new file mode 100644 index 000000000..ad35eaf3a --- /dev/null +++ b/examples/basic-project/src/pages/dashboard/index.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default () => { + return ( +
Dashboard
+ ); +}; \ No newline at end of file diff --git a/examples/basic-project/src/pages/dashboard/layout.tsx b/examples/basic-project/src/pages/dashboard/layout.tsx new file mode 100644 index 000000000..0c308ac2b --- /dev/null +++ b/examples/basic-project/src/pages/dashboard/layout.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { Outlet, Link } from 'ice'; + +export default () => { + return ( +
+

Dashboard Layout

+ data + +
+ ); +}; \ No newline at end of file diff --git a/examples/basic-project/src/pages/detail/$id.tsx b/examples/basic-project/src/pages/detail/$id.tsx new file mode 100644 index 000000000..7a15036df --- /dev/null +++ b/examples/basic-project/src/pages/detail/$id.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { useParams, Link } from 'ice'; + +export default function DetailId() { + const params = useParams(); + + return ( +
+
Detail Id: {params.id}
+ Back to Detail +
+ ); +} diff --git a/examples/basic-project/src/pages/detail/index.tsx b/examples/basic-project/src/pages/detail/index.tsx new file mode 100644 index 000000000..2658ca7a2 --- /dev/null +++ b/examples/basic-project/src/pages/detail/index.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { Link } from 'ice'; + +export default function Detail() { + return ( +
+

Detail

+
    +
  • join
  • +
  • dashboard
  • +
+
+ ); +} \ No newline at end of file diff --git a/examples/basic-project/src/pages/index.tsx b/examples/basic-project/src/pages/index.tsx index 323f928d1..3bda03406 100644 --- a/examples/basic-project/src/pages/index.tsx +++ b/examples/basic-project/src/pages/index.tsx @@ -11,7 +11,10 @@ export default function Home(props) { return ( <>

Home Page

- about +
    +
  • about
  • +
  • detail
  • +
); } diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 8ebc42423..60c93302b 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -5,6 +5,7 @@ import consola from 'consola'; import type { CommandArgs, CommandName } from 'build-scripts'; import type { ExportData } from '@ice/types/esm/generator.js'; import type { ExtendsPluginAPI } from '@ice/types/esm/plugin.js'; +import type { Config } from '@ice/types'; import Generator from './service/runtimeGenerator.js'; import { createEsbuildCompiler } from './service/compile.js'; import createWatch from './service/watchSource.js'; @@ -31,7 +32,6 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const templateDir = path.join(__dirname, '../template/'); const configFile = 'ice.config.(mts|mjs|ts|js|cjs|json)'; const dataCache = new Map(); - const generator = new Generator({ rootDir, targetDir, @@ -42,14 +42,15 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const { addWatchEvent, removeWatchEvent } = createWatch({ watchDir: rootDir, command, - watchEvents: getWatchEvents({ - generator, - rootDir, - targetDir, - templateDir, - configFile, - cache: dataCache, - }), + // watchEvents: getWatchEvents({ + // generator, + // rootDir, + // targetDir, + // templateDir, + // configFile, + // cache: dataCache, + // getCtx, + // }), }); const generatorAPI = { @@ -65,6 +66,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt addRenderFile: generator.addRenderFile, addRenderTemplate: generator.addTemplateFiles, }; + const ctx = new Context({ rootDir, command, @@ -93,12 +95,21 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt generator.setPlugins(ctx.getAllPlugin()); await ctx.setup(); + // render template before webpack compile const renderStart = new Date().getTime(); + generator.render(); + + addWatchEvent( + ...getWatchEvents({ generator, targetDir, templateDir, cache: dataCache, ctx }), + ); + consola.debug('template render cost:', new Date().getTime() - renderStart); + // define runtime env before get webpack config defineRuntimeEnv(); + const contextConfig = getContextConfig(ctx); const webTask = contextConfig.find(({ name }) => name === 'web'); const esbuildCompile = createEsbuildCompiler({ diff --git a/packages/ice/src/getWatchEvents.ts b/packages/ice/src/getWatchEvents.ts index 9f987bec4..116bd8a54 100644 --- a/packages/ice/src/getWatchEvents.ts +++ b/packages/ice/src/getWatchEvents.ts @@ -1,32 +1,34 @@ import * as path from 'path'; import consola from 'consola'; import type { WatchEvent } from '@ice/types/esm/plugin.js'; +import type { Context } from 'build-scripts'; +import type { Config } from '@ice/types'; import { generateRoutesInfo } from './routes.js'; import type Generator from './service/runtimeGenerator'; interface Options { - rootDir: string; targetDir: string; templateDir: string; - configFile: string; generator: Generator; cache: Map; + ctx: Context; } const getWatchEvents = (options: Options): WatchEvent[] => { - const { rootDir, generator, targetDir, templateDir, configFile, cache } = options; + const { generator, targetDir, templateDir, cache, ctx } = options; + const { userConfig: { routes: routesConfig }, configFile, rootDir } = ctx; const watchRoutes: WatchEvent = [ /src\/pages\/?[\w*-:.$]+$/, (eventName: string) => { if (eventName === 'add' || eventName === 'unlink') { - const routesRenderData = generateRoutesInfo(rootDir); + const routesRenderData = generateRoutesInfo(rootDir, routesConfig); const stringifiedData = JSON.stringify(routesRenderData); if (cache.get('routes') !== stringifiedData) { cache.set('routes', stringifiedData); consola.debug('[event]', `routes data regenerated: ${stringifiedData}`); generator.renderFile( path.join(templateDir, 'routes.ts.ejs'), - path.join(rootDir, targetDir, 'route.ts'), + path.join(rootDir, targetDir, 'routes.ts'), routesRenderData, ); generator.renderFile( @@ -38,6 +40,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => { } }, ]; + const watchGlobalStyle: WatchEvent = [ /src\/global.(scss|less|css)/, (event: string, filePath: string) => { @@ -49,7 +52,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => { ]; const watchConfigFile: WatchEvent = [ - new RegExp(configFile), + new RegExp(configFile as string), (event: string, filePath: string) => { if (event === 'change') { consola.warn(`Found a change in ${path.basename(filePath)}. Restart the dev server to see the changes in effect.`); diff --git a/packages/ice/src/service/watchSource.ts b/packages/ice/src/service/watchSource.ts index 518efd148..a44ab1f19 100644 --- a/packages/ice/src/service/watchSource.ts +++ b/packages/ice/src/service/watchSource.ts @@ -29,8 +29,8 @@ function createWatch(options: { return { watcher, - addWatchEvent: ([pattern, action, name]: WatchEvent) => { - watchEvents.push([pattern, action, name]); + addWatchEvent: (...args: WatchEvent[]) => { + watchEvents.push(...args); }, removeWatchEvent: (name: string) => { const eventIndex = watchEvents.findIndex(([,,watchName]) => watchName === name); diff --git a/packages/ice/template/index.ts.ejs b/packages/ice/template/index.ts.ejs index 2f6a46d59..7a92b6144 100644 --- a/packages/ice/template/index.ts.ejs +++ b/packages/ice/template/index.ts.ejs @@ -3,6 +3,8 @@ import { useAppContext, Link, Outlet, + useParams, + useSearchParams, Meta, Title, Links, @@ -16,6 +18,8 @@ export { useAppContext, Link, Outlet, + useParams, + useSearchParams, Meta, Title, Links, diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index c1301d296..49d03625e 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -235,8 +235,9 @@ function visitFiles( /** * remove `/layout` str if the routeId has it * - * /About/layout -> /About - * /About/layout/index -> /About/layout/index + * 'layout' -> '' + * 'About/layout' -> 'About' + * 'About/layout/index' -> 'About/layout/index' */ function removeLastLayoutStrFromId(id?: string) { return id?.endsWith('layout') ? id.slice(0, id.length - 'layout'.length) : id; diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 77e7eafaf..eadad8d37 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -1,6 +1,8 @@ import { Link, Outlet, + useParams, + useSearchParams, } from 'react-router-dom'; import Runtime from './runtime.js'; import App from './App.js'; @@ -14,7 +16,7 @@ import { Scripts, Main, } from './Document.js'; -import { +import type { RuntimePlugin, AppContext, AppConfig, @@ -31,15 +33,20 @@ export { runClientApp, runServerApp, useAppContext, - Link, - Outlet, Meta, Title, Links, Scripts, Main, defineAppConfig, - // types + // react-router-dom API + Link, + Outlet, + useParams, + useSearchParams, +}; + +export type { RuntimePlugin, AppContext, AppConfig, From 7eae64849fccb35c4e02ffbb0a500e3dcb967de7 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 15:12:48 +0800 Subject: [PATCH 08/36] fix: warn --- packages/ice/src/createService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 60c93302b..2336c9062 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -5,7 +5,6 @@ import consola from 'consola'; import type { CommandArgs, CommandName } from 'build-scripts'; import type { ExportData } from '@ice/types/esm/generator.js'; import type { ExtendsPluginAPI } from '@ice/types/esm/plugin.js'; -import type { Config } from '@ice/types'; import Generator from './service/runtimeGenerator.js'; import { createEsbuildCompiler } from './service/compile.js'; import createWatch from './service/watchSource.js'; From bb155b0bad09515d404eed3d7158246e3f5079db Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 16:14:09 +0800 Subject: [PATCH 09/36] fix: test --- packages/ice/src/createService.ts | 9 ------- packages/route-manifest/src/index.ts | 10 ++++++-- .../formatNestedRouteManifest.spec.ts.snap | 24 +++++++++---------- .../generateRouteManifest.spec.ts.snap | 4 ++-- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 2336c9062..9db3827f2 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -41,15 +41,6 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const { addWatchEvent, removeWatchEvent } = createWatch({ watchDir: rootDir, command, - // watchEvents: getWatchEvents({ - // generator, - // rootDir, - // targetDir, - // templateDir, - // configFile, - // cache: dataCache, - // getCtx, - // }), }); const generatorAPI = { diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 49d03625e..30eb7edd9 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -115,8 +115,11 @@ function defineConventionalRoutes( }); for (let routeId of childRouteIds) { + const parentRoutePath = removeLastLayoutStrFromId(parentId) || ''; const routePath: string | undefined = createRoutePath( - routeId.slice((removeLastLayoutStrFromId(parentId) || '').length), + // parentRoutePath = 'home', routeId = 'home/me', the new routeId is 'me' + // in order to escape the child route path is absolute path + routeId.slice(parentRoutePath.length + (parentRoutePath ? 1 : 0)), ); const routeFilePath = path.join('src', 'pages', files[routeId]); if (RegExp(`[^${validRouteChar.join(',')}]`).test(routePath)) { @@ -240,5 +243,8 @@ function visitFiles( * 'About/layout/index' -> 'About/layout/index' */ function removeLastLayoutStrFromId(id?: string) { - return id?.endsWith('layout') ? id.slice(0, id.length - 'layout'.length) : id; + const layoutStrs = ['/layout', 'layout']; + const currentLayoutStr = layoutStrs.find(layoutStr => id?.endsWith(layoutStr)); + return currentLayoutStr ? id.slice(0, id.length - currentLayoutStr.length) : id; + // return id?.endsWith('layout') ? id.slice(0, id.length - 'layout'.length) : id; } diff --git a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap index a56ffa0c9..19b03e40a 100644 --- a/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/formatNestedRouteManifest.spec.ts.snap @@ -3,33 +3,33 @@ exports[`generateRouteManifest function layout-routes 1`] = ` Array [ Object { - "componentName": "PagesBlogIndex", - "file": "pages/blog/index.tsx", - "id": "pages/blog/index", + "componentName": "blog-index", + "file": "blog/index.tsx", + "id": "blog/index", "index": true, "parentId": undefined, "path": "blog", }, Object { - "componentName": "PagesBlog$id", - "file": "pages/blog/$id.tsx", - "id": "pages/blog/$id", + "componentName": "blog-$id", + "file": "blog/$id.tsx", + "id": "blog/$id", "index": undefined, "parentId": undefined, "path": "blog/:id", }, Object { - "componentName": "PagesAbout", - "file": "pages/about.tsx", - "id": "pages/about", + "componentName": "about", + "file": "about.tsx", + "id": "about", "index": undefined, "parentId": undefined, "path": "about", }, Object { - "componentName": "PagesIndex", - "file": "pages/index.tsx", - "id": "pages/index", + "componentName": "index", + "file": "index.tsx", + "id": "index", "index": true, "parentId": undefined, "path": undefined, diff --git a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap index 40223c04b..1c445368a 100644 --- a/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap +++ b/packages/route-manifest/tests/__snapshots__/generateRouteManifest.spec.ts.snap @@ -217,7 +217,7 @@ Object { "id": "blog/layout", "index": undefined, "parentId": "layout", - "path": "blog/", + "path": "blog", }, "home/index": Object { "componentName": "home-index", @@ -233,7 +233,7 @@ Object { "id": "home/layout", "index": undefined, "parentId": "layout", - "path": "home/", + "path": "home", }, "home/layout/index": Object { "componentName": "home-layout-index", From e5c4da1c4930dd18df81f2893ae45bc9e739bac5 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 17:02:40 +0800 Subject: [PATCH 10/36] fix: test --- packages/ice/src/plugins/web/ssr/generateHtml.ts | 14 ++++++++------ packages/runtime/src/runServerApp.tsx | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/ice/src/plugins/web/ssr/generateHtml.ts b/packages/ice/src/plugins/web/ssr/generateHtml.ts index b364e7268..9288ed688 100644 --- a/packages/ice/src/plugins/web/ssr/generateHtml.ts +++ b/packages/ice/src/plugins/web/ssr/generateHtml.ts @@ -1,5 +1,5 @@ -import * as fs from 'fs'; import * as path from 'path'; +import fse from 'fs-extra'; import type { RouteItem } from '@ice/runtime'; interface Options { @@ -16,7 +16,7 @@ export default async function generateHTML(options: Options) { } = options; const serverEntry = await import(entry); - const routes = JSON.parse(fs.readFileSync(routeManifest, 'utf8')); + const routes = JSON.parse(fse.readFileSync(routeManifest, 'utf8')); const paths = getPaths(routes); for (let i = 0, n = paths.length; i < n; i++) { @@ -29,7 +29,9 @@ export default async function generateHTML(options: Options) { }); const fileName = routePath === '/' ? 'index.html' : `${routePath}.html`; - fs.writeFileSync(path.join(outDir, fileName), htmlContent); + const contentPath = path.join(outDir, fileName); + await fse.ensureFile(contentPath); + await fse.writeFile(contentPath, htmlContent); } } @@ -38,14 +40,14 @@ export default async function generateHTML(options: Options) { * @param routes * @returns */ -function getPaths(routes: RouteItem[]): string[] { +function getPaths(routes: RouteItem[], parentPath = ''): string[] { let pathList = []; routes.forEach(route => { if (route.children) { - pathList = pathList.concat(getPaths(route.children)); + pathList = pathList.concat(getPaths(route.children, route.path)); } else { - pathList.push(route.path || '/'); + pathList.push(path.join('/', parentPath, route.path || '')); } }); diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 8c286b028..0932bcde2 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -84,14 +84,14 @@ async function runServerApp(options: RunServerAppOptions): Promise { runtime.loadModule(m); }); - const html = render(Document, runtime, location, documentOnly); + const html = await render(Document, runtime, location, documentOnly); return html; } export default runServerApp; async function render( - Document, + Document: React.ComponentType<{}>, runtime: Runtime, location: Location, documentOnly: boolean, From 13f5b4936518a7505363f076966f1851b344b316 Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 17:43:47 +0800 Subject: [PATCH 11/36] chore: example --- examples/basic-project/ice.config.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index d31d0a678..f245e2526 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -1,14 +1,14 @@ import { defineUserConfig } from '@ice/app'; -// import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; export default defineUserConfig({ publicPath: '/', - // webpack: (webpackConfig) => { - // if (process.env.NODE_ENV !== 'test') { - // webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); - // } - // return webpackConfig; - // }, + webpack: (webpackConfig) => { + if (process.env.NODE_ENV !== 'test') { + webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); + } + return webpackConfig; + }, routes: { ignoreFiles: ['about.tsx'], defineRoutes: (route) => { From fd717320a9346abf62b61b7b22d76ffeffc5720e Mon Sep 17 00:00:00 2001 From: luhc228 Date: Fri, 1 Apr 2022 19:29:52 +0800 Subject: [PATCH 12/36] chore: add route-gen example --- examples/basic-project/ice.config.ts | 6 - examples/basic-project/src/pages/about.tsx | 2 +- examples/basic-project/src/pages/index.tsx | 5 +- examples/routes-generate/ice.config.ts | 14 + examples/routes-generate/package.json | 23 + examples/routes-generate/src/app.tsx | 18 + examples/routes-generate/src/document.tsx | 24 + examples/routes-generate/src/pages/about.tsx | 6 + .../src/pages/dashboard/a.tsx} | 2 +- .../routes-generate/src/pages/dashboard/b.tsx | 7 + .../src/pages/dashboard/index.tsx | 2 +- .../src/pages/dashboard/layout.tsx | 7 +- .../src/pages/detail/$id.tsx | 0 .../src/pages/detail/index.tsx | 0 examples/routes-generate/src/pages/index.tsx | 15 + examples/routes-generate/src/pages/layout.tsx | 11 + .../routes-generate/src/pages/products.tsx | 6 + examples/routes-generate/tsconfig.json | 32 + packages/ice/src/createService.ts | 2 +- packages/ice/src/getWatchEvents.ts | 2 +- packages/ice/src/routes.ts | 2 +- packages/route-manifest/src/index.ts | 1 - pnpm-lock.yaml | 907 +++++++++++------- 23 files changed, 741 insertions(+), 353 deletions(-) create mode 100644 examples/routes-generate/ice.config.ts create mode 100644 examples/routes-generate/package.json create mode 100644 examples/routes-generate/src/app.tsx create mode 100644 examples/routes-generate/src/document.tsx create mode 100644 examples/routes-generate/src/pages/about.tsx rename examples/{basic-project/src/pages/dashboard/data.tsx => routes-generate/src/pages/dashboard/a.tsx} (77%) create mode 100644 examples/routes-generate/src/pages/dashboard/b.tsx rename examples/{basic-project => routes-generate}/src/pages/dashboard/index.tsx (73%) rename examples/{basic-project => routes-generate}/src/pages/dashboard/layout.tsx (50%) rename examples/{basic-project => routes-generate}/src/pages/detail/$id.tsx (100%) rename examples/{basic-project => routes-generate}/src/pages/detail/index.tsx (100%) create mode 100644 examples/routes-generate/src/pages/index.tsx create mode 100644 examples/routes-generate/src/pages/layout.tsx create mode 100644 examples/routes-generate/src/pages/products.tsx create mode 100644 examples/routes-generate/tsconfig.json diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index f245e2526..890e35a45 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -9,11 +9,5 @@ export default defineUserConfig({ } return webpackConfig; }, - routes: { - ignoreFiles: ['about.tsx'], - defineRoutes: (route) => { - route('/about-me', 'about.tsx'); - }, - }, plugins: ['@ice/plugin-auth'], }); \ No newline at end of file diff --git a/examples/basic-project/src/pages/about.tsx b/examples/basic-project/src/pages/about.tsx index 2b02defa3..77e2ff96a 100644 --- a/examples/basic-project/src/pages/about.tsx +++ b/examples/basic-project/src/pages/about.tsx @@ -7,7 +7,7 @@ export default function About() { export function getPageConfig() { return { - // auth: ['guest'], + auth: ['guest'], }; } diff --git a/examples/basic-project/src/pages/index.tsx b/examples/basic-project/src/pages/index.tsx index 3bda03406..40632d971 100644 --- a/examples/basic-project/src/pages/index.tsx +++ b/examples/basic-project/src/pages/index.tsx @@ -11,10 +11,7 @@ export default function Home(props) { return ( <>

Home Page

-
    -
  • about
  • -
  • detail
  • -
+ about ); } diff --git a/examples/routes-generate/ice.config.ts b/examples/routes-generate/ice.config.ts new file mode 100644 index 000000000..b9db68e37 --- /dev/null +++ b/examples/routes-generate/ice.config.ts @@ -0,0 +1,14 @@ +import { defineUserConfig } from '@ice/app'; + +export default defineUserConfig({ + routes: { + ignoreFiles: ['about.tsx', 'products.tsx'], + defineRoutes: (route) => { + route('/about-me', 'about.tsx'); + + route('/', 'layout.tsx', () => { + route('/product', 'products.tsx'); + }); + }, + }, +}); \ No newline at end of file diff --git a/examples/routes-generate/package.json b/examples/routes-generate/package.json new file mode 100644 index 000000000..dc63256b0 --- /dev/null +++ b/examples/routes-generate/package.json @@ -0,0 +1,23 @@ +{ + "name": "basic-project", + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build" + }, + "description": "", + "author": "", + "license": "MIT", + "dependencies": { + "@ice/app": "file:../../packages/ice", + "@ice/runtime": "^1.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@types/react": "^17.0.39", + "@types/react-dom": "^17.0.11", + "browserslist": "^4.19.3", + "regenerator-runtime": "^0.13.9" + } +} \ No newline at end of file diff --git a/examples/routes-generate/src/app.tsx b/examples/routes-generate/src/app.tsx new file mode 100644 index 000000000..b9054210c --- /dev/null +++ b/examples/routes-generate/src/app.tsx @@ -0,0 +1,18 @@ +import { defineAppConfig } from 'ice'; + +if (process.env.ICE_RUNTIME_ERROR_BOUNDARY) { + console.log('__REMOVED__'); +} + +export default defineAppConfig({ + app: { + // @ts-expect-error loss tslib dependency + getInitialData: async (ctx) => { + return { + auth: { + admin: true, + }, + }; + }, + }, +}); diff --git a/examples/routes-generate/src/document.tsx b/examples/routes-generate/src/document.tsx new file mode 100644 index 000000000..1be1b41a0 --- /dev/null +++ b/examples/routes-generate/src/document.tsx @@ -0,0 +1,24 @@ +/* eslint-disable react/self-closing-comp */ +import React from 'react'; +import { Meta, Title, Links, Main, Scripts } from 'ice'; + +function Document() { + return ( + + + + + + + + <Links /> + </head> + <body> + <Main /> + <Scripts /> + </body> + </html> + ); +} + +export default Document; \ No newline at end of file diff --git a/examples/routes-generate/src/pages/about.tsx b/examples/routes-generate/src/pages/about.tsx new file mode 100644 index 000000000..cd85ebeda --- /dev/null +++ b/examples/routes-generate/src/pages/about.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; +import { Link } from 'ice'; + +export default function About() { + return <><h2>About Page</h2><Link to="/">home</Link></>; +} diff --git a/examples/basic-project/src/pages/dashboard/data.tsx b/examples/routes-generate/src/pages/dashboard/a.tsx similarity index 77% rename from examples/basic-project/src/pages/dashboard/data.tsx rename to examples/routes-generate/src/pages/dashboard/a.tsx index 73244ecd1..0ab11289c 100644 --- a/examples/basic-project/src/pages/dashboard/data.tsx +++ b/examples/routes-generate/src/pages/dashboard/a.tsx @@ -2,6 +2,6 @@ import React from 'react'; export default () => { return ( - <div>data</div> + <div>a</div> ); }; \ No newline at end of file diff --git a/examples/routes-generate/src/pages/dashboard/b.tsx b/examples/routes-generate/src/pages/dashboard/b.tsx new file mode 100644 index 000000000..8fe7bae78 --- /dev/null +++ b/examples/routes-generate/src/pages/dashboard/b.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default () => { + return ( + <div>b</div> + ); +}; \ No newline at end of file diff --git a/examples/basic-project/src/pages/dashboard/index.tsx b/examples/routes-generate/src/pages/dashboard/index.tsx similarity index 73% rename from examples/basic-project/src/pages/dashboard/index.tsx rename to examples/routes-generate/src/pages/dashboard/index.tsx index ad35eaf3a..e9a67fe0c 100644 --- a/examples/basic-project/src/pages/dashboard/index.tsx +++ b/examples/routes-generate/src/pages/dashboard/index.tsx @@ -2,6 +2,6 @@ import React from 'react'; export default () => { return ( - <div>Dashboard</div> + <div>Index</div> ); }; \ No newline at end of file diff --git a/examples/basic-project/src/pages/dashboard/layout.tsx b/examples/routes-generate/src/pages/dashboard/layout.tsx similarity index 50% rename from examples/basic-project/src/pages/dashboard/layout.tsx rename to examples/routes-generate/src/pages/dashboard/layout.tsx index 0c308ac2b..6c594e432 100644 --- a/examples/basic-project/src/pages/dashboard/layout.tsx +++ b/examples/routes-generate/src/pages/dashboard/layout.tsx @@ -4,8 +4,11 @@ import { Outlet, Link } from 'ice'; export default () => { return ( <div> - <h1>Dashboard Layout</h1> - <Link to="/dashboard/data">data</Link> + <h2>Dashboard</h2> + <ul> + <li><Link to="/dashboard/a">a</Link></li> + <li><Link to="/dashboard/b">b</Link></li> + </ul> <Outlet /> </div> ); diff --git a/examples/basic-project/src/pages/detail/$id.tsx b/examples/routes-generate/src/pages/detail/$id.tsx similarity index 100% rename from examples/basic-project/src/pages/detail/$id.tsx rename to examples/routes-generate/src/pages/detail/$id.tsx diff --git a/examples/basic-project/src/pages/detail/index.tsx b/examples/routes-generate/src/pages/detail/index.tsx similarity index 100% rename from examples/basic-project/src/pages/detail/index.tsx rename to examples/routes-generate/src/pages/detail/index.tsx diff --git a/examples/routes-generate/src/pages/index.tsx b/examples/routes-generate/src/pages/index.tsx new file mode 100644 index 000000000..0c9f084ef --- /dev/null +++ b/examples/routes-generate/src/pages/index.tsx @@ -0,0 +1,15 @@ +import * as React from 'react'; +import { Link } from 'ice'; + +export default function Home() { + return ( + <> + <h2>Home</h2> + <ul> + <li><Link to="/about-me">about</Link></li> + <li><Link to="/detail">detail</Link></li> + <li><Link to="/dashboard">dashboard</Link></li> + </ul> + </> + ); +} diff --git a/examples/routes-generate/src/pages/layout.tsx b/examples/routes-generate/src/pages/layout.tsx new file mode 100644 index 000000000..45c897cd4 --- /dev/null +++ b/examples/routes-generate/src/pages/layout.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { Outlet } from 'ice'; + +export default () => { + return ( + <div> + <h1>Layout</h1> + <Outlet /> + </div> + ); +}; \ No newline at end of file diff --git a/examples/routes-generate/src/pages/products.tsx b/examples/routes-generate/src/pages/products.tsx new file mode 100644 index 000000000..ebea3a78c --- /dev/null +++ b/examples/routes-generate/src/pages/products.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; +import { Link } from 'ice'; + +export default function Products() { + return <><h2>Products Page</h2><Link to="/">home</Link></>; +} diff --git a/examples/routes-generate/tsconfig.json b/examples/routes-generate/tsconfig.json new file mode 100644 index 000000000..1abf2c77d --- /dev/null +++ b/examples/routes-generate/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react", + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "lib": ["es6", "dom"], + "sourceMap": true, + "allowJs": true, + "rootDir": "./", + "forceConsistentCasingInFileNames": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": false, + "importHelpers": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "noUnusedLocals": true, + "skipLibCheck": true, + "paths": { + "@/*": ["./src/*"], + "ice": [".ice"] + } + }, + "include": ["src", ".ice", "ice.config.*"], + "exclude": ["node_modules", "build", "public"] +} \ No newline at end of file diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 9db3827f2..52829cf48 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -81,7 +81,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt ...renderData, ...routesRenderData, })); - dataCache.set('routes', JSON.stringify(routesRenderData)); + dataCache.set('routes', JSON.stringify(routesRenderData.routeManifest)); generator.setPlugins(ctx.getAllPlugin()); await ctx.setup(); diff --git a/packages/ice/src/getWatchEvents.ts b/packages/ice/src/getWatchEvents.ts index 116bd8a54..5fce7ed53 100644 --- a/packages/ice/src/getWatchEvents.ts +++ b/packages/ice/src/getWatchEvents.ts @@ -52,7 +52,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => { ]; const watchConfigFile: WatchEvent = [ - new RegExp(configFile as string), + new RegExp((typeof configFile === 'string' ? [configFile] : configFile).join('|')), (event: string, filePath: string) => { if (event === 'change') { consola.warn(`Found a change in ${path.basename(filePath)}. Restart the dev server to see the changes in effect.`); diff --git a/packages/ice/src/routes.ts b/packages/ice/src/routes.ts index 355c90e52..0b2a233c5 100644 --- a/packages/ice/src/routes.ts +++ b/packages/ice/src/routes.ts @@ -3,7 +3,7 @@ import { formatNestedRouteManifest, generateRouteManifest } from '@ice/route-man import type { NestedRouteManifest } from '@ice/route-manifest'; import type { UserConfig } from '@ice/types'; -export function generateRoutesInfo(rootDir: string, routesConfig?: UserConfig['routes']) { +export function generateRoutesInfo(rootDir: string, routesConfig: UserConfig['routes'] = {}) { const routeManifest = generateRouteManifest(rootDir, routesConfig.ignoreFiles, routesConfig.defineRoutes); const routes = formatNestedRouteManifest(routeManifest); const str = generateNestRoutesStr(routes); diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index 30eb7edd9..dd98fa2e5 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -246,5 +246,4 @@ function removeLastLayoutStrFromId(id?: string) { const layoutStrs = ['/layout', 'layout']; const currentLayoutStr = layoutStrs.find(layoutStr => id?.endsWith(layoutStr)); return currentLayoutStr ? id.slice(0, id.length - currentLayoutStr.length) : id; - // return id?.endsWith('layout') ? id.slice(0, id.length - 'layout'.length) : id; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c3c1ff42..31033e14d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,6 +93,27 @@ importers: regenerator-runtime: 0.13.9 webpack-bundle-analyzer: 4.5.0 + examples/routes-generate: + specifiers: + '@ice/app': file:../../packages/ice + '@ice/runtime': ^1.0.0 + '@types/react': ^17.0.39 + '@types/react-dom': ^17.0.11 + browserslist: ^4.19.3 + react: ^17.0.2 + react-dom: ^17.0.2 + regenerator-runtime: ^0.13.9 + dependencies: + '@ice/app': link:../../packages/ice + '@ice/runtime': link:../../packages/runtime + react: registry.npm.alibaba-inc.com/react/17.0.2 + react-dom: registry.npm.alibaba-inc.com/react-dom/17.0.2_react@17.0.2 + devDependencies: + '@types/react': registry.npm.alibaba-inc.com/@types/react/17.0.39 + '@types/react-dom': registry.npm.alibaba-inc.com/@types/react-dom/17.0.11 + browserslist: registry.npm.alibaba-inc.com/browserslist/4.19.3 + regenerator-runtime: registry.npm.alibaba-inc.com/regenerator-runtime/0.13.9 + packages/build-webpack-config: specifiers: '@builder/pack': ^0.6.0 @@ -800,15 +821,6 @@ packages: workbox-strategies: 6.4.2 dev: false - /@builder/swc-darwin-arm64/0.1.3: - resolution: {integrity: sha512-Sm69HjiM3bTFjWQqxpA6x9cnvK8c/RJfA9uyN5ypxAjEq8F9O1sV8qrzjmELUqdnSDcjG1DE3VFWNeyjgrA2Qg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - /@builder/swc-darwin-x64/0.1.3: resolution: {integrity: sha512-SC4Mj1/nMurpDfT6TgydhfyOEraC77e6wYXpp6X+TbujYYXAXuDgTj682llNOfl79cU2ouBMk0flnGt37td7aA==} engines: {node: '>= 10'} @@ -818,34 +830,16 @@ packages: dev: false optional: true - /@builder/swc-linux-x64-gnu/0.1.3: - resolution: {integrity: sha512-YV2T5RFb19Lo2KzAuwIKRXyTxtLNxb/UfNuZ3xdNDLX5p8jaCw1U3X8q1sCY7phXcHz2w9drdXlK/om+0zPfjw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - /@builder/swc-win32-x64-msvc/0.1.3: - resolution: {integrity: sha512-BAc63zk6gAm9kvG+lpnevDoeVD7l9QLpM9MYZjTN/UnHhh/zl2lVCVj+ivSI3LpJZNVMG6OLQtAYAtmWNT83cQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false - optional: true - /@builder/swc/0.1.3: resolution: {integrity: sha512-faikwN1YjtS3JdLV8QMM7angXZuXhBPFnmgkXWP8iBh/wk+DGOWUkcybrgCt7B0rgceWHyZv/l2eNlAJI3bKfg==} engines: {node: '>= 10'} dependencies: '@napi-rs/triples': 1.1.0 optionalDependencies: - '@builder/swc-darwin-arm64': 0.1.3 + '@builder/swc-darwin-arm64': registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/0.1.3 '@builder/swc-darwin-x64': 0.1.3 - '@builder/swc-linux-x64-gnu': 0.1.3 - '@builder/swc-win32-x64-msvc': 0.1.3 + '@builder/swc-linux-x64-gnu': registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/0.1.3 + '@builder/swc-win32-x64-msvc': registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/0.1.3 dev: false /@commitlint/cli/16.2.1: @@ -1353,36 +1347,6 @@ packages: '@sinonjs/commons': 1.8.3 dev: true - /@swc/core-android-arm-eabi/1.2.146: - resolution: {integrity: sha512-vRlxDksEDdprqfj9VACYUGyCJr/tYLetNjhjel46qmKoXU5uAib1WLWWgMB1Ur+oh8eCSTN8cnOblOziqfC1Rw==} - engines: {node: '>=10'} - cpu: [arm] - os: [android] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-android-arm64/1.2.146: - resolution: {integrity: sha512-YoJygRvjZ6IXvWstYZHGThEj1aWshzoMohX0i6WH5NIZhkzeF0UhRu/IZoS9VcQsd0WtDEMQe0G0wcrd/FToNg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [android] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-darwin-arm64/1.2.146: - resolution: {integrity: sha512-ftAyhczQHSUQo1Mox/VyZ3YL9KtG0LgOFUUUuLD3Pb9zKQB20Jc/Dfnh/bFktemVG8XiH0rOyR9yEI2EANHuEA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - hasBin: true - requiresBuild: true - dev: false - optional: true - /@swc/core-darwin-x64/1.2.146: resolution: {integrity: sha512-mYRN/WTS7TfYt3jqJYghcrpAW7zkpjdeEx9Rot8rmUEmk97luh9Bcwqafzjb9ndoG1mAiaTQcqvs/QqT2efS5Q==} engines: {node: '>=10'} @@ -1393,113 +1357,23 @@ packages: dev: false optional: true - /@swc/core-freebsd-x64/1.2.146: - resolution: {integrity: sha512-eYU5g7p/dY98+hvg3VJtwiX+btRWnq+WO4y4M+X1nguqghvuTv6jtVLeHDNr8FEhc+FMSJPYKO321ZVa0xCKXw==} - engines: {node: '>=10'} - cpu: [x64] - os: [freebsd] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-linux-arm-gnueabihf/1.2.146: - resolution: {integrity: sha512-ahKwlP9b41HUlwY+0eRJjgG4yJZN+uT16iBB2X7VedipmRO0aOOaP8xLReDjn4Z13DL14iAPC6Jnxiaw5rl8LQ==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-linux-arm64-gnu/1.2.146: - resolution: {integrity: sha512-S/0EJI8BWBQtsyIuYwVg+Gq03NlGl/xWOJgwLJss5+DawvxK8YZFteczw7M/bN/E5D2TqZRyybLM6baQozgDAg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-linux-arm64-musl/1.2.146: - resolution: {integrity: sha512-tOHcanuqgniMwUWMwjA+zr/hZyVn931l8DiIi3Mthyplp/PDY68PVAUJ8miJd4C5XDPcYfPOe5kRyXsFrdZzhw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-linux-x64-gnu/1.2.146: - resolution: {integrity: sha512-w9jHnFe1XLYfQYWkaJwKgmtb/HKsgyFy0sCQpVjgDq/+ds8PPyACthDINpiEMsAOFN+IfE59HDn4A2gN3qyVgg==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-linux-x64-musl/1.2.146: - resolution: {integrity: sha512-iwKiHvV8p48/82+eJRCy/WcnAZBOFr2ZJ5VLtRuV+sz0mkWjoimnLZ8SEshoru9PVoKF7hfG7AMqKaVOUjSJFg==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-win32-arm64-msvc/1.2.146: - resolution: {integrity: sha512-n21riIEGTPim19Y0mrBIDVZfOrYdfd2W8QEgbiG/f+kcOlWckvyh9ZKexd6D8QpHe73C4lOX1RrmH3DgnPGhqA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-win32-ia32-msvc/1.2.146: - resolution: {integrity: sha512-5b99VzxvTqTQCZDmpKrGevUc9SK0QBiGZG4Oeh5CnSJyx8SZU0A3R7rbMoSR5/raP9OA/0ZvlXefUDXIsKNadA==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - - /@swc/core-win32-x64-msvc/1.2.146: - resolution: {integrity: sha512-P45vAh0hR9dISIceSv6MkypjT0WduLWB4U8LPoCneeAw7mA1U7liS0Uu1PeiafxQVMWg8SNyIJFDcSg/haLJgg==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - /@swc/core/1.2.146: resolution: {integrity: sha512-axIapm2mReT45ILuYxwe0xEWqtITj3dyfDIGIgdC8Tx7ss5vpXvr22UbDSUTRIS+nypFy6hViIR1RhXE1hXnig==} engines: {node: '>=10'} optionalDependencies: - '@swc/core-android-arm-eabi': 1.2.146 - '@swc/core-android-arm64': 1.2.146 - '@swc/core-darwin-arm64': 1.2.146 + '@swc/core-android-arm-eabi': registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/1.2.146 + '@swc/core-android-arm64': registry.npm.alibaba-inc.com/@swc/core-android-arm64/1.2.146 + '@swc/core-darwin-arm64': registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/1.2.146 '@swc/core-darwin-x64': 1.2.146 - '@swc/core-freebsd-x64': 1.2.146 - '@swc/core-linux-arm-gnueabihf': 1.2.146 - '@swc/core-linux-arm64-gnu': 1.2.146 - '@swc/core-linux-arm64-musl': 1.2.146 - '@swc/core-linux-x64-gnu': 1.2.146 - '@swc/core-linux-x64-musl': 1.2.146 - '@swc/core-win32-arm64-msvc': 1.2.146 - '@swc/core-win32-ia32-msvc': 1.2.146 - '@swc/core-win32-x64-msvc': 1.2.146 + '@swc/core-freebsd-x64': registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/1.2.146 + '@swc/core-linux-arm-gnueabihf': registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/1.2.146 + '@swc/core-linux-arm64-gnu': registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/1.2.146 + '@swc/core-linux-arm64-musl': registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/1.2.146 + '@swc/core-linux-x64-gnu': registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/1.2.146 + '@swc/core-linux-x64-musl': registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/1.2.146 + '@swc/core-win32-arm64-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/1.2.146 + '@swc/core-win32-ia32-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/1.2.146 + '@swc/core-win32-x64-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/1.2.146 dev: false /@tootallnate/once/1.1.2: @@ -1768,14 +1642,6 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@types/yauzl/2.9.2: - resolution: {integrity: sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==} - requiresBuild: true - dependencies: - '@types/node': 17.0.19 - dev: true - optional: true - /@typescript-eslint/eslint-plugin/5.14.0_9ddc5cf84647bb617a6e52d8169a070d: resolution: {integrity: sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3230,14 +3096,6 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-android-arm64/0.14.23: - resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - /esbuild-darwin-64/0.14.23: resolution: {integrity: sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==} engines: {node: '>=12'} @@ -3246,116 +3104,12 @@ packages: requiresBuild: true optional: true - /esbuild-darwin-arm64/0.14.23: - resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - /esbuild-freebsd-64/0.14.23: - resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - /esbuild-freebsd-arm64/0.14.23: - resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - /esbuild-linux-32/0.14.23: - resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-64/0.14.23: - resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-arm/0.14.23: - resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-arm64/0.14.23: - resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-mips64le/0.14.23: - resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-ppc64le/0.14.23: - resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-riscv64/0.14.23: - resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-linux-s390x/0.14.23: - resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - /esbuild-netbsd-64/0.14.23: - resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - /esbuild-node-loader/0.6.5: resolution: {integrity: sha512-uPP+dllWm38cFvDysdocutN3lfe5pTIbddAHp1ENyLzpHYqE2r+3Wo+pfg9X3p8DFWwzIisft5YkeBIthIcixw==} dependencies: esbuild: 0.14.23 dev: true - /esbuild-openbsd-64/0.14.23: - resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - /esbuild-register/3.3.2_esbuild@0.14.23: resolution: {integrity: sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==} peerDependencies: @@ -3364,63 +3118,31 @@ packages: esbuild: 0.14.23 dev: true - /esbuild-sunos-64/0.14.23: - resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - /esbuild-windows-32/0.14.23: - resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - /esbuild-windows-64/0.14.23: - resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - /esbuild-windows-arm64/0.14.23: - resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - /esbuild/0.14.23: resolution: {integrity: sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - esbuild-android-arm64: 0.14.23 + esbuild-android-arm64: registry.npm.alibaba-inc.com/esbuild-android-arm64/0.14.23 esbuild-darwin-64: 0.14.23 - esbuild-darwin-arm64: 0.14.23 - esbuild-freebsd-64: 0.14.23 - esbuild-freebsd-arm64: 0.14.23 - esbuild-linux-32: 0.14.23 - esbuild-linux-64: 0.14.23 - esbuild-linux-arm: 0.14.23 - esbuild-linux-arm64: 0.14.23 - esbuild-linux-mips64le: 0.14.23 - esbuild-linux-ppc64le: 0.14.23 - esbuild-linux-riscv64: 0.14.23 - esbuild-linux-s390x: 0.14.23 - esbuild-netbsd-64: 0.14.23 - esbuild-openbsd-64: 0.14.23 - esbuild-sunos-64: 0.14.23 - esbuild-windows-32: 0.14.23 - esbuild-windows-64: 0.14.23 - esbuild-windows-arm64: 0.14.23 + esbuild-darwin-arm64: registry.npm.alibaba-inc.com/esbuild-darwin-arm64/0.14.23 + esbuild-freebsd-64: registry.npm.alibaba-inc.com/esbuild-freebsd-64/0.14.23 + esbuild-freebsd-arm64: registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/0.14.23 + esbuild-linux-32: registry.npm.alibaba-inc.com/esbuild-linux-32/0.14.23 + esbuild-linux-64: registry.npm.alibaba-inc.com/esbuild-linux-64/0.14.23 + esbuild-linux-arm: registry.npm.alibaba-inc.com/esbuild-linux-arm/0.14.23 + esbuild-linux-arm64: registry.npm.alibaba-inc.com/esbuild-linux-arm64/0.14.23 + esbuild-linux-mips64le: registry.npm.alibaba-inc.com/esbuild-linux-mips64le/0.14.23 + esbuild-linux-ppc64le: registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/0.14.23 + esbuild-linux-riscv64: registry.npm.alibaba-inc.com/esbuild-linux-riscv64/0.14.23 + esbuild-linux-s390x: registry.npm.alibaba-inc.com/esbuild-linux-s390x/0.14.23 + esbuild-netbsd-64: registry.npm.alibaba-inc.com/esbuild-netbsd-64/0.14.23 + esbuild-openbsd-64: registry.npm.alibaba-inc.com/esbuild-openbsd-64/0.14.23 + esbuild-sunos-64: registry.npm.alibaba-inc.com/esbuild-sunos-64/0.14.23 + esbuild-windows-32: registry.npm.alibaba-inc.com/esbuild-windows-32/0.14.23 + esbuild-windows-64: registry.npm.alibaba-inc.com/esbuild-windows-64/0.14.23 + esbuild-windows-arm64: registry.npm.alibaba-inc.com/esbuild-windows-arm64/0.14.23 /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz} @@ -3453,7 +3175,7 @@ packages: esutils: 2.0.3 optionator: 0.8.3 optionalDependencies: - source-map: 0.6.1 + source-map: registry.npm.alibaba-inc.com/source-map/0.6.1 dev: true /eslint-config-ali/13.1.0_eslint@8.9.0: @@ -3833,7 +3555,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.9.2 + '@types/yauzl': registry.npm.alibaba-inc.com/@types/yauzl/2.9.2 transitivePeerDependencies: - supports-color dev: true @@ -8108,3 +7830,520 @@ packages: /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + + registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/0.1.3: + resolution: {integrity: sha1-IGScpKGAsHOccP4NlOeIO9tzIJA=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/download/@builder/swc-darwin-arm64-0.1.3.tgz} + name: '@builder/swc-darwin-arm64' + version: 0.1.3 + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/0.1.3: + resolution: {integrity: sha1-AN+p0VdFZtllSS3cmDQr7NqBP/Y=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/download/@builder/swc-linux-x64-gnu-0.1.3.tgz} + name: '@builder/swc-linux-x64-gnu' + version: 0.1.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/0.1.3: + resolution: {integrity: sha1-1twcTcgRYxOX60MrNGdbhvfQGgU=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/download/@builder/swc-win32-x64-msvc-0.1.3.tgz} + name: '@builder/swc-win32-x64-msvc' + version: 0.1.3 + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/1.2.146: + resolution: {integrity: sha512-vRlxDksEDdprqfj9VACYUGyCJr/tYLetNjhjel46qmKoXU5uAib1WLWWgMB1Ur+oh8eCSTN8cnOblOziqfC1Rw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/download/@swc/core-android-arm-eabi-1.2.146.tgz} + name: '@swc/core-android-arm-eabi' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm] + os: [android] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-android-arm64/1.2.146: + resolution: {integrity: sha512-YoJygRvjZ6IXvWstYZHGThEj1aWshzoMohX0i6WH5NIZhkzeF0UhRu/IZoS9VcQsd0WtDEMQe0G0wcrd/FToNg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-android-arm64/download/@swc/core-android-arm64-1.2.146.tgz} + name: '@swc/core-android-arm64' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm64] + os: [android] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/1.2.146: + resolution: {integrity: sha512-ftAyhczQHSUQo1Mox/VyZ3YL9KtG0LgOFUUUuLD3Pb9zKQB20Jc/Dfnh/bFktemVG8XiH0rOyR9yEI2EANHuEA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/download/@swc/core-darwin-arm64-1.2.146.tgz} + name: '@swc/core-darwin-arm64' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/1.2.146: + resolution: {integrity: sha512-eYU5g7p/dY98+hvg3VJtwiX+btRWnq+WO4y4M+X1nguqghvuTv6jtVLeHDNr8FEhc+FMSJPYKO321ZVa0xCKXw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/download/@swc/core-freebsd-x64-1.2.146.tgz} + name: '@swc/core-freebsd-x64' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [x64] + os: [freebsd] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/1.2.146: + resolution: {integrity: sha512-ahKwlP9b41HUlwY+0eRJjgG4yJZN+uT16iBB2X7VedipmRO0aOOaP8xLReDjn4Z13DL14iAPC6Jnxiaw5rl8LQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/download/@swc/core-linux-arm-gnueabihf-1.2.146.tgz} + name: '@swc/core-linux-arm-gnueabihf' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/1.2.146: + resolution: {integrity: sha512-S/0EJI8BWBQtsyIuYwVg+Gq03NlGl/xWOJgwLJss5+DawvxK8YZFteczw7M/bN/E5D2TqZRyybLM6baQozgDAg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/download/@swc/core-linux-arm64-gnu-1.2.146.tgz} + name: '@swc/core-linux-arm64-gnu' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/1.2.146: + resolution: {integrity: sha512-tOHcanuqgniMwUWMwjA+zr/hZyVn931l8DiIi3Mthyplp/PDY68PVAUJ8miJd4C5XDPcYfPOe5kRyXsFrdZzhw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/download/@swc/core-linux-arm64-musl-1.2.146.tgz} + name: '@swc/core-linux-arm64-musl' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/1.2.146: + resolution: {integrity: sha512-w9jHnFe1XLYfQYWkaJwKgmtb/HKsgyFy0sCQpVjgDq/+ds8PPyACthDINpiEMsAOFN+IfE59HDn4A2gN3qyVgg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/download/@swc/core-linux-x64-gnu-1.2.146.tgz} + name: '@swc/core-linux-x64-gnu' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/1.2.146: + resolution: {integrity: sha512-iwKiHvV8p48/82+eJRCy/WcnAZBOFr2ZJ5VLtRuV+sz0mkWjoimnLZ8SEshoru9PVoKF7hfG7AMqKaVOUjSJFg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/download/@swc/core-linux-x64-musl-1.2.146.tgz} + name: '@swc/core-linux-x64-musl' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/1.2.146: + resolution: {integrity: sha512-n21riIEGTPim19Y0mrBIDVZfOrYdfd2W8QEgbiG/f+kcOlWckvyh9ZKexd6D8QpHe73C4lOX1RrmH3DgnPGhqA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/download/@swc/core-win32-arm64-msvc-1.2.146.tgz} + name: '@swc/core-win32-arm64-msvc' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/1.2.146: + resolution: {integrity: sha512-5b99VzxvTqTQCZDmpKrGevUc9SK0QBiGZG4Oeh5CnSJyx8SZU0A3R7rbMoSR5/raP9OA/0ZvlXefUDXIsKNadA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/download/@swc/core-win32-ia32-msvc-1.2.146.tgz} + name: '@swc/core-win32-ia32-msvc' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/1.2.146: + resolution: {integrity: sha512-P45vAh0hR9dISIceSv6MkypjT0WduLWB4U8LPoCneeAw7mA1U7liS0Uu1PeiafxQVMWg8SNyIJFDcSg/haLJgg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/download/@swc/core-win32-x64-msvc-1.2.146.tgz} + name: '@swc/core-win32-x64-msvc' + version: 1.2.146 + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + + registry.npm.alibaba-inc.com/@types/prop-types/15.7.4: + resolution: {integrity: sha1-/PcgXCXf95Xuea8eMNosl5CAjxE=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/prop-types/download/@types/prop-types-15.7.4.tgz} + name: '@types/prop-types' + version: 15.7.4 + dev: true + + registry.npm.alibaba-inc.com/@types/react-dom/17.0.11: + resolution: {integrity: sha1-4ercPF6GvbX3aE4AJ0riKOe8xGY=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/react-dom/download/@types/react-dom-17.0.11.tgz} + name: '@types/react-dom' + version: 17.0.11 + dependencies: + '@types/react': registry.npm.alibaba-inc.com/@types/react/17.0.39 + dev: true + + registry.npm.alibaba-inc.com/@types/react/17.0.39: + resolution: {integrity: sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/react/download/@types/react-17.0.39.tgz} + name: '@types/react' + version: 17.0.39 + dependencies: + '@types/prop-types': registry.npm.alibaba-inc.com/@types/prop-types/15.7.4 + '@types/scheduler': registry.npm.alibaba-inc.com/@types/scheduler/0.16.2 + csstype: registry.npm.alibaba-inc.com/csstype/3.0.10 + dev: true + + registry.npm.alibaba-inc.com/@types/scheduler/0.16.2: + resolution: {integrity: sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/scheduler/download/@types/scheduler-0.16.2.tgz} + name: '@types/scheduler' + version: 0.16.2 + dev: true + + registry.npm.alibaba-inc.com/@types/yauzl/2.9.2: + resolution: {integrity: sha1-xI5dVq/xREQJ45+hZLC01FUqe3o=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/yauzl/download/@types/yauzl-2.9.2.tgz} + name: '@types/yauzl' + version: 2.9.2 + requiresBuild: true + dependencies: + '@types/node': 17.0.19 + dev: true + optional: true + + registry.npm.alibaba-inc.com/browserslist/4.19.3: + resolution: {integrity: sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/browserslist/download/browserslist-4.19.3.tgz} + name: browserslist + version: 4.19.3 + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: registry.npm.alibaba-inc.com/caniuse-lite/1.0.30001312 + electron-to-chromium: registry.npm.alibaba-inc.com/electron-to-chromium/1.4.71 + escalade: registry.npm.alibaba-inc.com/escalade/3.1.1 + node-releases: registry.npm.alibaba-inc.com/node-releases/2.0.2 + picocolors: registry.npm.alibaba-inc.com/picocolors/1.0.0 + dev: true + + registry.npm.alibaba-inc.com/caniuse-lite/1.0.30001312: + resolution: {integrity: sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/caniuse-lite/download/caniuse-lite-1.0.30001312.tgz} + name: caniuse-lite + version: 1.0.30001312 + dev: true + + registry.npm.alibaba-inc.com/csstype/3.0.10: + resolution: {integrity: sha1-KtOnvtcPNbllcHwJLl8wsyfCkOU=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/csstype/download/csstype-3.0.10.tgz} + name: csstype + version: 3.0.10 + dev: true + + registry.npm.alibaba-inc.com/electron-to-chromium/1.4.71: + resolution: {integrity: sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/electron-to-chromium/download/electron-to-chromium-1.4.71.tgz} + name: electron-to-chromium + version: 1.4.71 + dev: true + + registry.npm.alibaba-inc.com/esbuild-android-arm64/0.14.23: + resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-android-arm64/download/esbuild-android-arm64-0.14.23.tgz} + name: esbuild-android-arm64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-darwin-arm64/0.14.23: + resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-darwin-arm64/download/esbuild-darwin-arm64-0.14.23.tgz} + name: esbuild-darwin-arm64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-freebsd-64/0.14.23: + resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-freebsd-64/download/esbuild-freebsd-64-0.14.23.tgz} + name: esbuild-freebsd-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/0.14.23: + resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/download/esbuild-freebsd-arm64-0.14.23.tgz} + name: esbuild-freebsd-arm64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-32/0.14.23: + resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-32/download/esbuild-linux-32-0.14.23.tgz} + name: esbuild-linux-32 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-64/0.14.23: + resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-64/download/esbuild-linux-64-0.14.23.tgz} + name: esbuild-linux-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-arm/0.14.23: + resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-arm/download/esbuild-linux-arm-0.14.23.tgz} + name: esbuild-linux-arm + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-arm64/0.14.23: + resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-arm64/download/esbuild-linux-arm64-0.14.23.tgz} + name: esbuild-linux-arm64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-mips64le/0.14.23: + resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-mips64le/download/esbuild-linux-mips64le-0.14.23.tgz} + name: esbuild-linux-mips64le + version: 0.14.23 + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/0.14.23: + resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/download/esbuild-linux-ppc64le-0.14.23.tgz} + name: esbuild-linux-ppc64le + version: 0.14.23 + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-riscv64/0.14.23: + resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-riscv64/download/esbuild-linux-riscv64-0.14.23.tgz} + name: esbuild-linux-riscv64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-linux-s390x/0.14.23: + resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-s390x/download/esbuild-linux-s390x-0.14.23.tgz} + name: esbuild-linux-s390x + version: 0.14.23 + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-netbsd-64/0.14.23: + resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-netbsd-64/download/esbuild-netbsd-64-0.14.23.tgz} + name: esbuild-netbsd-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-openbsd-64/0.14.23: + resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-openbsd-64/download/esbuild-openbsd-64-0.14.23.tgz} + name: esbuild-openbsd-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-sunos-64/0.14.23: + resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-sunos-64/download/esbuild-sunos-64-0.14.23.tgz} + name: esbuild-sunos-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-windows-32/0.14.23: + resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-32/download/esbuild-windows-32-0.14.23.tgz} + name: esbuild-windows-32 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-windows-64/0.14.23: + resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-64/download/esbuild-windows-64-0.14.23.tgz} + name: esbuild-windows-64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/esbuild-windows-arm64/0.14.23: + resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-arm64/download/esbuild-windows-arm64-0.14.23.tgz} + name: esbuild-windows-arm64 + version: 0.14.23 + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + registry.npm.alibaba-inc.com/escalade/3.1.1: + resolution: {integrity: sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/escalade/download/escalade-3.1.1.tgz} + name: escalade + version: 3.1.1 + engines: {node: '>=6'} + dev: true + + registry.npm.alibaba-inc.com/js-tokens/4.0.0: + resolution: {integrity: sha1-GSA/tZmR35jjoocFDUZHzerzJJk=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/js-tokens/download/js-tokens-4.0.0.tgz} + name: js-tokens + version: 4.0.0 + dev: false + + registry.npm.alibaba-inc.com/loose-envify/1.4.0: + resolution: {integrity: sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/loose-envify/download/loose-envify-1.4.0.tgz} + name: loose-envify + version: 1.4.0 + hasBin: true + dependencies: + js-tokens: registry.npm.alibaba-inc.com/js-tokens/4.0.0 + dev: false + + registry.npm.alibaba-inc.com/node-releases/2.0.2: + resolution: {integrity: sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/node-releases/download/node-releases-2.0.2.tgz} + name: node-releases + version: 2.0.2 + dev: true + + registry.npm.alibaba-inc.com/object-assign/4.1.1: + resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/object-assign/download/object-assign-4.1.1.tgz} + name: object-assign + version: 4.1.1 + engines: {node: '>=0.10.0'} + dev: false + + registry.npm.alibaba-inc.com/picocolors/1.0.0: + resolution: {integrity: sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/picocolors/download/picocolors-1.0.0.tgz} + name: picocolors + version: 1.0.0 + dev: true + + registry.npm.alibaba-inc.com/react-dom/17.0.2_react@17.0.2: + resolution: {integrity: sha1-7P+2hF462Nv83EmPDQqTlzZQLCM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/react-dom/download/react-dom-17.0.2.tgz} + id: registry.npm.alibaba-inc.com/react-dom/17.0.2 + name: react-dom + version: 17.0.2 + peerDependencies: + react: 17.0.2 + dependencies: + loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 + object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 + react: registry.npm.alibaba-inc.com/react/17.0.2 + scheduler: registry.npm.alibaba-inc.com/scheduler/0.20.2 + dev: false + + registry.npm.alibaba-inc.com/react/17.0.2: + resolution: {integrity: sha1-0LXMUW0p6z7uOD91tihkz7aAADc=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/react/download/react-17.0.2.tgz} + name: react + version: 17.0.2 + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 + object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 + dev: false + + registry.npm.alibaba-inc.com/regenerator-runtime/0.13.9: + resolution: {integrity: sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/regenerator-runtime/download/regenerator-runtime-0.13.9.tgz} + name: regenerator-runtime + version: 0.13.9 + dev: true + + registry.npm.alibaba-inc.com/scheduler/0.20.2: + resolution: {integrity: sha1-S67jlDbjSqk7SHS93L8P6Li1DpE=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/scheduler/download/scheduler-0.20.2.tgz} + name: scheduler + version: 0.20.2 + dependencies: + loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 + object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 + dev: false + + registry.npm.alibaba-inc.com/source-map/0.6.1: + resolution: {integrity: sha1-dHIq8y6WFOnCh6jQu95IteLxomM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/source-map/download/source-map-0.6.1.tgz} + name: source-map + version: 0.6.1 + engines: {node: '>=0.10.0'} + dev: true + optional: true From a6fce249b324a79b1f8fa91db2b787af47842a76 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 13:41:56 +0800 Subject: [PATCH 13/36] feat: add integration test --- examples/routes-generate/src/app.tsx | 17 +- examples/routes-generate/src/pages/about.tsx | 2 +- .../routes-generate/src/pages/dashboard/a.tsx | 2 +- .../routes-generate/src/pages/dashboard/b.tsx | 2 +- .../routes-generate/src/pages/detail/$id.tsx | 2 +- pnpm-lock.yaml | 898 +++++++----------- tests/integration/routes-generate.test.ts | 107 +++ 7 files changed, 452 insertions(+), 578 deletions(-) create mode 100644 tests/integration/routes-generate.test.ts diff --git a/examples/routes-generate/src/app.tsx b/examples/routes-generate/src/app.tsx index b9054210c..c1664902e 100644 --- a/examples/routes-generate/src/app.tsx +++ b/examples/routes-generate/src/app.tsx @@ -1,18 +1,3 @@ import { defineAppConfig } from 'ice'; -if (process.env.ICE_RUNTIME_ERROR_BOUNDARY) { - console.log('__REMOVED__'); -} - -export default defineAppConfig({ - app: { - // @ts-expect-error loss tslib dependency - getInitialData: async (ctx) => { - return { - auth: { - admin: true, - }, - }; - }, - }, -}); +export default defineAppConfig({}); diff --git a/examples/routes-generate/src/pages/about.tsx b/examples/routes-generate/src/pages/about.tsx index cd85ebeda..43bfb7bae 100644 --- a/examples/routes-generate/src/pages/about.tsx +++ b/examples/routes-generate/src/pages/about.tsx @@ -2,5 +2,5 @@ import * as React from 'react'; import { Link } from 'ice'; export default function About() { - return <><h2>About Page</h2><Link to="/">home</Link></>; + return <><h2>About</h2><Link to="/">home</Link></>; } diff --git a/examples/routes-generate/src/pages/dashboard/a.tsx b/examples/routes-generate/src/pages/dashboard/a.tsx index 0ab11289c..7b5f063c5 100644 --- a/examples/routes-generate/src/pages/dashboard/a.tsx +++ b/examples/routes-generate/src/pages/dashboard/a.tsx @@ -2,6 +2,6 @@ import React from 'react'; export default () => { return ( - <div>a</div> + <h3>A page</h3> ); }; \ No newline at end of file diff --git a/examples/routes-generate/src/pages/dashboard/b.tsx b/examples/routes-generate/src/pages/dashboard/b.tsx index 8fe7bae78..1ce33353f 100644 --- a/examples/routes-generate/src/pages/dashboard/b.tsx +++ b/examples/routes-generate/src/pages/dashboard/b.tsx @@ -2,6 +2,6 @@ import React from 'react'; export default () => { return ( - <div>b</div> + <h3>B page</h3> ); }; \ No newline at end of file diff --git a/examples/routes-generate/src/pages/detail/$id.tsx b/examples/routes-generate/src/pages/detail/$id.tsx index 7a15036df..f0f0b9905 100644 --- a/examples/routes-generate/src/pages/detail/$id.tsx +++ b/examples/routes-generate/src/pages/detail/$id.tsx @@ -6,7 +6,7 @@ export default function DetailId() { return ( <div> - <div>Detail Id: {params.id}</div> + <h2>Detail id: {params.id}</h2> <Link to="/detail">Back to Detail</Link> </div> ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31033e14d..13ba6c5cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,13 +106,13 @@ importers: dependencies: '@ice/app': link:../../packages/ice '@ice/runtime': link:../../packages/runtime - react: registry.npm.alibaba-inc.com/react/17.0.2 - react-dom: registry.npm.alibaba-inc.com/react-dom/17.0.2_react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 devDependencies: - '@types/react': registry.npm.alibaba-inc.com/@types/react/17.0.39 - '@types/react-dom': registry.npm.alibaba-inc.com/@types/react-dom/17.0.11 - browserslist: registry.npm.alibaba-inc.com/browserslist/4.19.3 - regenerator-runtime: registry.npm.alibaba-inc.com/regenerator-runtime/0.13.9 + '@types/react': 17.0.39 + '@types/react-dom': 17.0.11 + browserslist: 4.19.3 + regenerator-runtime: 0.13.9 packages/build-webpack-config: specifiers: @@ -821,6 +821,15 @@ packages: workbox-strategies: 6.4.2 dev: false + /@builder/swc-darwin-arm64/0.1.3: + resolution: {integrity: sha512-Sm69HjiM3bTFjWQqxpA6x9cnvK8c/RJfA9uyN5ypxAjEq8F9O1sV8qrzjmELUqdnSDcjG1DE3VFWNeyjgrA2Qg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@builder/swc-darwin-x64/0.1.3: resolution: {integrity: sha512-SC4Mj1/nMurpDfT6TgydhfyOEraC77e6wYXpp6X+TbujYYXAXuDgTj682llNOfl79cU2ouBMk0flnGt37td7aA==} engines: {node: '>= 10'} @@ -830,16 +839,34 @@ packages: dev: false optional: true + /@builder/swc-linux-x64-gnu/0.1.3: + resolution: {integrity: sha512-YV2T5RFb19Lo2KzAuwIKRXyTxtLNxb/UfNuZ3xdNDLX5p8jaCw1U3X8q1sCY7phXcHz2w9drdXlK/om+0zPfjw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@builder/swc-win32-x64-msvc/0.1.3: + resolution: {integrity: sha512-BAc63zk6gAm9kvG+lpnevDoeVD7l9QLpM9MYZjTN/UnHhh/zl2lVCVj+ivSI3LpJZNVMG6OLQtAYAtmWNT83cQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@builder/swc/0.1.3: resolution: {integrity: sha512-faikwN1YjtS3JdLV8QMM7angXZuXhBPFnmgkXWP8iBh/wk+DGOWUkcybrgCt7B0rgceWHyZv/l2eNlAJI3bKfg==} engines: {node: '>= 10'} dependencies: '@napi-rs/triples': 1.1.0 optionalDependencies: - '@builder/swc-darwin-arm64': registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/0.1.3 + '@builder/swc-darwin-arm64': 0.1.3 '@builder/swc-darwin-x64': 0.1.3 - '@builder/swc-linux-x64-gnu': registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/0.1.3 - '@builder/swc-win32-x64-msvc': registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/0.1.3 + '@builder/swc-linux-x64-gnu': 0.1.3 + '@builder/swc-win32-x64-msvc': 0.1.3 dev: false /@commitlint/cli/16.2.1: @@ -1347,6 +1374,36 @@ packages: '@sinonjs/commons': 1.8.3 dev: true + /@swc/core-android-arm-eabi/1.2.146: + resolution: {integrity: sha512-vRlxDksEDdprqfj9VACYUGyCJr/tYLetNjhjel46qmKoXU5uAib1WLWWgMB1Ur+oh8eCSTN8cnOblOziqfC1Rw==} + engines: {node: '>=10'} + cpu: [arm] + os: [android] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-android-arm64/1.2.146: + resolution: {integrity: sha512-YoJygRvjZ6IXvWstYZHGThEj1aWshzoMohX0i6WH5NIZhkzeF0UhRu/IZoS9VcQsd0WtDEMQe0G0wcrd/FToNg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [android] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-darwin-arm64/1.2.146: + resolution: {integrity: sha512-ftAyhczQHSUQo1Mox/VyZ3YL9KtG0LgOFUUUuLD3Pb9zKQB20Jc/Dfnh/bFktemVG8XiH0rOyR9yEI2EANHuEA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + hasBin: true + requiresBuild: true + dev: false + optional: true + /@swc/core-darwin-x64/1.2.146: resolution: {integrity: sha512-mYRN/WTS7TfYt3jqJYghcrpAW7zkpjdeEx9Rot8rmUEmk97luh9Bcwqafzjb9ndoG1mAiaTQcqvs/QqT2efS5Q==} engines: {node: '>=10'} @@ -1357,23 +1414,113 @@ packages: dev: false optional: true + /@swc/core-freebsd-x64/1.2.146: + resolution: {integrity: sha512-eYU5g7p/dY98+hvg3VJtwiX+btRWnq+WO4y4M+X1nguqghvuTv6jtVLeHDNr8FEhc+FMSJPYKO321ZVa0xCKXw==} + engines: {node: '>=10'} + cpu: [x64] + os: [freebsd] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm-gnueabihf/1.2.146: + resolution: {integrity: sha512-ahKwlP9b41HUlwY+0eRJjgG4yJZN+uT16iBB2X7VedipmRO0aOOaP8xLReDjn4Z13DL14iAPC6Jnxiaw5rl8LQ==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm64-gnu/1.2.146: + resolution: {integrity: sha512-S/0EJI8BWBQtsyIuYwVg+Gq03NlGl/xWOJgwLJss5+DawvxK8YZFteczw7M/bN/E5D2TqZRyybLM6baQozgDAg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-arm64-musl/1.2.146: + resolution: {integrity: sha512-tOHcanuqgniMwUWMwjA+zr/hZyVn931l8DiIi3Mthyplp/PDY68PVAUJ8miJd4C5XDPcYfPOe5kRyXsFrdZzhw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-x64-gnu/1.2.146: + resolution: {integrity: sha512-w9jHnFe1XLYfQYWkaJwKgmtb/HKsgyFy0sCQpVjgDq/+ds8PPyACthDINpiEMsAOFN+IfE59HDn4A2gN3qyVgg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-linux-x64-musl/1.2.146: + resolution: {integrity: sha512-iwKiHvV8p48/82+eJRCy/WcnAZBOFr2ZJ5VLtRuV+sz0mkWjoimnLZ8SEshoru9PVoKF7hfG7AMqKaVOUjSJFg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-arm64-msvc/1.2.146: + resolution: {integrity: sha512-n21riIEGTPim19Y0mrBIDVZfOrYdfd2W8QEgbiG/f+kcOlWckvyh9ZKexd6D8QpHe73C4lOX1RrmH3DgnPGhqA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-ia32-msvc/1.2.146: + resolution: {integrity: sha512-5b99VzxvTqTQCZDmpKrGevUc9SK0QBiGZG4Oeh5CnSJyx8SZU0A3R7rbMoSR5/raP9OA/0ZvlXefUDXIsKNadA==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + + /@swc/core-win32-x64-msvc/1.2.146: + resolution: {integrity: sha512-P45vAh0hR9dISIceSv6MkypjT0WduLWB4U8LPoCneeAw7mA1U7liS0Uu1PeiafxQVMWg8SNyIJFDcSg/haLJgg==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + hasBin: true + requiresBuild: true + dev: false + optional: true + /@swc/core/1.2.146: resolution: {integrity: sha512-axIapm2mReT45ILuYxwe0xEWqtITj3dyfDIGIgdC8Tx7ss5vpXvr22UbDSUTRIS+nypFy6hViIR1RhXE1hXnig==} engines: {node: '>=10'} optionalDependencies: - '@swc/core-android-arm-eabi': registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/1.2.146 - '@swc/core-android-arm64': registry.npm.alibaba-inc.com/@swc/core-android-arm64/1.2.146 - '@swc/core-darwin-arm64': registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/1.2.146 + '@swc/core-android-arm-eabi': 1.2.146 + '@swc/core-android-arm64': 1.2.146 + '@swc/core-darwin-arm64': 1.2.146 '@swc/core-darwin-x64': 1.2.146 - '@swc/core-freebsd-x64': registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/1.2.146 - '@swc/core-linux-arm-gnueabihf': registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/1.2.146 - '@swc/core-linux-arm64-gnu': registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/1.2.146 - '@swc/core-linux-arm64-musl': registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/1.2.146 - '@swc/core-linux-x64-gnu': registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/1.2.146 - '@swc/core-linux-x64-musl': registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/1.2.146 - '@swc/core-win32-arm64-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/1.2.146 - '@swc/core-win32-ia32-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/1.2.146 - '@swc/core-win32-x64-msvc': registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/1.2.146 + '@swc/core-freebsd-x64': 1.2.146 + '@swc/core-linux-arm-gnueabihf': 1.2.146 + '@swc/core-linux-arm64-gnu': 1.2.146 + '@swc/core-linux-arm64-musl': 1.2.146 + '@swc/core-linux-x64-gnu': 1.2.146 + '@swc/core-linux-x64-musl': 1.2.146 + '@swc/core-win32-arm64-msvc': 1.2.146 + '@swc/core-win32-ia32-msvc': 1.2.146 + '@swc/core-win32-x64-msvc': 1.2.146 dev: false /@tootallnate/once/1.1.2: @@ -1642,6 +1789,14 @@ packages: '@types/yargs-parser': 20.2.1 dev: true + /@types/yauzl/2.9.2: + resolution: {integrity: sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==} + requiresBuild: true + dependencies: + '@types/node': 17.0.19 + dev: true + optional: true + /@typescript-eslint/eslint-plugin/5.14.0_9ddc5cf84647bb617a6e52d8169a070d: resolution: {integrity: sha512-ir0wYI4FfFUDfLcuwKzIH7sMVA+db7WYen47iRSaCGl+HMAZI9fpBwfDo45ZALD3A45ZGyHWDNLhbg8tZrMX4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3096,6 +3251,14 @@ packages: is-symbol: 1.0.4 dev: true + /esbuild-android-arm64/0.14.23: + resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + /esbuild-darwin-64/0.14.23: resolution: {integrity: sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==} engines: {node: '>=12'} @@ -3104,12 +3267,116 @@ packages: requiresBuild: true optional: true + /esbuild-darwin-arm64/0.14.23: + resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /esbuild-freebsd-64/0.14.23: + resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + /esbuild-freebsd-arm64/0.14.23: + resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + /esbuild-linux-32/0.14.23: + resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-64/0.14.23: + resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-arm/0.14.23: + resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-arm64/0.14.23: + resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-mips64le/0.14.23: + resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-ppc64le/0.14.23: + resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-riscv64/0.14.23: + resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-linux-s390x/0.14.23: + resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /esbuild-netbsd-64/0.14.23: + resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + optional: true + /esbuild-node-loader/0.6.5: resolution: {integrity: sha512-uPP+dllWm38cFvDysdocutN3lfe5pTIbddAHp1ENyLzpHYqE2r+3Wo+pfg9X3p8DFWwzIisft5YkeBIthIcixw==} dependencies: esbuild: 0.14.23 dev: true + /esbuild-openbsd-64/0.14.23: + resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + optional: true + /esbuild-register/3.3.2_esbuild@0.14.23: resolution: {integrity: sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==} peerDependencies: @@ -3118,31 +3385,63 @@ packages: esbuild: 0.14.23 dev: true + /esbuild-sunos-64/0.14.23: + resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + optional: true + + /esbuild-windows-32/0.14.23: + resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /esbuild-windows-64/0.14.23: + resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + + /esbuild-windows-arm64/0.14.23: + resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + /esbuild/0.14.23: resolution: {integrity: sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - esbuild-android-arm64: registry.npm.alibaba-inc.com/esbuild-android-arm64/0.14.23 + esbuild-android-arm64: 0.14.23 esbuild-darwin-64: 0.14.23 - esbuild-darwin-arm64: registry.npm.alibaba-inc.com/esbuild-darwin-arm64/0.14.23 - esbuild-freebsd-64: registry.npm.alibaba-inc.com/esbuild-freebsd-64/0.14.23 - esbuild-freebsd-arm64: registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/0.14.23 - esbuild-linux-32: registry.npm.alibaba-inc.com/esbuild-linux-32/0.14.23 - esbuild-linux-64: registry.npm.alibaba-inc.com/esbuild-linux-64/0.14.23 - esbuild-linux-arm: registry.npm.alibaba-inc.com/esbuild-linux-arm/0.14.23 - esbuild-linux-arm64: registry.npm.alibaba-inc.com/esbuild-linux-arm64/0.14.23 - esbuild-linux-mips64le: registry.npm.alibaba-inc.com/esbuild-linux-mips64le/0.14.23 - esbuild-linux-ppc64le: registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/0.14.23 - esbuild-linux-riscv64: registry.npm.alibaba-inc.com/esbuild-linux-riscv64/0.14.23 - esbuild-linux-s390x: registry.npm.alibaba-inc.com/esbuild-linux-s390x/0.14.23 - esbuild-netbsd-64: registry.npm.alibaba-inc.com/esbuild-netbsd-64/0.14.23 - esbuild-openbsd-64: registry.npm.alibaba-inc.com/esbuild-openbsd-64/0.14.23 - esbuild-sunos-64: registry.npm.alibaba-inc.com/esbuild-sunos-64/0.14.23 - esbuild-windows-32: registry.npm.alibaba-inc.com/esbuild-windows-32/0.14.23 - esbuild-windows-64: registry.npm.alibaba-inc.com/esbuild-windows-64/0.14.23 - esbuild-windows-arm64: registry.npm.alibaba-inc.com/esbuild-windows-arm64/0.14.23 + esbuild-darwin-arm64: 0.14.23 + esbuild-freebsd-64: 0.14.23 + esbuild-freebsd-arm64: 0.14.23 + esbuild-linux-32: 0.14.23 + esbuild-linux-64: 0.14.23 + esbuild-linux-arm: 0.14.23 + esbuild-linux-arm64: 0.14.23 + esbuild-linux-mips64le: 0.14.23 + esbuild-linux-ppc64le: 0.14.23 + esbuild-linux-riscv64: 0.14.23 + esbuild-linux-s390x: 0.14.23 + esbuild-netbsd-64: 0.14.23 + esbuild-openbsd-64: 0.14.23 + esbuild-sunos-64: 0.14.23 + esbuild-windows-32: 0.14.23 + esbuild-windows-64: 0.14.23 + esbuild-windows-arm64: 0.14.23 /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz} @@ -3175,7 +3474,7 @@ packages: esutils: 2.0.3 optionator: 0.8.3 optionalDependencies: - source-map: registry.npm.alibaba-inc.com/source-map/0.6.1 + source-map: 0.6.1 dev: true /eslint-config-ali/13.1.0_eslint@8.9.0: @@ -3555,7 +3854,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': registry.npm.alibaba-inc.com/@types/yauzl/2.9.2 + '@types/yauzl': 2.9.2 transitivePeerDependencies: - supports-color dev: true @@ -7830,520 +8129,3 @@ packages: /yocto-queue/0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - - registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/0.1.3: - resolution: {integrity: sha1-IGScpKGAsHOccP4NlOeIO9tzIJA=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-darwin-arm64/download/@builder/swc-darwin-arm64-0.1.3.tgz} - name: '@builder/swc-darwin-arm64' - version: 0.1.3 - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/0.1.3: - resolution: {integrity: sha1-AN+p0VdFZtllSS3cmDQr7NqBP/Y=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-linux-x64-gnu/download/@builder/swc-linux-x64-gnu-0.1.3.tgz} - name: '@builder/swc-linux-x64-gnu' - version: 0.1.3 - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/0.1.3: - resolution: {integrity: sha1-1twcTcgRYxOX60MrNGdbhvfQGgU=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@builder/swc-win32-x64-msvc/download/@builder/swc-win32-x64-msvc-0.1.3.tgz} - name: '@builder/swc-win32-x64-msvc' - version: 0.1.3 - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/1.2.146: - resolution: {integrity: sha512-vRlxDksEDdprqfj9VACYUGyCJr/tYLetNjhjel46qmKoXU5uAib1WLWWgMB1Ur+oh8eCSTN8cnOblOziqfC1Rw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-android-arm-eabi/download/@swc/core-android-arm-eabi-1.2.146.tgz} - name: '@swc/core-android-arm-eabi' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm] - os: [android] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-android-arm64/1.2.146: - resolution: {integrity: sha512-YoJygRvjZ6IXvWstYZHGThEj1aWshzoMohX0i6WH5NIZhkzeF0UhRu/IZoS9VcQsd0WtDEMQe0G0wcrd/FToNg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-android-arm64/download/@swc/core-android-arm64-1.2.146.tgz} - name: '@swc/core-android-arm64' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm64] - os: [android] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/1.2.146: - resolution: {integrity: sha512-ftAyhczQHSUQo1Mox/VyZ3YL9KtG0LgOFUUUuLD3Pb9zKQB20Jc/Dfnh/bFktemVG8XiH0rOyR9yEI2EANHuEA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-darwin-arm64/download/@swc/core-darwin-arm64-1.2.146.tgz} - name: '@swc/core-darwin-arm64' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/1.2.146: - resolution: {integrity: sha512-eYU5g7p/dY98+hvg3VJtwiX+btRWnq+WO4y4M+X1nguqghvuTv6jtVLeHDNr8FEhc+FMSJPYKO321ZVa0xCKXw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-freebsd-x64/download/@swc/core-freebsd-x64-1.2.146.tgz} - name: '@swc/core-freebsd-x64' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [x64] - os: [freebsd] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/1.2.146: - resolution: {integrity: sha512-ahKwlP9b41HUlwY+0eRJjgG4yJZN+uT16iBB2X7VedipmRO0aOOaP8xLReDjn4Z13DL14iAPC6Jnxiaw5rl8LQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm-gnueabihf/download/@swc/core-linux-arm-gnueabihf-1.2.146.tgz} - name: '@swc/core-linux-arm-gnueabihf' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/1.2.146: - resolution: {integrity: sha512-S/0EJI8BWBQtsyIuYwVg+Gq03NlGl/xWOJgwLJss5+DawvxK8YZFteczw7M/bN/E5D2TqZRyybLM6baQozgDAg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm64-gnu/download/@swc/core-linux-arm64-gnu-1.2.146.tgz} - name: '@swc/core-linux-arm64-gnu' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/1.2.146: - resolution: {integrity: sha512-tOHcanuqgniMwUWMwjA+zr/hZyVn931l8DiIi3Mthyplp/PDY68PVAUJ8miJd4C5XDPcYfPOe5kRyXsFrdZzhw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-arm64-musl/download/@swc/core-linux-arm64-musl-1.2.146.tgz} - name: '@swc/core-linux-arm64-musl' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/1.2.146: - resolution: {integrity: sha512-w9jHnFe1XLYfQYWkaJwKgmtb/HKsgyFy0sCQpVjgDq/+ds8PPyACthDINpiEMsAOFN+IfE59HDn4A2gN3qyVgg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-x64-gnu/download/@swc/core-linux-x64-gnu-1.2.146.tgz} - name: '@swc/core-linux-x64-gnu' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/1.2.146: - resolution: {integrity: sha512-iwKiHvV8p48/82+eJRCy/WcnAZBOFr2ZJ5VLtRuV+sz0mkWjoimnLZ8SEshoru9PVoKF7hfG7AMqKaVOUjSJFg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-linux-x64-musl/download/@swc/core-linux-x64-musl-1.2.146.tgz} - name: '@swc/core-linux-x64-musl' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/1.2.146: - resolution: {integrity: sha512-n21riIEGTPim19Y0mrBIDVZfOrYdfd2W8QEgbiG/f+kcOlWckvyh9ZKexd6D8QpHe73C4lOX1RrmH3DgnPGhqA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-arm64-msvc/download/@swc/core-win32-arm64-msvc-1.2.146.tgz} - name: '@swc/core-win32-arm64-msvc' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/1.2.146: - resolution: {integrity: sha512-5b99VzxvTqTQCZDmpKrGevUc9SK0QBiGZG4Oeh5CnSJyx8SZU0A3R7rbMoSR5/raP9OA/0ZvlXefUDXIsKNadA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-ia32-msvc/download/@swc/core-win32-ia32-msvc-1.2.146.tgz} - name: '@swc/core-win32-ia32-msvc' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/1.2.146: - resolution: {integrity: sha512-P45vAh0hR9dISIceSv6MkypjT0WduLWB4U8LPoCneeAw7mA1U7liS0Uu1PeiafxQVMWg8SNyIJFDcSg/haLJgg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@swc/core-win32-x64-msvc/download/@swc/core-win32-x64-msvc-1.2.146.tgz} - name: '@swc/core-win32-x64-msvc' - version: 1.2.146 - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - hasBin: true - requiresBuild: true - dev: false - optional: true - - registry.npm.alibaba-inc.com/@types/prop-types/15.7.4: - resolution: {integrity: sha1-/PcgXCXf95Xuea8eMNosl5CAjxE=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/prop-types/download/@types/prop-types-15.7.4.tgz} - name: '@types/prop-types' - version: 15.7.4 - dev: true - - registry.npm.alibaba-inc.com/@types/react-dom/17.0.11: - resolution: {integrity: sha1-4ercPF6GvbX3aE4AJ0riKOe8xGY=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/react-dom/download/@types/react-dom-17.0.11.tgz} - name: '@types/react-dom' - version: 17.0.11 - dependencies: - '@types/react': registry.npm.alibaba-inc.com/@types/react/17.0.39 - dev: true - - registry.npm.alibaba-inc.com/@types/react/17.0.39: - resolution: {integrity: sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/react/download/@types/react-17.0.39.tgz} - name: '@types/react' - version: 17.0.39 - dependencies: - '@types/prop-types': registry.npm.alibaba-inc.com/@types/prop-types/15.7.4 - '@types/scheduler': registry.npm.alibaba-inc.com/@types/scheduler/0.16.2 - csstype: registry.npm.alibaba-inc.com/csstype/3.0.10 - dev: true - - registry.npm.alibaba-inc.com/@types/scheduler/0.16.2: - resolution: {integrity: sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/scheduler/download/@types/scheduler-0.16.2.tgz} - name: '@types/scheduler' - version: 0.16.2 - dev: true - - registry.npm.alibaba-inc.com/@types/yauzl/2.9.2: - resolution: {integrity: sha1-xI5dVq/xREQJ45+hZLC01FUqe3o=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/@types/yauzl/download/@types/yauzl-2.9.2.tgz} - name: '@types/yauzl' - version: 2.9.2 - requiresBuild: true - dependencies: - '@types/node': 17.0.19 - dev: true - optional: true - - registry.npm.alibaba-inc.com/browserslist/4.19.3: - resolution: {integrity: sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/browserslist/download/browserslist-4.19.3.tgz} - name: browserslist - version: 4.19.3 - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: registry.npm.alibaba-inc.com/caniuse-lite/1.0.30001312 - electron-to-chromium: registry.npm.alibaba-inc.com/electron-to-chromium/1.4.71 - escalade: registry.npm.alibaba-inc.com/escalade/3.1.1 - node-releases: registry.npm.alibaba-inc.com/node-releases/2.0.2 - picocolors: registry.npm.alibaba-inc.com/picocolors/1.0.0 - dev: true - - registry.npm.alibaba-inc.com/caniuse-lite/1.0.30001312: - resolution: {integrity: sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/caniuse-lite/download/caniuse-lite-1.0.30001312.tgz} - name: caniuse-lite - version: 1.0.30001312 - dev: true - - registry.npm.alibaba-inc.com/csstype/3.0.10: - resolution: {integrity: sha1-KtOnvtcPNbllcHwJLl8wsyfCkOU=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/csstype/download/csstype-3.0.10.tgz} - name: csstype - version: 3.0.10 - dev: true - - registry.npm.alibaba-inc.com/electron-to-chromium/1.4.71: - resolution: {integrity: sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/electron-to-chromium/download/electron-to-chromium-1.4.71.tgz} - name: electron-to-chromium - version: 1.4.71 - dev: true - - registry.npm.alibaba-inc.com/esbuild-android-arm64/0.14.23: - resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-android-arm64/download/esbuild-android-arm64-0.14.23.tgz} - name: esbuild-android-arm64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-darwin-arm64/0.14.23: - resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-darwin-arm64/download/esbuild-darwin-arm64-0.14.23.tgz} - name: esbuild-darwin-arm64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-freebsd-64/0.14.23: - resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-freebsd-64/download/esbuild-freebsd-64-0.14.23.tgz} - name: esbuild-freebsd-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/0.14.23: - resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-freebsd-arm64/download/esbuild-freebsd-arm64-0.14.23.tgz} - name: esbuild-freebsd-arm64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-32/0.14.23: - resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-32/download/esbuild-linux-32-0.14.23.tgz} - name: esbuild-linux-32 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-64/0.14.23: - resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-64/download/esbuild-linux-64-0.14.23.tgz} - name: esbuild-linux-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-arm/0.14.23: - resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-arm/download/esbuild-linux-arm-0.14.23.tgz} - name: esbuild-linux-arm - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-arm64/0.14.23: - resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-arm64/download/esbuild-linux-arm64-0.14.23.tgz} - name: esbuild-linux-arm64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-mips64le/0.14.23: - resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-mips64le/download/esbuild-linux-mips64le-0.14.23.tgz} - name: esbuild-linux-mips64le - version: 0.14.23 - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/0.14.23: - resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-ppc64le/download/esbuild-linux-ppc64le-0.14.23.tgz} - name: esbuild-linux-ppc64le - version: 0.14.23 - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-riscv64/0.14.23: - resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-riscv64/download/esbuild-linux-riscv64-0.14.23.tgz} - name: esbuild-linux-riscv64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-linux-s390x/0.14.23: - resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-linux-s390x/download/esbuild-linux-s390x-0.14.23.tgz} - name: esbuild-linux-s390x - version: 0.14.23 - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-netbsd-64/0.14.23: - resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-netbsd-64/download/esbuild-netbsd-64-0.14.23.tgz} - name: esbuild-netbsd-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-openbsd-64/0.14.23: - resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-openbsd-64/download/esbuild-openbsd-64-0.14.23.tgz} - name: esbuild-openbsd-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-sunos-64/0.14.23: - resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-sunos-64/download/esbuild-sunos-64-0.14.23.tgz} - name: esbuild-sunos-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-windows-32/0.14.23: - resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-32/download/esbuild-windows-32-0.14.23.tgz} - name: esbuild-windows-32 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-windows-64/0.14.23: - resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-64/download/esbuild-windows-64-0.14.23.tgz} - name: esbuild-windows-64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/esbuild-windows-arm64/0.14.23: - resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/esbuild-windows-arm64/download/esbuild-windows-arm64-0.14.23.tgz} - name: esbuild-windows-arm64 - version: 0.14.23 - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - optional: true - - registry.npm.alibaba-inc.com/escalade/3.1.1: - resolution: {integrity: sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/escalade/download/escalade-3.1.1.tgz} - name: escalade - version: 3.1.1 - engines: {node: '>=6'} - dev: true - - registry.npm.alibaba-inc.com/js-tokens/4.0.0: - resolution: {integrity: sha1-GSA/tZmR35jjoocFDUZHzerzJJk=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/js-tokens/download/js-tokens-4.0.0.tgz} - name: js-tokens - version: 4.0.0 - dev: false - - registry.npm.alibaba-inc.com/loose-envify/1.4.0: - resolution: {integrity: sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/loose-envify/download/loose-envify-1.4.0.tgz} - name: loose-envify - version: 1.4.0 - hasBin: true - dependencies: - js-tokens: registry.npm.alibaba-inc.com/js-tokens/4.0.0 - dev: false - - registry.npm.alibaba-inc.com/node-releases/2.0.2: - resolution: {integrity: sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/node-releases/download/node-releases-2.0.2.tgz} - name: node-releases - version: 2.0.2 - dev: true - - registry.npm.alibaba-inc.com/object-assign/4.1.1: - resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/object-assign/download/object-assign-4.1.1.tgz} - name: object-assign - version: 4.1.1 - engines: {node: '>=0.10.0'} - dev: false - - registry.npm.alibaba-inc.com/picocolors/1.0.0: - resolution: {integrity: sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/picocolors/download/picocolors-1.0.0.tgz} - name: picocolors - version: 1.0.0 - dev: true - - registry.npm.alibaba-inc.com/react-dom/17.0.2_react@17.0.2: - resolution: {integrity: sha1-7P+2hF462Nv83EmPDQqTlzZQLCM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/react-dom/download/react-dom-17.0.2.tgz} - id: registry.npm.alibaba-inc.com/react-dom/17.0.2 - name: react-dom - version: 17.0.2 - peerDependencies: - react: 17.0.2 - dependencies: - loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 - object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 - react: registry.npm.alibaba-inc.com/react/17.0.2 - scheduler: registry.npm.alibaba-inc.com/scheduler/0.20.2 - dev: false - - registry.npm.alibaba-inc.com/react/17.0.2: - resolution: {integrity: sha1-0LXMUW0p6z7uOD91tihkz7aAADc=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/react/download/react-17.0.2.tgz} - name: react - version: 17.0.2 - engines: {node: '>=0.10.0'} - dependencies: - loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 - object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 - dev: false - - registry.npm.alibaba-inc.com/regenerator-runtime/0.13.9: - resolution: {integrity: sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/regenerator-runtime/download/regenerator-runtime-0.13.9.tgz} - name: regenerator-runtime - version: 0.13.9 - dev: true - - registry.npm.alibaba-inc.com/scheduler/0.20.2: - resolution: {integrity: sha1-S67jlDbjSqk7SHS93L8P6Li1DpE=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/scheduler/download/scheduler-0.20.2.tgz} - name: scheduler - version: 0.20.2 - dependencies: - loose-envify: registry.npm.alibaba-inc.com/loose-envify/1.4.0 - object-assign: registry.npm.alibaba-inc.com/object-assign/4.1.1 - dev: false - - registry.npm.alibaba-inc.com/source-map/0.6.1: - resolution: {integrity: sha1-dHIq8y6WFOnCh6jQu95IteLxomM=, registry: https://registry.antfin-inc.com/, tarball: https://registry.npm.alibaba-inc.com/source-map/download/source-map-0.6.1.tgz} - name: source-map - version: 0.6.1 - engines: {node: '>=0.10.0'} - dev: true - optional: true diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test.ts new file mode 100644 index 000000000..87e3416e3 --- /dev/null +++ b/tests/integration/routes-generate.test.ts @@ -0,0 +1,107 @@ +import { buildFixture, setupBrowser } from '../utils/build'; +import { startFixture, setupStartBrowser } from '../utils/start'; +import { Page } from '../utils/browser'; + +const example = 'routes-generate'; + +describe(`build ${example}`, () => { + let page: Page = null; + let browser = null; + + buildFixture(example); + + test('open /', async () => { + const res = await setupBrowser({ example }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Home']); + }); + + test('define extra routes', async () => { + let res = await setupBrowser({ example, defaultHtml: 'about-me.html' }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual([]); + expect(await page.$$text('h2')).toStrictEqual(['About']); + + res = await setupBrowser({ example, defaultHtml: 'product.html' }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Products Page']); + }); + + test('page layout', async () => { + let res = await setupBrowser({ example, defaultHtml: 'dashboard/a.html' }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['A page']); + + res = await setupBrowser({ example, defaultHtml: 'dashboard/b.html' }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['B page']); + }); + + // TODO: dynamic-routes test + + afterAll(async () => { + await browser.close(); + }); +}); + +describe(`start ${example}`, () => { + let page: Page = null; + let browser = null; + + test('setup devServer', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Home']); + }, 120000); + + test('define extra routes', async () => { + await page.push('about-me'); + expect(await page.$$text('h1')).toStrictEqual([]); + expect(await page.$$text('h2')).toStrictEqual(['About']); + + await page.push('product'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Products Page']); + }); + + test('page layout', async () => { + await page.push('dashboard/a'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['A page']); + + await page.push('dashboard/b'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['B page']); + }); + + test('dynamic routes layout', async () => { + await page.push('detail/a'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); + + await page.push('detail/b'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); + + }); + + afterAll(async () => { + await browser.close(); + }); +}); From a303db28cf6a61e532738cf25033d116f514cb89 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:18:47 +0800 Subject: [PATCH 14/36] chore: test --- .../{routes-generate.test.ts => routes-generate.test111.ts} | 1 - 1 file changed, 1 deletion(-) rename tests/integration/{routes-generate.test.ts => routes-generate.test111.ts} (99%) diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test111.ts similarity index 99% rename from tests/integration/routes-generate.test.ts rename to tests/integration/routes-generate.test111.ts index 87e3416e3..c37f89cd4 100644 --- a/tests/integration/routes-generate.test.ts +++ b/tests/integration/routes-generate.test111.ts @@ -98,7 +98,6 @@ describe(`start ${example}`, () => { await page.push('detail/b'); expect(await page.$$text('h1')).toStrictEqual(['Layout']); expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); - }); afterAll(async () => { From eff14494d010dda49e6ee8a2126317aa0e47e6b9 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:24:26 +0800 Subject: [PATCH 15/36] chore: update config file --- examples/routes-generate/{ice.config.ts => ice.config.js} | 0 .../{routes-generate.test111.ts => routes-generate.test.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/routes-generate/{ice.config.ts => ice.config.js} (100%) rename tests/integration/{routes-generate.test111.ts => routes-generate.test.ts} (100%) diff --git a/examples/routes-generate/ice.config.ts b/examples/routes-generate/ice.config.js similarity index 100% rename from examples/routes-generate/ice.config.ts rename to examples/routes-generate/ice.config.js diff --git a/tests/integration/routes-generate.test111.ts b/tests/integration/routes-generate.test.ts similarity index 100% rename from tests/integration/routes-generate.test111.ts rename to tests/integration/routes-generate.test.ts From 0debd8a5808ac1684faed56f09312b89e44568c4 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:26:51 +0800 Subject: [PATCH 16/36] chore: remove pnpm cache --- .github/workflows/ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15817310c..df616cb22 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,12 +22,6 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ - - name: Cache .pnpm-store - id: cache - uses: actions/cache@v1 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }} - name: Install pnpm run: npm i pnpm -g - run: npm run setup From 61c2e8b0cd95e36144457dd44ade31d5b95b32de Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:30:41 +0800 Subject: [PATCH 17/36] chore: test --- .github/workflows/ci.yml | 6 ++++++ .../{basic-project.test.ts => basic-project.tests.ts} | 0 2 files changed, 6 insertions(+) rename tests/integration/{basic-project.test.ts => basic-project.tests.ts} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df616cb22..15817310c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,12 @@ jobs: with: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ + - name: Cache .pnpm-store + id: cache + uses: actions/cache@v1 + with: + path: ~/.pnpm-store + key: ${{ runner.os }}-node${{ matrix.node-version }}-${{ hashFiles('**/pnpm-lock.yaml') }} - name: Install pnpm run: npm i pnpm -g - run: npm run setup diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.tests.ts similarity index 100% rename from tests/integration/basic-project.test.ts rename to tests/integration/basic-project.tests.ts From f4513717ac8e577e68dae41ef4eef17540582866 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:33:47 +0800 Subject: [PATCH 18/36] chore: remove test:ci from ci workflow --- .github/workflows/ci.yml | 2 +- .../{basic-project.tests.ts => basic-project.test.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/integration/{basic-project.tests.ts => basic-project.test.ts} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15817310c..dd4c2ae42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - run: npm run setup - run: npm run dependency:check - run: npm run lint - - run: npm run test:ci + - run: npm run test - run: npm run version:check env: ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} diff --git a/tests/integration/basic-project.tests.ts b/tests/integration/basic-project.test.ts similarity index 100% rename from tests/integration/basic-project.tests.ts rename to tests/integration/basic-project.test.ts From 5dedac7a1a7ee684c817810f76c4e34a318ef14e Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 15:47:58 +0800 Subject: [PATCH 19/36] chore: update build-scripts version --- package.json | 2 +- packages/build-webpack-config/package.json | 2 +- packages/ice/package.json | 2 +- packages/types/package.json | 2 +- pnpm-lock.yaml | 20 ++++++++++---------- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 039f3045a..3d3e7117d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@types/jest": "^27.4.0", "@types/node": "^17.0.13", "@types/semver": "^7.3.9", - "build-scripts": "^2.0.0-15", + "build-scripts": "^2.0.0-16", "chalk": "^4.1.2", "chokidar": "^3.5.3", "dependency-check": "^4.1.0", diff --git a/packages/build-webpack-config/package.json b/packages/build-webpack-config/package.json index 705c6275d..898792fef 100644 --- a/packages/build-webpack-config/package.json +++ b/packages/build-webpack-config/package.json @@ -33,7 +33,7 @@ }, "devDependencies": { "@ice/types": "^1.0.0", - "build-scripts": "^2.0.0-15", + "build-scripts": "^2.0.0-16", "webpack": "^5.69.1", "webpack-dev-server": "^4.7.4" } diff --git a/packages/ice/package.json b/packages/ice/package.json index 94931df68..e9971fcea 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -24,7 +24,7 @@ "@ice/route-manifest": "^1.0.0", "@ice/runtime": "^1.0.0", "address": "^1.1.2", - "build-scripts": "^2.0.0-15", + "build-scripts": "^2.0.0-16", "chalk": "^4.0.0", "commander": "^9.0.0", "consola": "^2.15.3", diff --git a/packages/types/package.json b/packages/types/package.json index 7839923a7..69afbfb0d 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -26,7 +26,7 @@ "bugs": "https://github.com/ice-lab/ice-next/issues", "homepage": "https://next.ice.work", "devDependencies": { - "build-scripts": "^2.0.0-15", + "build-scripts": "^2.0.0-16", "esbuild": "^0.14.23", "@ice/runtime": "^1.0.0", "@ice/route-manifest": "^1.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13ba6c5cd..769233b98 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,7 +12,7 @@ importers: '@types/jest': ^27.4.0 '@types/node': ^17.0.13 '@types/semver': ^7.3.9 - build-scripts: ^2.0.0-15 + build-scripts: ^2.0.0-16 chalk: ^4.1.2 chokidar: ^3.5.3 dependency-check: ^4.1.0 @@ -44,7 +44,7 @@ importers: '@types/jest': 27.4.0 '@types/node': 17.0.19 '@types/semver': 7.3.9 - build-scripts: 2.0.0-15 + build-scripts: 2.0.0-16 chalk: 4.1.2 chokidar: 3.5.3 dependency-check: 4.1.0 @@ -123,7 +123,7 @@ importers: '@rollup/pluginutils': ^4.2.0 '@swc/core': ^1.2.146 browserslist: ^4.19.3 - build-scripts: ^2.0.0-15 + build-scripts: ^2.0.0-16 consola: ^2.15.3 es-module-lexer: ^0.10.0 event: ^1.0.0 @@ -159,7 +159,7 @@ importers: unplugin: 0.3.2_webpack@5.69.1 devDependencies: '@ice/types': link:../types - build-scripts: 2.0.0-15 + build-scripts: 2.0.0-16 webpack: 5.69.1_@swc+core@1.2.146 webpack-dev-server: 4.7.4_webpack@5.69.1 @@ -173,7 +173,7 @@ importers: '@types/ejs': ^3.1.0 '@types/lodash.debounce': ^4.0.6 address: ^1.1.2 - build-scripts: ^2.0.0-15 + build-scripts: ^2.0.0-16 chalk: ^4.0.0 chokidar: ^3.5.3 commander: ^9.0.0 @@ -196,7 +196,7 @@ importers: '@ice/runtime': link:../runtime '@ice/webpack-config': link:../build-webpack-config address: 1.1.2 - build-scripts: 2.0.0-15 + build-scripts: 2.0.0-16 chalk: 4.1.2 commander: 9.0.0 consola: 2.15.3 @@ -249,7 +249,7 @@ importers: specifiers: '@ice/route-manifest': ^1.0.0 '@ice/runtime': ^1.0.0 - build-scripts: ^2.0.0-15 + build-scripts: ^2.0.0-16 esbuild: ^0.14.23 react: ^17.0.2 unplugin: ^0.3.2 @@ -258,7 +258,7 @@ importers: devDependencies: '@ice/route-manifest': link:../route-manifest '@ice/runtime': link:../runtime - build-scripts: 2.0.0-15 + build-scripts: 2.0.0-16 esbuild: 0.14.23 react: 17.0.2 unplugin: 0.3.2_esbuild@0.14.23+webpack@5.69.1 @@ -2513,8 +2513,8 @@ packages: ieee754: 1.2.1 dev: true - /build-scripts/2.0.0-15: - resolution: {integrity: sha512-mn6u9gnjhICYm8Rp1OXJvpjsH5jWPLHtx+b2pHtbi30lrWcctepElfJS7cH14exx9OXtOwsilRIKXNnCzbYKLg==} + /build-scripts/2.0.0-16: + resolution: {integrity: sha512-w6Z+yIwhDxCKqORg//mHO0F4o6uNVEhBo3EiAk9zR9T0hDLazRHVBSz1Tsf+GErvGVGp6g2iBt1tv7z/5tynzg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: camelcase: 5.3.1 From 6e11fd02b92e1073502eba9323b59812d170ac61 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 16:00:55 +0800 Subject: [PATCH 20/36] chore: build fixture --- package.json | 1 - tests/utils/build.ts | 14 ++++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 3d3e7117d..91a59f02d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "lint:fix": "npm run lint -- --fix", "publish:alpha": "PUBLISH_TYPE=alpha esmo ./scripts/publishPackageWithDistTag.ts", "test": "NODE_OPTIONS=--experimental-vm-modules jest --forceExit --config ./jest.config.mjs", - "test:ci": "npm run test -- --ci", "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --config ./jest.config.mjs" }, "author": "ice-admin@alibaba-inc.com", diff --git a/tests/utils/build.ts b/tests/utils/build.ts index 536704d1f..d0312105a 100644 --- a/tests/utils/build.ts +++ b/tests/utils/build.ts @@ -21,14 +21,12 @@ interface ReturnValue { } // get builtIn plugins -export const buildFixture = function(example: string) { - test(`setup ${example}`, async () => { - const rootDir = path.join(__dirname, `../../examples/${example}`); - process.env.DISABLE_FS_CACHE = 'true'; - process.env.JEST_TEST = 'true'; - const service = await createService({ rootDir, command: 'build', commandArgs: {} }); - await service.run(); - }, 120000); +export const buildFixture = async function(example: string) { + const rootDir = path.join(__dirname, `../../examples/${example}`); + process.env.DISABLE_FS_CACHE = 'true'; + process.env.JEST_TEST = 'true'; + const service = await createService({ rootDir, command: 'build', commandArgs: {} }); + await service.run(); } export const setupBrowser: SetupBrowser = async (options) => { From 2ea451c7b7bf12c4cc487f4e28b895cefc302c20 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 16:07:03 +0800 Subject: [PATCH 21/36] chore: remove devServer test --- tests/integration/routes-generate.test.ts | 98 +++++++++++------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test.ts index c37f89cd4..d6f41a8ac 100644 --- a/tests/integration/routes-generate.test.ts +++ b/tests/integration/routes-generate.test.ts @@ -55,52 +55,52 @@ describe(`build ${example}`, () => { }); }); -describe(`start ${example}`, () => { - let page: Page = null; - let browser = null; - - test('setup devServer', async () => { - const { devServer, port } = await startFixture(example); - const res = await setupStartBrowser({ server: devServer, port }); - page = res.page; - browser = res.browser; - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Home']); - }, 120000); - - test('define extra routes', async () => { - await page.push('about-me'); - expect(await page.$$text('h1')).toStrictEqual([]); - expect(await page.$$text('h2')).toStrictEqual(['About']); - - await page.push('product'); - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Products Page']); - }); - - test('page layout', async () => { - await page.push('dashboard/a'); - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); - expect(await page.$$text('h3')).toStrictEqual(['A page']); - - await page.push('dashboard/b'); - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); - expect(await page.$$text('h3')).toStrictEqual(['B page']); - }); - - test('dynamic routes layout', async () => { - await page.push('detail/a'); - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); - - await page.push('detail/b'); - expect(await page.$$text('h1')).toStrictEqual(['Layout']); - expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); - }); - - afterAll(async () => { - await browser.close(); - }); -}); +// describe(`start ${example}`, () => { +// let page: Page = null; +// let browser = null; + +// test('setup devServer', async () => { +// const { devServer, port } = await startFixture(example); +// const res = await setupStartBrowser({ server: devServer, port }); +// page = res.page; +// browser = res.browser; +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Home']); +// }, 120000); + +// test('define extra routes', async () => { +// await page.push('about-me'); +// expect(await page.$$text('h1')).toStrictEqual([]); +// expect(await page.$$text('h2')).toStrictEqual(['About']); + +// await page.push('product'); +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Products Page']); +// }); + +// test('page layout', async () => { +// await page.push('dashboard/a'); +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); +// expect(await page.$$text('h3')).toStrictEqual(['A page']); + +// await page.push('dashboard/b'); +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); +// expect(await page.$$text('h3')).toStrictEqual(['B page']); +// }); + +// test('dynamic routes layout', async () => { +// await page.push('detail/a'); +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); + +// await page.push('detail/b'); +// expect(await page.$$text('h1')).toStrictEqual(['Layout']); +// expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); +// }); + +// afterAll(async () => { +// await browser.close(); +// }); +// }); From 4972237606d3a2c0afcaa50ca09d7e73ab5d39f1 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 16:11:04 +0800 Subject: [PATCH 22/36] chore: buildFixture --- tests/integration/basic-project.test.ts | 3 +- tests/integration/routes-generate.test.ts | 101 +++++++++++----------- 2 files changed, 51 insertions(+), 53 deletions(-) diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.test.ts index 2891f82aa..b2c4d6819 100644 --- a/tests/integration/basic-project.test.ts +++ b/tests/integration/basic-project.test.ts @@ -13,9 +13,8 @@ describe(`build ${example}`, () => { let page: Page = null; let browser = null; - buildFixture(example); - test('open /', async () => { + await buildFixture(example); const res = await setupBrowser({ example }); page = res.page; browser = res.browser; diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test.ts index d6f41a8ac..0e3be932d 100644 --- a/tests/integration/routes-generate.test.ts +++ b/tests/integration/routes-generate.test.ts @@ -8,9 +8,8 @@ describe(`build ${example}`, () => { let page: Page = null; let browser = null; - buildFixture(example); - test('open /', async () => { + await buildFixture(example); const res = await setupBrowser({ example }); page = res.page; browser = res.browser; @@ -55,52 +54,52 @@ describe(`build ${example}`, () => { }); }); -// describe(`start ${example}`, () => { -// let page: Page = null; -// let browser = null; - -// test('setup devServer', async () => { -// const { devServer, port } = await startFixture(example); -// const res = await setupStartBrowser({ server: devServer, port }); -// page = res.page; -// browser = res.browser; -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Home']); -// }, 120000); - -// test('define extra routes', async () => { -// await page.push('about-me'); -// expect(await page.$$text('h1')).toStrictEqual([]); -// expect(await page.$$text('h2')).toStrictEqual(['About']); - -// await page.push('product'); -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Products Page']); -// }); - -// test('page layout', async () => { -// await page.push('dashboard/a'); -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); -// expect(await page.$$text('h3')).toStrictEqual(['A page']); - -// await page.push('dashboard/b'); -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); -// expect(await page.$$text('h3')).toStrictEqual(['B page']); -// }); - -// test('dynamic routes layout', async () => { -// await page.push('detail/a'); -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); - -// await page.push('detail/b'); -// expect(await page.$$text('h1')).toStrictEqual(['Layout']); -// expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); -// }); - -// afterAll(async () => { -// await browser.close(); -// }); -// }); +describe(`start ${example}`, () => { + let page: Page = null; + let browser = null; + + test('setup devServer', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Home']); + }, 120000); + + test('define extra routes', async () => { + await page.push('about-me'); + expect(await page.$$text('h1')).toStrictEqual([]); + expect(await page.$$text('h2')).toStrictEqual(['About']); + + await page.push('product'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Products Page']); + }); + + test('page layout', async () => { + await page.push('dashboard/a'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['A page']); + + await page.push('dashboard/b'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Dashboard']); + expect(await page.$$text('h3')).toStrictEqual(['B page']); + }); + + test('dynamic routes layout', async () => { + await page.push('detail/a'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Detail id: a']); + + await page.push('detail/b'); + expect(await page.$$text('h1')).toStrictEqual(['Layout']); + expect(await page.$$text('h2')).toStrictEqual(['Detail id: b']); + }); + + afterAll(async () => { + await browser.close(); + }); +}); From 8ef7f27f3d550c4161ba3d39cf2e09735448949f Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 17:21:06 +0800 Subject: [PATCH 23/36] feat: add vitest --- .github/workflows/ci.yml | 2 +- jest.config.mjs | 2 +- package.json | 8 +- pnpm-lock.yaml | 350 ++++++++++++++++++++++ tests/integration/basic-project.test.ts | 1 + tests/integration/routes-generate.test.ts | 1 + vitest.config.ts | 24 ++ 7 files changed, 383 insertions(+), 5 deletions(-) create mode 100644 vitest.config.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd4c2ae42..15ee5f1b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - run: npm run setup - run: npm run dependency:check - run: npm run lint - - run: npm run test + - run: npm run vitest - run: npm run version:check env: ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} diff --git a/jest.config.mjs b/jest.config.mjs index 3801fb48e..d5c6d5f33 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -30,7 +30,7 @@ export default { '/node_modules/', '/esm/', 'create-cli-utils/', - '/tests/fixtures/' + '/tests/fixtures/', ], extensionsToTreatAsEsm: ['.ts'], testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'], diff --git a/package.json b/package.json index 91a59f02d..87d051b0e 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,9 @@ "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./", "lint:fix": "npm run lint -- --fix", "publish:alpha": "PUBLISH_TYPE=alpha esmo ./scripts/publishPackageWithDistTag.ts", - "test": "NODE_OPTIONS=--experimental-vm-modules jest --forceExit --config ./jest.config.mjs", - "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --config ./jest.config.mjs" + "test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --forceExit --config ./jest.config.mjs", + "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch --config ./jest.config.mjs", + "vitest": "vitest run" }, "author": "ice-admin@alibaba-inc.com", "license": "MIT", @@ -56,7 +57,8 @@ "semver": "^7.3.5", "stylelint": "^14.3.0", "ts-jest": "^27.1.3", - "typescript": "^4.5.5" + "typescript": "^4.5.5", + "vitest": "^0.8.2" }, "packageManager": "pnpm" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 769233b98..254460aec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,7 @@ importers: stylelint: ^14.3.0 ts-jest: ^27.1.3 typescript: ^4.5.5 + vitest: ^0.8.2 devDependencies: '@applint/spec': 1.1.1_936f70d4edd6ac1a2cef9869d6224569 '@commitlint/cli': 16.2.1 @@ -67,6 +68,7 @@ importers: stylelint: 14.5.2 ts-jest: 27.1.3_ac171f3d9f636bd8b4c3e7aa384f840e typescript: 4.6.2 + vitest: 0.8.2 examples/basic-project: specifiers: @@ -1584,6 +1586,16 @@ packages: dependencies: '@types/node': 17.0.19 + /@types/chai-subset/1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.0 + dev: true + + /@types/chai/4.3.0: + resolution: {integrity: sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==} + dev: true + /@types/connect-history-api-fallback/1.3.5: resolution: {integrity: sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==} dependencies: @@ -2283,6 +2295,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /assertion-error/1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /ast-types-flow/0.0.7: resolution: {integrity: sha1-9wtzXGvKGlycItmCw+Oef+ujva0=} dev: true @@ -2576,6 +2592,19 @@ packages: /caniuse-lite/1.0.30001312: resolution: {integrity: sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz} + /chai/4.3.6: + resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 3.0.1 + get-func-name: 2.0.0 + loupe: 2.3.4 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk/2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2596,6 +2625,10 @@ packages: engines: {node: '>=10'} dev: true + /check-error/1.0.2: + resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=} + dev: true + /chokidar/3.5.2: resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} engines: {node: '>= 8.10.0'} @@ -2967,6 +3000,13 @@ packages: resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} dev: true + /deep-eql/3.0.1: + resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} + engines: {node: '>=0.12'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-equal/1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: @@ -3251,6 +3291,15 @@ packages: is-symbol: 1.0.4 dev: true + /esbuild-android-64/0.14.30: + resolution: {integrity: sha512-vdJ7t8A8msPfKpYUGUV/KaTQRiZ0vDa2XSTlzXVkGGVHLKPeb85PBUtYJcEgw3htW3IdX5i1t1IMdQCwJJgNAg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-android-arm64/0.14.23: resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==} engines: {node: '>=12'} @@ -3259,6 +3308,15 @@ packages: requiresBuild: true optional: true + /esbuild-android-arm64/0.14.30: + resolution: {integrity: sha512-BdgGfxeA5hBQNErLr7BWJUA8xjflEfyaARICy8e0OJYNSAwDbEzOf8LyiKWSrDcgV129mWhi3VpbNQvOIDEHcg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-64/0.14.23: resolution: {integrity: sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==} engines: {node: '>=12'} @@ -3267,6 +3325,15 @@ packages: requiresBuild: true optional: true + /esbuild-darwin-64/0.14.30: + resolution: {integrity: sha512-VRaOXMMrsG5n53pl4qFZQdXy2+E0NoLP/QH3aDUI0+bQP+ZHDmbINKcDy2IX7GVFI9kqPS18iJNAs5a6/G2LZg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-arm64/0.14.23: resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==} engines: {node: '>=12'} @@ -3275,6 +3342,15 @@ packages: requiresBuild: true optional: true + /esbuild-darwin-arm64/0.14.30: + resolution: {integrity: sha512-qDez+fHMOrO9Oc9qjt/x+sy09RJVh62kik5tVybKRLmezeV4qczM9/sAYY57YN0aWLdHbcCj2YqJUWYJNsgKnw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-64/0.14.23: resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==} engines: {node: '>=12'} @@ -3283,6 +3359,15 @@ packages: requiresBuild: true optional: true + /esbuild-freebsd-64/0.14.30: + resolution: {integrity: sha512-mec1jENcImVVagddZlGWsdAUwBnzR5cgnhzCxv+9fSMxKbx1uZYLLUAnLPp8m/i934zrumR1xGjJ5VoWdPlI2w==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-arm64/0.14.23: resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==} engines: {node: '>=12'} @@ -3291,6 +3376,15 @@ packages: requiresBuild: true optional: true + /esbuild-freebsd-arm64/0.14.30: + resolution: {integrity: sha512-cpjbTs6Iok/AfeB0JgTzyUJTMStC1SQULmany5nHx6S4GTkSgaAHuJzZO0GcVWqghI4e0YL/bjXAhN5Mn6feNw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-32/0.14.23: resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==} engines: {node: '>=12'} @@ -3299,6 +3393,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-32/0.14.30: + resolution: {integrity: sha512-liIONVT4F2kZmOMwtwASqZ8WkIjb5HHBR9HUffdHiuotSTF3CyZO+EJf+Og+SYYuuVIvt0qHNSFjBA/iSESteQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-64/0.14.23: resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==} engines: {node: '>=12'} @@ -3307,6 +3410,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-64/0.14.30: + resolution: {integrity: sha512-LUnpzoMpRqFON5En4qEj6NWiyH6a1K+Y2qYNKrCy5qPTjDoG/EWeqMz69n8Uv7pRuvDKl3FNGJ1dufTrA5i0sw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm/0.14.23: resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==} engines: {node: '>=12'} @@ -3315,6 +3427,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-arm/0.14.30: + resolution: {integrity: sha512-97T+bbXnpqf7mfIG49UR7ZSJFGgvc22byn74qw3Kx2GDCBSQoVFjyWuKOHGXp8nXk3XYrdFF+mQ8yQ7aNsgQvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm64/0.14.23: resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==} engines: {node: '>=12'} @@ -3323,6 +3444,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-arm64/0.14.30: + resolution: {integrity: sha512-DHZHn6FK5q/KL0fpNT/0jE38Nnyk2rXxKE9WENi95EXtqfOLPgE8tzjTZQNgpr61R95QX4ymQU26ni3IZk8buQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-mips64le/0.14.23: resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==} engines: {node: '>=12'} @@ -3331,6 +3461,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-mips64le/0.14.30: + resolution: {integrity: sha512-fLUzTFZ7uknC0aPTk7/lM7NmaG/9ZqE3SaHEphcaM009SZK/mDOvZugWi1ss6WGNhk13dUrhkfHcc4FSb9hYhg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-ppc64le/0.14.23: resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==} engines: {node: '>=12'} @@ -3339,6 +3478,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-ppc64le/0.14.30: + resolution: {integrity: sha512-2Oudm2WEfj0dNU9bzIl5L/LrsMEmHWsOsYgJJqu8fDyUDgER+J1d33qz3cUdjsJk7gAENayIxDSpsuCszx0w3A==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-riscv64/0.14.23: resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==} engines: {node: '>=12'} @@ -3347,6 +3495,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-riscv64/0.14.30: + resolution: {integrity: sha512-RPMucPW47rV4t2jlelaE948iCRtbZf5RhifxSwzlpM1Mqdyu99MMNK0w4jFreGTmLN+oGomxIOxD6n+2E/XqHw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-s390x/0.14.23: resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==} engines: {node: '>=12'} @@ -3355,6 +3512,15 @@ packages: requiresBuild: true optional: true + /esbuild-linux-s390x/0.14.30: + resolution: {integrity: sha512-OZ68r7ok6qO7hdwrwQn2p5jbIRRcUcVaAykB7e0uCA0ODwfeGunILM6phJtq2Oz4dlEEFvd+tSuma3paQKwt+A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-netbsd-64/0.14.23: resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==} engines: {node: '>=12'} @@ -3363,6 +3529,15 @@ packages: requiresBuild: true optional: true + /esbuild-netbsd-64/0.14.30: + resolution: {integrity: sha512-iyejQUKn0TzpPkufq8pSCxOg9NheycQbMbPCmjefTe9wYuUlBt1TcHvdoJnYbQzsAhAh1BNq+s0ycRsIJFZzaQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-node-loader/0.6.5: resolution: {integrity: sha512-uPP+dllWm38cFvDysdocutN3lfe5pTIbddAHp1ENyLzpHYqE2r+3Wo+pfg9X3p8DFWwzIisft5YkeBIthIcixw==} dependencies: @@ -3377,6 +3552,15 @@ packages: requiresBuild: true optional: true + /esbuild-openbsd-64/0.14.30: + resolution: {integrity: sha512-UyK1MTMcy4j5fH260fsE1o6MVgWNhb62eCK2yCKCRazZv8Nqdc2WiP9ygjWidmEdCDS+A6MuVp9ozk9uoQtQpA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-register/3.3.2_esbuild@0.14.23: resolution: {integrity: sha512-jceAtTO6zxPmCfSD5cBb3rgIK1vmuqCKYwgylHiS1BF4pq0jJiJb4K2QMuqF4BEw7XDBRatYzip0upyTzfkgsQ==} peerDependencies: @@ -3393,6 +3577,15 @@ packages: requiresBuild: true optional: true + /esbuild-sunos-64/0.14.30: + resolution: {integrity: sha512-aQRtRTNKHB4YuG+xXATe5AoRTNY48IJg5vjE8ElxfmjO9+KdX7MHFkTLhlKevCD6rNANtB3qOlSIeAiXTwHNqw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-32/0.14.23: resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==} engines: {node: '>=12'} @@ -3401,6 +3594,15 @@ packages: requiresBuild: true optional: true + /esbuild-windows-32/0.14.30: + resolution: {integrity: sha512-9/fb1tPtpacMqxAXp3fGHowUDg/l9dVch5hKmCLEZC6PdGljh6h372zMdJwYfH0Bd5CCPT0Wx95uycBLJiqpXA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-64/0.14.23: resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==} engines: {node: '>=12'} @@ -3409,6 +3611,15 @@ packages: requiresBuild: true optional: true + /esbuild-windows-64/0.14.30: + resolution: {integrity: sha512-DHgITeUhPAnN9I5O6QBa1GVyPOhiYCn4S4TtQr7sO4+X0LNyqnlmA1M0qmGkUdDC1QQfjI8uQ4G/whdWb2pWIQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-arm64/0.14.23: resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==} engines: {node: '>=12'} @@ -3417,6 +3628,15 @@ packages: requiresBuild: true optional: true + /esbuild-windows-arm64/0.14.30: + resolution: {integrity: sha512-F1kLyQH7zSgjh5eLxogGZN7C9+KNs9m+s7Q6WZoMmCWT/6j998zlaoECHyM8izJRRfsvw2eZlEa1jO6/IOU1AQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild/0.14.23: resolution: {integrity: sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==} engines: {node: '>=12'} @@ -3443,6 +3663,34 @@ packages: esbuild-windows-64: 0.14.23 esbuild-windows-arm64: 0.14.23 + /esbuild/0.14.30: + resolution: {integrity: sha512-wCecQSBkIjp2xjuXY+wcXS/PpOQo9rFh4NAKPh4Pm9f3fuLcnxkR0rDzA+mYP88FtXIUcXUyYmaIgfrzRl55jA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.30 + esbuild-android-arm64: 0.14.30 + esbuild-darwin-64: 0.14.30 + esbuild-darwin-arm64: 0.14.30 + esbuild-freebsd-64: 0.14.30 + esbuild-freebsd-arm64: 0.14.30 + esbuild-linux-32: 0.14.30 + esbuild-linux-64: 0.14.30 + esbuild-linux-arm: 0.14.30 + esbuild-linux-arm64: 0.14.30 + esbuild-linux-mips64le: 0.14.30 + esbuild-linux-ppc64le: 0.14.30 + esbuild-linux-riscv64: 0.14.30 + esbuild-linux-s390x: 0.14.30 + esbuild-netbsd-64: 0.14.30 + esbuild-openbsd-64: 0.14.30 + esbuild-sunos-64: 0.14.30 + esbuild-windows-32: 0.14.30 + esbuild-windows-64: 0.14.30 + esbuild-windows-arm64: 0.14.30 + dev: true + /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, registry: https://registry.yarnpkg.com/, tarball: https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz} engines: {node: '>=6'} @@ -4073,6 +4321,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name/2.0.0: + resolution: {integrity: sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=} + dev: true + /get-intrinsic/1.1.1: resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} dependencies: @@ -5499,6 +5751,11 @@ packages: json5: 2.2.0 dev: false + /local-pkg/0.4.1: + resolution: {integrity: sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw==} + engines: {node: '>=14'} + dev: true + /locate-path/2.0.0: resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} engines: {node: '>=4'} @@ -5549,6 +5806,12 @@ packages: dependencies: js-tokens: 4.0.0 + /loupe/2.3.4: + resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} + dependencies: + get-func-name: 2.0.0 + dev: true + /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -6167,6 +6430,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /pathval/1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /pend/1.2.0: resolution: {integrity: sha1-elfrVQpng/kRUzH89GY9XI4AelA=} dev: true @@ -6240,6 +6507,15 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true + /postcss/8.4.12: + resolution: {integrity: sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.1 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + /postcss/8.4.6: resolution: {integrity: sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==} engines: {node: ^10 || ^12 || >=14} @@ -6639,6 +6915,14 @@ packages: dependencies: glob: 7.2.0 + /rollup/2.70.1: + resolution: {integrity: sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -7314,6 +7598,16 @@ packages: /thunky/1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + /tinypool/0.1.2: + resolution: {integrity: sha512-fvtYGXoui2RpeMILfkvGIgOVkzJEGediv8UJt7TxdAOY8pnvUkFg/fkvqTfXG9Acc9S17Cnn1S4osDc2164guA==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy/0.3.0: + resolution: {integrity: sha512-c5uFHqtUp74R2DJE3/Efg0mH5xicmgziaQXMm/LvuuZn3RdpADH32aEGDRyCzObXT1DNfwDMqRQ/Drh1MlO12g==} + engines: {node: '>=14.0.0'} + dev: true + /tmpl/1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true @@ -7642,6 +7936,62 @@ packages: resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=} engines: {node: '>= 0.8'} + /vite/2.9.1: + resolution: {integrity: sha512-vSlsSdOYGcYEJfkQ/NeLXgnRv5zZfpAsdztkIrs7AZHV8RCMZQkwjo4DS5BnrYTqoWqLoUe1Cah4aVO4oNNqCQ==} + engines: {node: '>=12.2.0'} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + peerDependenciesMeta: + less: + optional: true + sass: + optional: true + stylus: + optional: true + dependencies: + esbuild: 0.14.30 + postcss: 8.4.12 + resolve: 1.22.0 + rollup: 2.70.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitest/0.8.2: + resolution: {integrity: sha512-dTFDJl2F3pkWy1tcE3M29LasklhgtP7M88kT7AJcAurX7nCl/eWu1PQeSzjzWQyUbDq2p8jqdoLETd7MDeibcA==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@vitest/ui': '*' + c8: '*' + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@vitest/ui': + optional: true + c8: + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/chai': 4.3.0 + '@types/chai-subset': 1.3.3 + chai: 4.3.6 + local-pkg: 0.4.1 + tinypool: 0.1.2 + tinyspy: 0.3.0 + vite: 2.9.1 + transitivePeerDependencies: + - less + - sass + - stylus + dev: true + /vue-eslint-parser/8.3.0_eslint@8.9.0: resolution: {integrity: sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.test.ts index b2c4d6819..3cac1e603 100644 --- a/tests/integration/basic-project.test.ts +++ b/tests/integration/basic-project.test.ts @@ -1,3 +1,4 @@ +import { expect, test, describe, afterAll } from 'vitest'; import * as path from 'path'; import * as fs from 'fs'; import { fileURLToPath } from 'url'; diff --git a/tests/integration/routes-generate.test.ts b/tests/integration/routes-generate.test.ts index 0e3be932d..75fafcdf8 100644 --- a/tests/integration/routes-generate.test.ts +++ b/tests/integration/routes-generate.test.ts @@ -1,3 +1,4 @@ +import { expect, test, describe, afterAll } from 'vitest'; import { buildFixture, setupBrowser } from '../utils/build'; import { startFixture, setupStartBrowser } from '../utils/start'; import { Page } from '../utils/browser'; diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..c760b9786 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from 'vitest/config'; +import { getHookFiles } from './packages/ice/esm/requireHook.js'; + +const moduleNameMapper = getHookFiles().reduce((mapper, [id, value]) => { + mapper[`^${id}$`] = value; + return mapper; +}, {}); + +export default defineConfig({ + resolve: { + alias: { ...moduleNameMapper }, + }, + test: { + include: [ + './tests/integration/basic-project.test.ts', + './tests/integration/routes-generate.test.ts', + ], + exclude: [ + '**/node_modules/**', + '**/esm/**', + '**/tests/fixtures/**', + ], + }, +}); From 1979985d2a9daf95f41cbfce4daf58c8435a8f15 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 17:27:11 +0800 Subject: [PATCH 24/36] chore: add ts-ignore --- packages/build-webpack-config/src/unPlugins/compilation.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/build-webpack-config/src/unPlugins/compilation.ts b/packages/build-webpack-config/src/unPlugins/compilation.ts index bc3ab1f56..8cf1e163b 100644 --- a/packages/build-webpack-config/src/unPlugins/compilation.ts +++ b/packages/build-webpack-config/src/unPlugins/compilation.ts @@ -25,6 +25,7 @@ const compilationPlugin = (options: Options): UnpluginOptions => { return { name: 'compilation-plugin', + // @ts-expect-error async transform(source: string, id: string) { // TODO specific runtime plugin name if ((/node_modules/.test(id) && !/[\\/]runtime[\\/]/.test(id))) { From ae4047e6661897b47883d136fe79f01121c5a71b Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@gmail.com> Date: Sat, 2 Apr 2022 17:36:11 +0800 Subject: [PATCH 25/36] chore: node ci version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15ee5f1b8..dcb660f10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [12.x] + node-version: [14.x] steps: - uses: actions/checkout@v2 - name: Set branch name From bc1ea1e0a03be9caba2adafc46f27310e3efeae3 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Wed, 6 Apr 2022 21:18:59 +0800 Subject: [PATCH 26/36] chore: comment bundle analyzer --- examples/basic-project/ice.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index 890e35a45..ea9a5afcd 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -1,12 +1,12 @@ import { defineUserConfig } from '@ice/app'; -import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; +// import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; export default defineUserConfig({ publicPath: '/', webpack: (webpackConfig) => { - if (process.env.NODE_ENV !== 'test') { - webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); - } + // if (process.env.NODE_ENV !== 'test') { + // webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); + // } return webpackConfig; }, plugins: ['@ice/plugin-auth'], From a5bc6beb024a8c6c8e1a07c8327092a31cc2f3f5 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Wed, 6 Apr 2022 23:33:53 +0800 Subject: [PATCH 27/36] chore: add test timeout --- vitest.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/vitest.config.ts b/vitest.config.ts index c760b9786..114d0f3cc 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,6 +11,7 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { + testTimeout: 200000, include: [ './tests/integration/basic-project.test.ts', './tests/integration/routes-generate.test.ts', From d50e248bf8e5ac6f6e6edcf2c785530ac7d0e783 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 10:51:52 +0800 Subject: [PATCH 28/36] fix: lint --- packages/build-webpack-config/src/index.ts | 2 +- packages/ice/src/plugins/web/index.ts | 2 +- packages/route-manifest/src/index.ts | 2 +- packages/runtime/src/assets.ts | 2 +- packages/types/src/config.ts | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/build-webpack-config/src/index.ts b/packages/build-webpack-config/src/index.ts index 2f8c46cc2..c1e0f8c51 100644 --- a/packages/build-webpack-config/src/index.ts +++ b/packages/build-webpack-config/src/index.ts @@ -191,7 +191,7 @@ const getWebpackConfig: GetWebpackConfig = ({ rootDir, config, commandArgs = {} performance: false, devtool: getDevtoolValue(sourceMap), plugins: [ - ...webpackPlugins, + ...webpackPlugins, dev && new ReactRefreshWebpackPlugin(), new webpack.DefinePlugin({ ...defineStaticVariables, diff --git a/packages/ice/src/plugins/web/index.ts b/packages/ice/src/plugins/web/index.ts index 53ec19e16..f47b9113a 100644 --- a/packages/ice/src/plugins/web/index.ts +++ b/packages/ice/src/plugins/web/index.ts @@ -52,7 +52,7 @@ const webPlugin: Plugin = ({ registerTask, context, onHook }) => { return middlewares; }, - }); + }); }; export default webPlugin; diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index dd98fa2e5..ef5e0e4ba 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -31,7 +31,7 @@ export function generateRouteManifest( rootDir: string, ignoreFiles: string[] = [], defineExtraRoutes?: (defineRoute: DefineRouteFunction) => void, - ) { +) { const srcDir = path.join(rootDir, 'src'); const routeManifest: RouteManifest = {}; // 2. find routes in `src/pages` directory diff --git a/packages/runtime/src/assets.ts b/packages/runtime/src/assets.ts index 0cce68197..deebcfbb8 100644 --- a/packages/runtime/src/assets.ts +++ b/packages/runtime/src/assets.ts @@ -5,7 +5,7 @@ import type { AssetsManifest, RouteMatch } from './types'; * @param assetsManifest * @returns */ - export function getPageAssets(matches: RouteMatch[], assetsManifest: AssetsManifest): string[] { +export function getPageAssets(matches: RouteMatch[], assetsManifest: AssetsManifest): string[] { const { bundles, publicPath } = assetsManifest; let result = []; diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index de733cad2..1f64bb953 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -42,8 +42,8 @@ export interface Config { transforms?: UnpluginOptions['transform'][]; middlewares?: - | ((middlewares: Middleware[], devServer: Server) => Middleware[]) - | undefined; + | ((middlewares: Middleware[], devServer: Server) => Middleware[]) + | undefined; proxy?: ProxyConfigArrayItem | ProxyConfigMap | ProxyConfigArray | undefined; From 09d849dc5a1816ad795126f13a4ffe98908d8a66 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 10:55:11 +0800 Subject: [PATCH 29/36] chore: remove threads --- vitest.config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 3f1dd8551..17e0d5554 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,8 +11,6 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { - // disable threads to avoid `Segmentation fault (core dumped)` error: https://github.com/vitest-dev/vitest/issues/317 - threads: false, exclude: [ '**/node_modules/**', '**/esm/**', From e3adc08c9c2dd46afb69f7b223b27578146943b4 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 11:21:14 +0800 Subject: [PATCH 30/36] chore: set maxThreads and minThreads --- package.json | 2 +- pnpm-lock.yaml | 8 ++++---- vitest.config.ts | 4 ++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 215a021ee..404110899 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "semver": "^7.3.5", "stylelint": "^14.3.0", "typescript": "^4.5.5", - "vitest": "^0.8.4" + "vitest": "^0.9.2" }, "packageManager": "pnpm" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a6a78b3f..d79505f93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,7 +33,7 @@ importers: semver: ^7.3.5 stylelint: ^14.3.0 typescript: ^4.5.5 - vitest: ^0.8.4 + vitest: ^0.9.2 devDependencies: '@applint/spec': 1.2.0_dcc7a92cec4fbc101cf834f08b738218 '@commitlint/cli': 16.2.3 @@ -64,7 +64,7 @@ importers: semver: 7.3.6 stylelint: 14.6.1 typescript: 4.6.3 - vitest: 0.8.5_c8@7.11.0 + vitest: 0.9.2_c8@7.11.0 examples/basic-project: specifiers: @@ -6247,8 +6247,8 @@ packages: fsevents: 2.3.2 dev: true - /vitest/0.8.5_c8@7.11.0: - resolution: {integrity: sha512-UOBAfyLUn9++isUDC5vk8joLcaBZj7esLS2Yx3GZSRMWzayOfEEzU1Iv4SBb4HkJun9e1D5ifZoSclhNHKn7IA==} + /vitest/0.9.2_c8@7.11.0: + resolution: {integrity: sha512-XgR42njw350OxBfKD4MK0cNIzgQrhSUKJq9sgbgRR+bD8GonPCyjpFFmPejptaiEyjmQ2FXpEvFHN37b9X2HJA==} engines: {node: '>=v14.16.0'} hasBin: true peerDependencies: diff --git a/vitest.config.ts b/vitest.config.ts index 17e0d5554..0e6d18325 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,6 +11,10 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { + // To avoid error `Segmentation fault (core dumped)` in CI environment, must set the threads number + // ref: https://github.com/vitest-dev/vitest/issues/317 + maxThreads: 3, + minThreads: 1, exclude: [ '**/node_modules/**', '**/esm/**', From 834d107c2c965f42b296c2227b018a6ea6ee7a3f Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 11:27:21 +0800 Subject: [PATCH 31/36] chore: add maxConcurrency --- .github/workflows/ci.yml | 2 +- vitest.config.ts | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5a1d81a5..3fdc60e26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - run: npm run setup - run: npm run dependency:check - run: npm run lint - - run: npm run test + - run: npm run test -- --maxConcurrency=8 - run: npm run version:check env: ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} diff --git a/vitest.config.ts b/vitest.config.ts index 0e6d18325..17e0d5554 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,10 +11,6 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { - // To avoid error `Segmentation fault (core dumped)` in CI environment, must set the threads number - // ref: https://github.com/vitest-dev/vitest/issues/317 - maxThreads: 3, - minThreads: 1, exclude: [ '**/node_modules/**', '**/esm/**', From f6efb61be1952aaae5c3285b7f3e9115b1579665 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 11:31:12 +0800 Subject: [PATCH 32/36] chore: remove coverage --- .github/workflows/ci.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3fdc60e26..c5a1d81a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - run: npm run setup - run: npm run dependency:check - run: npm run lint - - run: npm run test -- --maxConcurrency=8 + - run: npm run test - run: npm run version:check env: ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} diff --git a/package.json b/package.json index 404110899..6818ad74c 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./", "lint:fix": "npm run lint -- --fix", "publish:alpha": "PUBLISH_TYPE=alpha esmo ./scripts/publishPackageWithDistTag.ts", - "test": "vitest run --coverage", + "test": "vitest run", "test:watch": "vitest" }, "author": "ice-admin@alibaba-inc.com", From 3facfd3a5260b335b20d90033895fa6e811cd4ea Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 11:34:19 +0800 Subject: [PATCH 33/36] chore: threads --- package.json | 2 +- vitest.config.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 6818ad74c..404110899 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./", "lint:fix": "npm run lint -- --fix", "publish:alpha": "PUBLISH_TYPE=alpha esmo ./scripts/publishPackageWithDistTag.ts", - "test": "vitest run", + "test": "vitest run --coverage", "test:watch": "vitest" }, "author": "ice-admin@alibaba-inc.com", diff --git a/vitest.config.ts b/vitest.config.ts index 17e0d5554..7f51da139 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,6 +11,10 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { + // To avoid error `Segmentation fault (core dumped)` in CI environment, must set the threads number + // ref: https://github.com/vitest-dev/vitest/issues/317 + maxThreads: 1, + minThreads: 1, exclude: [ '**/node_modules/**', '**/esm/**', From 636536cf361abb6651f6e163d60dd28cdbf4fed4 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Fri, 8 Apr 2022 11:48:05 +0800 Subject: [PATCH 34/36] chore: set threads to false --- vitest.config.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index 7f51da139..c39bd1311 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -11,10 +11,9 @@ export default defineConfig({ alias: { ...moduleNameMapper }, }, test: { - // To avoid error `Segmentation fault (core dumped)` in CI environment, must set the threads number + // To avoid error `Segmentation fault (core dumped)` in CI environment, disable threads // ref: https://github.com/vitest-dev/vitest/issues/317 - maxThreads: 1, - minThreads: 1, + threads: false, exclude: [ '**/node_modules/**', '**/esm/**', From f7ddd64af2f0dc7b23bf765067744462c6c50826 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Mon, 11 Apr 2022 11:54:48 +0800 Subject: [PATCH 35/36] fix: conflict --- examples/basic-project/src/document.tsx | 6 +- examples/basic-project/src/pages/about.tsx | 24 ++- examples/basic-project/src/pages/index.tsx | 14 +- .../{ice.config.js => ice.config.ts} | 0 examples/routes-generate/src/document.tsx | 6 +- .../src/unPlugins/compilation.ts | 20 +- .../src/unPlugins/index.ts | 4 +- .../webpackPlugins/AssetsManifestPlugin.ts | 17 +- packages/ice/package.json | 5 +- packages/ice/src/analyzeRuntime.ts | 3 +- packages/ice/src/createService.ts | 14 +- packages/ice/src/plugins/config.ts | 8 + packages/ice/src/plugins/web/index.ts | 11 +- .../ssr/{generateHtml.ts => generateHTML.ts} | 19 +- .../ice/src/plugins/web/ssr/serverRender.ts | 15 +- packages/ice/src/service/compile.ts | 45 +++-- packages/ice/src/service/runtimeGenerator.ts | 24 --- packages/ice/src/utils/getContextConfig.ts | 18 +- packages/ice/src/utils/getRuntimeModules.ts | 4 +- packages/ice/template/entry.client.ts.ejs | 8 +- packages/ice/template/entry.server.ts.ejs | 20 +- packages/plugin-auth/package.json | 2 +- packages/runtime/src/App.tsx | 28 +-- packages/runtime/src/Document.tsx | 105 +++++------ packages/runtime/src/assets.ts | 91 +++++++-- packages/runtime/src/defineAppConfig.ts | 1 - packages/runtime/src/getInitialContext.ts | 15 -- packages/runtime/src/index.ts | 3 +- packages/runtime/src/routes.tsx | 18 +- packages/runtime/src/runClientApp.tsx | 130 +++++++++---- packages/runtime/src/runServerApp.tsx | 173 ++++++++++-------- packages/runtime/src/runtime.tsx | 4 +- packages/runtime/src/types.ts | 14 +- packages/types/src/config.ts | 2 +- packages/types/src/generator.ts | 1 - pnpm-lock.yaml | 15 +- tests/integration/basic-project.test.ts | 34 ++++ tests/utils/browser.ts | 25 +-- 38 files changed, 582 insertions(+), 364 deletions(-) rename examples/routes-generate/{ice.config.js => ice.config.ts} (100%) rename packages/ice/src/plugins/web/ssr/{generateHtml.ts => generateHTML.ts} (79%) delete mode 100644 packages/runtime/src/getInitialContext.ts diff --git a/examples/basic-project/src/document.tsx b/examples/basic-project/src/document.tsx index 1be1b41a0..24c078287 100644 --- a/examples/basic-project/src/document.tsx +++ b/examples/basic-project/src/document.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Meta, Title, Links, Main, Scripts } from 'ice'; -function Document() { +function Document(props) { return ( <html lang="en"> <head> @@ -14,7 +14,9 @@ function Document() { <Links /> </head> <body> - <Main /> + <Main> + {props.children} + </Main> <Scripts /> </body> </html> diff --git a/examples/basic-project/src/pages/about.tsx b/examples/basic-project/src/pages/about.tsx index 77e2ff96a..d57601aca 100644 --- a/examples/basic-project/src/pages/about.tsx +++ b/examples/basic-project/src/pages/about.tsx @@ -2,12 +2,32 @@ import * as React from 'react'; import { Link } from 'ice'; export default function About() { - return <><h2>About Page</h2><Link to="/">home</Link></>; + return ( + <> + <h2>About Page</h2> + <Link to="/">home</Link> + <span className="mark">new</span> + </> + ); } export function getPageConfig() { return { - auth: ['guest'], + title: 'About', + meta: [ + { + name: 'theme-color', + content: '#eee', + }, + ], + links: [{ + href: 'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css', + rel: 'stylesheet', + }], + scripts: [{ + src: 'https://cdn.jsdelivr.net/npm/lodash@2.4.1/dist/lodash.min.js', + }], + auth: ['admin'], }; } diff --git a/examples/basic-project/src/pages/index.tsx b/examples/basic-project/src/pages/index.tsx index 40632d971..0ef1cdff7 100644 --- a/examples/basic-project/src/pages/index.tsx +++ b/examples/basic-project/src/pages/index.tsx @@ -18,9 +18,17 @@ export default function Home(props) { export function getPageConfig(): PageConfig { return { - // scripts: [ - // { src: 'https://g.alicdn.com/alilog/mlog/aplus_v2.js', block: true }, - // ], + title: 'Home', + meta: [ + { + name: 'theme-color', + content: '#000', + }, + { + name: 'title-color', + content: '#f00', + }, + ], auth: ['admin'], }; } diff --git a/examples/routes-generate/ice.config.js b/examples/routes-generate/ice.config.ts similarity index 100% rename from examples/routes-generate/ice.config.js rename to examples/routes-generate/ice.config.ts diff --git a/examples/routes-generate/src/document.tsx b/examples/routes-generate/src/document.tsx index 1be1b41a0..24c078287 100644 --- a/examples/routes-generate/src/document.tsx +++ b/examples/routes-generate/src/document.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Meta, Title, Links, Main, Scripts } from 'ice'; -function Document() { +function Document(props) { return ( <html lang="en"> <head> @@ -14,7 +14,9 @@ function Document() { <Links /> </head> <body> - <Main /> + <Main> + {props.children} + </Main> <Scripts /> </body> </html> diff --git a/packages/build-webpack-config/src/unPlugins/compilation.ts b/packages/build-webpack-config/src/unPlugins/compilation.ts index 9c544da31..09d73efe4 100644 --- a/packages/build-webpack-config/src/unPlugins/compilation.ts +++ b/packages/build-webpack-config/src/unPlugins/compilation.ts @@ -12,7 +12,7 @@ type JSXSuffix = 'jsx' | 'tsx'; interface Options { rootDir: string; mode: 'development' | 'production' | 'none'; - isServer?: boolean; + compileIncludes?: (string | RegExp)[]; sourceMap?: Config['sourceMap']; } @@ -20,15 +20,16 @@ const require = createRequire(import.meta.url); const regeneratorRuntimePath = require.resolve('regenerator-runtime'); const compilationPlugin = (options: Options): UnpluginOptions => { - const { rootDir, sourceMap, mode, isServer } = options; + const { rootDir, sourceMap, mode, compileIncludes } = options; const dev = mode !== 'production'; - + const compileRegex = compileIncludes.map((includeRule) => { + return includeRule instanceof RegExp ? includeRule : new RegExp(includeRule); + }); return { name: 'compilation-plugin', // @ts-expect-error TODO: source map types async transform(source: string, id: string) { - // TODO specific runtime plugin name - if ((/node_modules/.test(id) && !/[\\/]runtime[\\/]/.test(id))) { + if ((/node_modules/.test(id) && !compileRegex.some((regex) => regex.test(id)))) { return; } @@ -40,7 +41,7 @@ const compilationPlugin = (options: Options): UnpluginOptions => { const programmaticOptions = { filename: id, sourceMaps: !!sourceMap, - ...getSwcTransformOptions({ suffix, rootDir, dev, isServer }), + ...getSwcTransformOptions({ suffix, rootDir, dev }), }; // auto detect development mode if (mode && programmaticOptions.jsc && programmaticOptions.jsc.transform && @@ -60,15 +61,13 @@ function getSwcTransformOptions({ suffix, rootDir, dev, - isServer, }: { suffix: JSXSuffix; rootDir: string; dev: boolean; - isServer?: boolean; }) { const baseReactTransformConfig = { - refresh: dev && !isServer, + refresh: dev, }; const reactTransformConfig = merge(baseReactTransformConfig, hasJsxRuntime(rootDir) ? { runtime: 'automatic' } : {}); @@ -95,9 +94,6 @@ function getSwcTransformOptions({ loose: true, }, }; - if (isServer) { - commonOptions.env.targets = 'node >= 12'; - } const jsOptions = merge({ jsc: { diff --git a/packages/build-webpack-config/src/unPlugins/index.ts b/packages/build-webpack-config/src/unPlugins/index.ts index d394e2a7b..aca0bfea7 100644 --- a/packages/build-webpack-config/src/unPlugins/index.ts +++ b/packages/build-webpack-config/src/unPlugins/index.ts @@ -3,9 +3,9 @@ import type { UnpluginOptions } from 'unplugin'; import compilationPlugin from './compilation.js'; const getTransformPlugins = (rootDir: string, config: Config): UnpluginOptions[] => { - const { sourceMap, transformPlugins = [], transforms = [], mode, isServer } = config; + const { sourceMap, transformPlugins = [], transforms = [], mode, compileIncludes } = config; return [ - compilationPlugin({ rootDir, sourceMap, mode, isServer }), + compilationPlugin({ rootDir, sourceMap, mode, compileIncludes }), ...transformPlugins, ...transforms.map((transform, index) => ({ name: `transform_${index}`, transform })), ]; diff --git a/packages/build-webpack-config/src/webpackPlugins/AssetsManifestPlugin.ts b/packages/build-webpack-config/src/webpackPlugins/AssetsManifestPlugin.ts index 1ec7852d7..78fb034c3 100644 --- a/packages/build-webpack-config/src/webpackPlugins/AssetsManifestPlugin.ts +++ b/packages/build-webpack-config/src/webpackPlugins/AssetsManifestPlugin.ts @@ -27,32 +27,29 @@ export default class AssetsManifestPlugin { } public createAssets(compilation: Compilation) { - const bundles = {}; + const entries = {}; + const pages = {}; const entrypoints = compilation.entrypoints.values(); for (const entrypoint of entrypoints) { const entryName = entrypoint.name; const mainFiles = getEntrypointFiles(entrypoint); - bundles[entryName] = { - isEntry: true, - files: mainFiles, - }; + + entries[entryName] = mainFiles; const chunks = entrypoint?.getChildren(); chunks.forEach((chunk: any) => { const chunkName = chunk.name; const chunkFiles = chunk.getFiles(); - bundles[chunkName] = { - isEntry: false, - files: chunkFiles, - }; + pages[chunkName] = chunkFiles; }); } const manifest = { publicPath: compilation.outputOptions?.publicPath, - bundles, + entries, + pages, }; const manifestFileName = resolve(this.outputDir, this.fileName); diff --git a/packages/ice/package.json b/packages/ice/package.json index d05c856c1..663d3440d 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -20,9 +20,9 @@ "homepage": "https://next.ice.work", "dependencies": { "@builder/pack": "^0.6.0", - "@ice/webpack-config": "^1.0.0", "@ice/route-manifest": "^1.0.0", "@ice/runtime": "^1.0.0", + "@ice/webpack-config": "^1.0.0", "address": "^1.1.2", "build-scripts": "^2.0.0-16", "chalk": "^4.0.0", @@ -34,6 +34,7 @@ "fast-glob": "^3.2.11", "find-up": "^5.0.0", "fs-extra": "^10.0.0", + "lodash.merge": "^4.6.2", "prettier": "^2.5.1", "semver": "^7.3.5", "webpack": "^5.69.1", @@ -42,7 +43,7 @@ "devDependencies": { "@ice/types": "^1.0.0", "@types/ejs": "^3.1.0", - "@types/lodash.debounce": "^4.0.6", + "@types/lodash.merge": "^4.6.6", "chokidar": "^3.5.3", "unplugin": "^0.3.2" } diff --git a/packages/ice/src/analyzeRuntime.ts b/packages/ice/src/analyzeRuntime.ts index 9f428414b..2133e8e38 100644 --- a/packages/ice/src/analyzeRuntime.ts +++ b/packages/ice/src/analyzeRuntime.ts @@ -17,8 +17,7 @@ export const getAppConfig = async (options: Options): Promise<AppConfig> => { entryPoints: [path.join(rootDir, 'src/app')], outfile, format: 'esm', - external: ['./node_modules/*'], - }, { isServer: true }); + }); const appConfig = (await import(outfile)).default; consola.debug('app config:', appConfig); diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 52829cf48..d439431ee 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -14,6 +14,7 @@ import getContextConfig from './utils/getContextConfig.js'; import getWatchEvents from './getWatchEvents.js'; import { getAppConfig } from './analyzeRuntime.js'; import { defineRuntimeEnv, updateRuntimeEnv } from './utils/runtimeEnv.js'; +import getRuntimeModules from './utils/getRuntimeModules.js'; import { generateRoutesInfo } from './routes.js'; import webPlugin from './plugins/web/index.js'; import configPlugin from './plugins/config.js'; @@ -83,7 +84,11 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt })); dataCache.set('routes', JSON.stringify(routesRenderData.routeManifest)); - generator.setPlugins(ctx.getAllPlugin()); + const runtimeModules = getRuntimeModules(ctx.getAllPlugin()); + generator.modifyRenderData((renderData) => ({ + ...renderData, + runtimeModules, + })); await ctx.setup(); // render template before webpack compile @@ -100,11 +105,12 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt // define runtime env before get webpack config defineRuntimeEnv(); - const contextConfig = getContextConfig(ctx); + const compileIncludes = runtimeModules.map(({ name }) => `${name}/runtime`); + const contextConfig = getContextConfig(ctx, { compileIncludes }); const webTask = contextConfig.find(({ name }) => name === 'web'); const esbuildCompile = createEsbuildCompiler({ - alias: webTask.webpackConfig.resolve.alias as Record<string, string>, - getTransformPlugins: webTask.getTransformPlugins, + rootDir, + task: webTask, }); return { diff --git a/packages/ice/src/plugins/config.ts b/packages/ice/src/plugins/config.ts index b30a0ed5f..4088cff21 100644 --- a/packages/ice/src/plugins/config.ts +++ b/packages/ice/src/plugins/config.ts @@ -90,6 +90,14 @@ const userConfig = [ } }, }, + { + name: 'ssg', + validation: 'boolean', + }, + { + name: 'ssr', + validation: 'boolean', + }, { name: 'webpack', validation: 'function', diff --git a/packages/ice/src/plugins/web/index.ts b/packages/ice/src/plugins/web/index.ts index f47b9113a..a63acc9dc 100644 --- a/packages/ice/src/plugins/web/index.ts +++ b/packages/ice/src/plugins/web/index.ts @@ -1,10 +1,11 @@ import * as path from 'path'; import type { Plugin } from '@ice/types'; -import generateHTML from './ssr/generateHtml.js'; +import generateHTML from './ssr/generateHTML.js'; import { setupRenderServer } from './ssr/serverRender.js'; const webPlugin: Plugin = ({ registerTask, context, onHook }) => { - const { command, rootDir } = context; + const { command, rootDir, userConfig } = context; + const { ssg = true, ssr = true } = userConfig; const outputDir = path.join(rootDir, 'build'); const routeManifest = path.join(rootDir, '.ice/route-manifest.json'); const serverEntry = path.join(outputDir, 'server/entry.mjs'); @@ -17,7 +18,7 @@ const webPlugin: Plugin = ({ registerTask, context, onHook }) => { // platform: 'node', format: 'esm', outExtension: { '.js': '.mjs' }, - }, { isServer: true }); + }); // timestamp for disable import cache return `${serverEntry}?version=${new Date().getTime()}`; }; @@ -28,6 +29,8 @@ const webPlugin: Plugin = ({ registerTask, context, onHook }) => { outDir: outputDir, entry: serverEntry, routeManifest, + ssg, + ssr, }); }); const mode = command === 'start' ? 'development' : 'production'; @@ -47,6 +50,8 @@ const webPlugin: Plugin = ({ registerTask, context, onHook }) => { middleware: setupRenderServer({ serverCompiler, routeManifest, + ssg, + ssr, }), }); diff --git a/packages/ice/src/plugins/web/ssr/generateHtml.ts b/packages/ice/src/plugins/web/ssr/generateHTML.ts similarity index 79% rename from packages/ice/src/plugins/web/ssr/generateHtml.ts rename to packages/ice/src/plugins/web/ssr/generateHTML.ts index 9288ed688..a804a1702 100644 --- a/packages/ice/src/plugins/web/ssr/generateHtml.ts +++ b/packages/ice/src/plugins/web/ssr/generateHTML.ts @@ -6,6 +6,8 @@ interface Options { entry: string; routeManifest: string; outDir: string; + ssg: boolean; + ssr: boolean; } export default async function generateHTML(options: Options) { @@ -13,6 +15,8 @@ export default async function generateHTML(options: Options) { entry, routeManifest, outDir, + ssg, + ssr, } = options; const serverEntry = await import(entry); @@ -21,17 +25,24 @@ export default async function generateHTML(options: Options) { for (let i = 0, n = paths.length; i < n; i++) { const routePath = paths[i]; - const htmlContent = await serverEntry.render({ + const requestContext = { req: { url: routePath, path: routePath, }, - }); + }; + + let html; + if (ssg || ssr) { + html = await serverEntry.render(requestContext); + } else { + html = await serverEntry.renderDocument(requestContext); + } const fileName = routePath === '/' ? 'index.html' : `${routePath}.html`; const contentPath = path.join(outDir, fileName); await fse.ensureFile(contentPath); - await fse.writeFile(contentPath, htmlContent); + await fse.writeFile(contentPath, html); } } @@ -52,4 +63,4 @@ function getPaths(routes: RouteItem[], parentPath = ''): string[] { }); return pathList; -} \ No newline at end of file +} diff --git a/packages/ice/src/plugins/web/ssr/serverRender.ts b/packages/ice/src/plugins/web/ssr/serverRender.ts index b8dcc6e55..721e703be 100644 --- a/packages/ice/src/plugins/web/ssr/serverRender.ts +++ b/packages/ice/src/plugins/web/ssr/serverRender.ts @@ -5,12 +5,16 @@ import type { Request, Response } from 'express'; interface Options { routeManifest: string; serverCompiler: () => Promise<string>; + ssg: boolean; + ssr: boolean; } export function setupRenderServer(options: Options) { const { routeManifest, serverCompiler, + ssg, + ssr, } = options; return async (req: Request, res: Response) => { @@ -23,10 +27,17 @@ export function setupRenderServer(options: Options) { const entry = await serverCompiler(); const serverEntry = await import(entry); - const html = await serverEntry.render({ + const requestContext = { req, res, - }); + }; + + let html; + if (ssg || ssr) { + html = await serverEntry.render(requestContext); + } else { + html = await serverEntry.renderDocument(requestContext); + } res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.send(html); diff --git a/packages/ice/src/service/compile.ts b/packages/ice/src/service/compile.ts index 5311ad308..e8193fcc1 100644 --- a/packages/ice/src/service/compile.ts +++ b/packages/ice/src/service/compile.ts @@ -3,27 +3,37 @@ import consola from 'consola'; import fg from 'fast-glob'; import esbuild from 'esbuild'; import { createUnplugin } from 'unplugin'; -import type { UnpluginOptions } from 'unplugin'; -import type { Config } from '@ice/types'; import type { EsbuildCompile } from '@ice/types/esm/plugin.js'; +import { getTransformPlugins } from '@ice/webpack-config'; +import type { ContextConfig } from '../utils/getContextConfig.js'; import { resolveId } from './analyze.js'; -export function createEsbuildCompiler(options: { - alias?: Record<string, string>; - getTransformPlugins?: (config: Partial<Config>) => UnpluginOptions[]; -}) { - const { alias = {}, getTransformPlugins } = options; - const esbuildCompile: EsbuildCompile = async (buildOptions, customConfig) => { +interface Options { + rootDir: string; + task: ContextConfig; +} + +export function createEsbuildCompiler(options: Options) { + const { task, rootDir } = options; + const { taskConfig, webpackConfig } = task; + const alias = webpackConfig.resolve?.alias || {}; + const compileRegex = (taskConfig.compileIncludes || []).map((includeRule) => { + return includeRule instanceof RegExp ? includeRule : new RegExp(includeRule); + }); + const transformPlugins = getTransformPlugins(rootDir, taskConfig); + const esbuildCompile: EsbuildCompile = async (buildOptions) => { const startTime = new Date().getTime(); consola.debug('[esbuild]', `start compile for: ${buildOptions.entryPoints}`); - const transformPlugins = getTransformPlugins(customConfig); const buildResult = await esbuild.build({ bundle: true, + target: 'node12.19.0', ...buildOptions, - // ref: https://github.com/evanw/esbuild/blob/master/CHANGELOG.md#01117 - // in esm, this in the global should be undefined. Set the following config to avoid warning define: { + // ref: https://github.com/evanw/esbuild/blob/master/CHANGELOG.md#01117 + // in esm, this in the global should be undefined. Set the following config to avoid warning this: undefined, + // TOOD: sync ice runtime env + 'process.env.ICE_RUNTIME_SERVER': 'true', }, plugins: [ { @@ -31,7 +41,8 @@ export function createEsbuildCompiler(options: { setup(build) { build.onResolve({ filter: /.*/ }, (args) => { const id = args.path; - const resolved = resolveId(id, alias); + // ice do not support alias with config onlyModule + const resolved = resolveId(id, alias as Record<string, string | false>); if (resolved && resolved !== id) { if (!path.extname(resolved)) { const basename = path.basename(resolved); @@ -52,8 +63,9 @@ export function createEsbuildCompiler(options: { build.onResolve({ filter: /.*/ }, (args) => { const id = args.path; // external ids which is third-party dependencies - // runtime folder need to been bundled while it is not compiled - if (id[0] !== '.' && !path.isAbsolute(id) && !id.includes('/runtime/')) { + if (id[0] !== '.' && !path.isAbsolute(id) && + // runtime folder need to been bundled while it is not compiled + !compileRegex.some((regex) => regex.test(id))) { return { external: true, }; @@ -61,7 +73,10 @@ export function createEsbuildCompiler(options: { }); }, }, - ...transformPlugins.map(plugin => createUnplugin(() => plugin).esbuild()), + ...transformPlugins + // ignore compilation-plugin while esbuild has it's own transform + .filter(({ name }) => name !== 'compilation-plugin') + .map(plugin => createUnplugin(() => plugin).esbuild()), ], }); consola.debug('[esbuild]', `time cost: ${new Date().getTime() - startTime}ms`); diff --git a/packages/ice/src/service/runtimeGenerator.ts b/packages/ice/src/service/runtimeGenerator.ts index 66179a8a7..48d409a0d 100644 --- a/packages/ice/src/service/runtimeGenerator.ts +++ b/packages/ice/src/service/runtimeGenerator.ts @@ -6,7 +6,6 @@ import ejs from 'ejs'; import prettier from 'prettier'; import lodash from '@builder/pack/deps/lodash/lodash.js'; import type { - SetPlugins, AddExport, RemoveExport, AddContent, @@ -17,7 +16,6 @@ import type { ModifyRenderData, AddRenderFile, AddTemplateFiles, - AddDisableRuntimePlugin, RenderDataRegistration, RenderTemplate, RenderData, @@ -25,7 +23,6 @@ import type { Registration, TemplateOptions, } from '@ice/types/esm/generator.js'; -import getRuntimeModules from '../utils/getRuntimeModules.js'; import formatPath from '../utils/formatPath.js'; const { debounce } = lodash; @@ -106,12 +103,8 @@ export default class Generator { private showPrettierError: boolean; - private disableRuntimePlugins: string[]; - private contentTypes: string[]; - private plugins: any[]; - public constructor(options: Options) { const { rootDir, targetDir, defaultRenderData = {}, templates } = options; this.rootDir = rootDir; @@ -122,9 +115,7 @@ export default class Generator { this.showPrettierError = true; this.renderTemplates = []; this.renderDataRegistration = []; - this.disableRuntimePlugins = []; this.contentTypes = ['framework', 'frameworkTypes', 'configTypes']; - this.plugins = []; // empty .ice before render fse.emptyDirSync(path.join(rootDir, targetDir)); // add initial templates @@ -133,10 +124,6 @@ export default class Generator { } } - public setPlugins: SetPlugins = (plugins) => { - this.plugins = plugins; - }; - private debounceRender = debounce(() => { this.render(); }, RENDER_WAIT); @@ -209,11 +196,6 @@ export default class Generator { } return previousValue; }, this.parseRenderData()); - // 生成所有运行时插件,在 load 阶段判断是否需要加载,确保 index 中的 exports 路径永远可以获取引用 - this.renderData.runtimeModules = getRuntimeModules(this.plugins) - .filter((plugin) => { - return !this.disableRuntimePlugins.includes(plugin?.name); - }); this.renderTemplates.forEach((args) => { this.renderFile(...args); @@ -300,10 +282,4 @@ export default class Generator { fse.copyFileSync(templatePath, realTargetPath); } }; - - public addDisableRuntimePlugin: AddDisableRuntimePlugin = (pluginName) => { - if (!this.disableRuntimePlugins.includes(pluginName)) { - this.disableRuntimePlugins.push(pluginName); - } - }; } diff --git a/packages/ice/src/utils/getContextConfig.ts b/packages/ice/src/utils/getContextConfig.ts index e2376bb95..66383f417 100644 --- a/packages/ice/src/utils/getContextConfig.ts +++ b/packages/ice/src/utils/getContextConfig.ts @@ -2,8 +2,8 @@ import type { Context } from 'build-scripts'; import type { Config } from '@ice/types'; import type { Configuration } from 'webpack'; import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'; -import type { UnpluginOptions } from 'unplugin'; -import { getWebpackConfig, getTransformPlugins as getBuiltInPlugins } from '@ice/webpack-config'; +import { getWebpackConfig } from '@ice/webpack-config'; +import merge from 'lodash.merge'; export interface ContextConfig { name: string; @@ -11,32 +11,24 @@ export interface ContextConfig { webpackConfig: Configuration & { devServer?: DevServerConfiguration; }; - getTransformPlugins: (config?: Partial<Config>) => UnpluginOptions[]; } -function getContextConfig(context: Context<Config>): ContextConfig[] { +function getContextConfig(context: Context<Config>, customConfig: Partial<Config>): ContextConfig[] { const { getConfig, rootDir } = context; + const contextConfig = getConfig(); if (!contextConfig.length) { throw new Error('Task config is not Found'); } const configs = contextConfig.map(({ config, name }) => { - // add runtime alias for built-in plugins const webpackConfig = getWebpackConfig({ rootDir, - config, + config: merge(config, customConfig), }); - const getTransformPlugins = (customConfig?: Partial<Config>) => { - return getBuiltInPlugins(rootDir, { - ...config, - ...(customConfig || {}), - }); - }; return { name, taskConfig: config, webpackConfig, - getTransformPlugins, }; }); return configs; diff --git a/packages/ice/src/utils/getRuntimeModules.ts b/packages/ice/src/utils/getRuntimeModules.ts index da64fd750..7d598397f 100644 --- a/packages/ice/src/utils/getRuntimeModules.ts +++ b/packages/ice/src/utils/getRuntimeModules.ts @@ -9,7 +9,7 @@ export interface RuntimeModule { } export interface Plugin { - pluginPath: string; + pluginPath?: string; } function getRuntimeModules(plugins: Plugin[]) { @@ -27,7 +27,7 @@ function getRuntimeModules(plugins: Plugin[]) { const pkgInfo = fse.readJSONSync(pkgPath); return { staticModule: !!pkgInfo?.pluginConfig?.staticModule, - path: `${packageDir}/runtime`, + path: `${pkgInfo.name}/runtime`, name: pkgInfo.name as string, }; } catch (error) { diff --git a/packages/ice/template/entry.client.ts.ejs b/packages/ice/template/entry.client.ts.ejs index f7dcc9500..81007b48d 100644 --- a/packages/ice/template/entry.client.ts.ejs +++ b/packages/ice/template/entry.client.ts.ejs @@ -2,5 +2,11 @@ import { runClientApp } from '@ice/runtime'; import appConfig from '@/app'; import runtimeModules from './runtimeModules'; import routes from './routes'; +import Document from '@/document'; -runClientApp(appConfig, runtimeModules, routes); \ No newline at end of file +runClientApp({ + appConfig, + runtimeModules, + routes, + Document +}); \ No newline at end of file diff --git a/packages/ice/template/entry.server.ts.ejs b/packages/ice/template/entry.server.ts.ejs index bae5fcc23..c3b79eaad 100644 --- a/packages/ice/template/entry.server.ts.ejs +++ b/packages/ice/template/entry.server.ts.ejs @@ -1,18 +1,26 @@ -import { runServerApp } from '@ice/runtime'; +import { runServerApp, renderDocument as runDocumentRender } from '@ice/runtime'; import appConfig from '@/app'; import runtimeModules from './runtimeModules'; import Document from '@/document'; import assetsManifest from './assets-manifest.json'; import routes from './routes'; -export async function render(requestContext, documentOnly = false) { - return await runServerApp({ - requestContext, - runtimeModules, +export async function render(requestContext) { + return await runServerApp(requestContext, { appConfig, + assetsManifest, routes, + runtimeModules, + Document, + }); +} + +export async function renderDocument(requestContext) { + return await runDocumentRender(requestContext, { + appConfig, assetsManifest, + routes, + runtimeModules, Document, - documentOnly, }); } \ No newline at end of file diff --git a/packages/plugin-auth/package.json b/packages/plugin-auth/package.json index e184a80f6..efb5ad43c 100644 --- a/packages/plugin-auth/package.json +++ b/packages/plugin-auth/package.json @@ -7,7 +7,7 @@ "main": "./esm/index.js", "exports": { ".": "./esm/index.js", - "./runtime": "./runtime", + "./runtime": "./runtime/index.tsx", "./runtime/Auth": "./runtime/Auth.tsx", "./runtime/types": "./runtime/types.ts" }, diff --git a/packages/runtime/src/App.tsx b/packages/runtime/src/App.tsx index c94e35fd8..d2a3dc868 100644 --- a/packages/runtime/src/App.tsx +++ b/packages/runtime/src/App.tsx @@ -2,16 +2,15 @@ import React, { useMemo } from 'react'; import type { Action, Location } from 'history'; import type { Navigator } from 'react-router-dom'; import AppErrorBoundary from './AppErrorBoundary.js'; -import { AppContextProvider } from './AppContext.js'; +import { useAppContext } from './AppContext.js'; import { createRouteElements } from './routes.js'; -import type { AppContext, PageWrapper, AppRouterProps } from './types'; +import type { PageWrapper, AppRouterProps } from './types'; interface Props { action: Action; location: Location; navigator: Navigator; static?: boolean; - appContext: AppContext; AppProvider: React.ComponentType<any>; PageWrappers: PageWrapper<{}>[]; AppRouter: React.ComponentType<AppRouterProps>; @@ -19,10 +18,16 @@ interface Props { export default function App(props: Props) { const { - location, action, navigator, static: staticProp = false, - appContext, AppProvider, AppRouter, PageWrappers, + location, + action, + navigator, + static: staticProp = false, + AppProvider, + AppRouter, + PageWrappers, } = props; - const { appConfig, routes: originRoutes } = appContext; + + const { appConfig, routes: originRoutes } = useAppContext(); const { strict } = appConfig.app; const StrictMode = strict ? React.StrictMode : React.Fragment; @@ -52,16 +57,13 @@ export default function App(props: Props) { /> ); } + return ( <StrictMode> <AppErrorBoundary> - <AppContextProvider - value={appContext} - > - <AppProvider> - {element} - </AppProvider> - </AppContextProvider> + <AppProvider> + {element} + </AppProvider> </AppErrorBoundary> </StrictMode> ); diff --git a/packages/runtime/src/Document.tsx b/packages/runtime/src/Document.tsx index 0f15c499a..53694cf81 100644 --- a/packages/runtime/src/Document.tsx +++ b/packages/runtime/src/Document.tsx @@ -1,38 +1,24 @@ import * as React from 'react'; -import type { PageData, AppData } from './types'; - -interface DocumentContext { - html?: string; - entryAssets?: string[]; - pageAssets?: string[]; - pageData?: PageData; - appData?: AppData; -} - -const Context = React.createContext<DocumentContext>(null); - -Context.displayName = 'DocumentContext'; - -export const useDocumentContext = () => { - const value = React.useContext(Context); - return value; -}; - -export const DocumentContextProvider = Context.Provider; +import { useAppContext } from './AppContext.js'; +import { getPageAssets, getEntryAssets } from './assets.js'; export function Meta() { - const { pageData } = useDocumentContext(); + const { pageData } = useAppContext(); const meta = pageData.pageConfig.meta || []; return ( <> - {meta.map(([name, value]) => <meta key={name} name={name} content={value} />)} + {meta.map(item => <meta key={item.name} {...item} />)} + <meta + name="ice-meta-count" + content={meta.length.toString()} + /> </> ); } export function Title() { - const { pageData } = useDocumentContext(); + const { pageData } = useAppContext(); const title = pageData.pageConfig.title || []; return ( @@ -41,18 +27,20 @@ export function Title() { } export function Links() { - const { pageAssets, entryAssets, pageData } = useDocumentContext(); + const { pageData, matches, assetsManifest } = useAppContext(); + const customLinks = pageData.pageConfig.links || []; - const blockLinks = customLinks.filter((link) => link.block); + const pageAssets = getPageAssets(matches, assetsManifest); + const entryAssets = getEntryAssets(assetsManifest); const styles = pageAssets.concat(entryAssets).filter(path => path.indexOf('.css') > -1); return ( <> { - blockLinks.map(link => { + customLinks.map(link => { const { block, ...props } = link; - return <script key={link.href} {...props} />; + return <link key={link.href} {...props} />; }) } {styles.map(style => <link key={style} rel="stylesheet" type="text/css" href={style} />)} @@ -61,50 +49,57 @@ export function Links() { } export function Scripts() { - const { pageData, pageAssets, entryAssets, appData } = useDocumentContext(); - const { links: customLinks = [], scripts: customScripts = [] } = pageData.pageConfig; + const { pageData, initialData, matches, assetsManifest, documentOnly } = useAppContext(); + + const pageAssets = getPageAssets(matches, assetsManifest); + const entryAssets = getEntryAssets(assetsManifest); + + const { scripts: customScripts = [] } = pageData.pageConfig; const scripts = pageAssets.concat(entryAssets).filter(path => path.indexOf('.js') > -1); - const blockScripts = customScripts.filter(script => script.block); - const deferredScripts = customScripts.filter(script => !script.block); - const deferredLinks = customLinks.filter(link => !link.block); + const appContext = { + initialData, + pageData, + assetsManifest, + }; return ( <> - <script dangerouslySetInnerHTML={{ __html: `window.__ICE_APP_DATA__=${JSON.stringify(appData)}` }} /> - <script dangerouslySetInnerHTML={{ __html: `window.__ICE_PAGE_DATA__=${JSON.stringify(pageData)}` }} /> + {/* + * disable hydration warning for csr. + * initial app data may not equal csr result. + */} + <script suppressHydrationWarning={documentOnly} dangerouslySetInnerHTML={{ __html: `window.__ICE_APP_CONTEXT__=${JSON.stringify(appContext)}` }} /> { - blockScripts.map(script => { + customScripts.map(script => { const { block, ...props } = script; - return <script key={script.src} {...props} />; + return <script key={script.src} defer {...props} />; }) } + {/* + * script must be deferred. + * if there are other dom after this tag, and hydrate before parsed all dom, + * hydrate will fail due to inconsistent dom nodes. + */} { scripts.map(script => { - return <script key={script} src={script} />; - }) - } - { - deferredLinks.map(link => { - const { block, ...props } = link; - return <script key={link.href} {...props} />; - }) - } - { - deferredScripts.map(script => { - const { block, ...props } = script; - return <script key={script.src} defer="true" {...props} />; + return <script key={script} defer src={script} />; }) } </> ); } -export function Main() { - const { html } = useDocumentContext(); +export function Main(props) { + const { documentOnly } = useAppContext(); - // TODO: set id from config - // eslint-disable-next-line react/self-closing-comp - return <div id="ice-container" dangerouslySetInnerHTML={{ __html: html || '' }}></div>; -} + // disable hydration warning for csr. + // document is rendered by hydration. + // initial content form "ice-container" is empty, which will not match csr result. + return ( + <div id="ice-container" suppressHydrationWarning={documentOnly} > + {props.children} + </div> + ); +} \ No newline at end of file diff --git a/packages/runtime/src/assets.ts b/packages/runtime/src/assets.ts index deebcfbb8..a725f4feb 100644 --- a/packages/runtime/src/assets.ts +++ b/packages/runtime/src/assets.ts @@ -1,19 +1,18 @@ import type { AssetsManifest, RouteMatch } from './types'; + /** * merge assets info for matched page - * @param matches - * @param assetsManifest - * @returns */ export function getPageAssets(matches: RouteMatch[], assetsManifest: AssetsManifest): string[] { - const { bundles, publicPath } = assetsManifest; + // TODO:publicPath from runtime + const { pages, publicPath } = assetsManifest; let result = []; matches.forEach(match => { const { componentName } = match.route; - const assets = bundles[componentName]; - assets && assets?.files.forEach(filePath => { + const assets = pages[componentName]; + assets && assets.forEach(filePath => { result.push(`${publicPath}${filePath}`); }); }); @@ -22,13 +21,79 @@ export function getPageAssets(matches: RouteMatch[], assetsManifest: AssetsManif } export function getEntryAssets(assetsManifest: AssetsManifest): string[] { - const { bundles, publicPath } = assetsManifest; - const assets = []; - Object.keys(bundles).forEach(key => { - const { isEntry, files } = bundles[key]; - if (isEntry) { - assets.push(...files); + const { entries, publicPath } = assetsManifest; + let result = []; + + Object.values(entries).forEach(assets => { + result = result.concat(assets); + }); + + return result.map(filePath => `${publicPath}${filePath}`); +} + +/** + * Load links for the next page. + */ +export async function loadStyleLinks(links): Promise<void> { + if (!links?.length) return; + + const matchedLinks = links.filter(link => { + const existingTags = document.querySelectorAll(`link[href='${link.href}']`); + return !existingTags.length; + }); + + await Promise.all(matchedLinks.map((link) => { + return preLoadAssets('link', link); + })); +} + +/** + * Load scripts for the next page. + */ +export async function loadScripts(scripts): Promise<void> { + if (!scripts?.length) return; + + const matchedScript = scripts.filter(script => { + const existingTags = document.querySelectorAll(`script[scr='${script.src}']`); + return !existingTags.length; + }); + + await Promise.all(matchedScript.map((script) => { + return preLoadAssets('script', script); + })); +} + +/** + * PreLoad assets by create tag. + * Remove this tag after onload. + * Actual tag will be created by rendering Document. + */ +async function preLoadAssets(type, props): Promise<void> { + return new Promise(resolve => { + let tag = document.createElement(type); + Object.assign(tag, props); + + function removeTag() { + // if a navigation interrupts this prefetch React will update the <head> + // and remove the link we put in there manually, so we check if it's still + // there before trying to remove it + if (document.head.contains(tag)) { + document.head.removeChild(tag); + } } + + tag.onload = () => { + // FIXME: Style link reloads on real DOM rendering if caching is disabled. + // ISSUE: https://github.com/ice-lab/ice-next/issues/90 + removeTag(); + resolve(); + }; + + tag.onerror = () => { + removeTag(); + resolve(); + }; + + document.head.appendChild(tag); }); - return assets.map(filePath => `${publicPath}${filePath}`); } \ No newline at end of file diff --git a/packages/runtime/src/defineAppConfig.ts b/packages/runtime/src/defineAppConfig.ts index bca63de7f..b288e42a7 100644 --- a/packages/runtime/src/defineAppConfig.ts +++ b/packages/runtime/src/defineAppConfig.ts @@ -2,7 +2,6 @@ import type { AppConfig } from './types'; const defaultAppConfig: AppConfig = { app: { - rootId: 'ice-container', strict: true, }, router: { diff --git a/packages/runtime/src/getInitialContext.ts b/packages/runtime/src/getInitialContext.ts deleted file mode 100644 index 3963623df..000000000 --- a/packages/runtime/src/getInitialContext.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { createSearchParams } from 'react-router-dom'; -import type { InitialContext } from './types'; - -export default function getInitialContext() { - const { href, origin, pathname, search } = window.location; - const path = href.replace(origin, ''); - const query = Object.fromEntries(createSearchParams(search)); - const initialContext: InitialContext = { - pathname, - path, - query, - }; - - return initialContext; -} \ No newline at end of file diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index eadad8d37..02defadfc 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -7,7 +7,7 @@ import { import Runtime from './runtime.js'; import App from './App.js'; import runClientApp from './runClientApp.js'; -import runServerApp from './runServerApp.js'; +import runServerApp, { renderDocument } from './runServerApp.js'; import { useAppContext } from './AppContext.js'; import { Meta, @@ -32,6 +32,7 @@ export { App, runClientApp, runServerApp, + renderDocument, useAppContext, Meta, Title, diff --git a/packages/runtime/src/routes.tsx b/packages/runtime/src/routes.tsx index ff15cd6fc..aa3e2e67a 100644 --- a/packages/runtime/src/routes.tsx +++ b/packages/runtime/src/routes.tsx @@ -3,7 +3,7 @@ import type { Location } from 'history'; import type { RouteObject } from 'react-router-dom'; import { matchRoutes as originMatchRoutes } from 'react-router-dom'; import PageWrapper from './PageWrapper.js'; -import type { RouteItem, RouteModules, PageWrapper as IPageWrapper, RouteMatch, InitialContext } from './types'; +import type { RouteItem, RouteModules, PageWrapper as IPageWrapper, RouteMatch, InitialContext, PageConfig } from './types'; // global route modules cache const routeModules: RouteModules = {}; @@ -48,7 +48,7 @@ export async function loadPageData(matches: RouteMatch[], initialContext: Initia const { getInitialData, getPageConfig } = routeModule; let initialData; - let pageConfig = {}; + let pageConfig: PageConfig = {}; if (getInitialData) { initialData = await getInitialData(initialContext); @@ -66,6 +66,20 @@ export async function loadPageData(matches: RouteMatch[], initialContext: Initia }; } +/** + * Load page config without initial data. + */ +export function loadPageConfig(matches: RouteMatch[]) { + const last = matches.length - 1; + const { route } = matches[last]; + const { id } = route; + + const routeModule = routeModules[id]; + + const { getPageConfig } = routeModule; + return getPageConfig({ initialData: null }); +} + /** * Create elements in routes which will be consumed by react-router-dom */ diff --git a/packages/runtime/src/runClientApp.tsx b/packages/runtime/src/runClientApp.tsx index a4ff720f1..d175e34f6 100644 --- a/packages/runtime/src/runClientApp.tsx +++ b/packages/runtime/src/runClientApp.tsx @@ -1,28 +1,41 @@ import React, { useLayoutEffect, useState } from 'react'; import { createHashHistory, createBrowserHistory } from 'history'; import type { HashHistory, BrowserHistory } from 'history'; +import { createSearchParams } from 'react-router-dom'; import Runtime from './runtime.js'; import App from './App.js'; -import type { AppContext, AppConfig, RouteItem, AppRouterProps, PageWrapper, RuntimeModules } from './types'; +import { AppContextProvider } from './AppContext.js'; +import type { AppContext, AppConfig, RouteItem, AppRouterProps, PageWrapper, RuntimeModules, InitialContext } from './types'; import { loadRouteModules, loadPageData, matchRoutes } from './routes.js'; -import getInitialContext from './getInitialContext.js'; +import { loadStyleLinks, loadScripts } from './assets.js'; + +interface RunClientAppOptions { + appConfig: AppConfig; + routes: RouteItem[]; + runtimeModules: RuntimeModules; + Document: React.ComponentType<{}>; +} + +export default async function runClientApp(options: RunClientAppOptions) { + const { + appConfig, + routes, + runtimeModules, + Document, + } = options; -export default async function runClientApp( - appConfig: AppConfig, - runtimeModules: RuntimeModules, - routes: RouteItem[], -) { const matches = matchRoutes(routes, window.location); await loadRouteModules(matches.map(({ route: { id, load } }) => ({ id, load }))); - const initialContext = getInitialContext(); - let appData = (window as any).__ICE_APP_DATA__ || {}; - let { initialData } = appData; + const appContextFromServer = (window as any).__ICE_APP_CONTEXT__ || {}; + + let { initialData, pageData, assetsManifest } = appContextFromServer; + + const initialContext = getInitialContext(); if (!initialData && appConfig.app?.getInitialData) { initialData = await appConfig.app.getInitialData(initialContext); } - let pageData = (window as any).__ICE_PAGE_DATA__ || {}; if (!pageData) { pageData = await loadPageData(matches, initialContext); } @@ -32,25 +45,28 @@ export default async function runClientApp( appConfig, initialData, initialPageData: pageData, + assetsManifest, + matches, }; + // TODO: provide useAppContext for runtime modules const runtime = new Runtime(appContext); runtimeModules.forEach(m => { runtime.loadModule(m); }); - render(runtime); + render(runtime, Document); } -async function render(runtime: Runtime) { +async function render(runtime: Runtime, Document: React.ComponentType<{}>) { const appContext = runtime.getAppContext(); const { appConfig } = appContext; - const { app: { rootId }, router: { type: routerType } } = appConfig; + const { router: { type: routerType } } = appConfig; const render = runtime.getRender(); const AppProvider = runtime.composeAppProvider() || React.Fragment; const PageWrappers = runtime.getWrapperPageRegistration(); const AppRouter = runtime.getAppRouter(); - const appMountNode = document.getElementById(rootId); + const history = (routerType === 'hash' ? createHashHistory : createBrowserHistory)({ window }); render( @@ -60,8 +76,9 @@ async function render(runtime: Runtime) { AppProvider={AppProvider} PageWrappers={PageWrappers} AppRouter={AppRouter} + Document={Document} />, - appMountNode, + document, ); } @@ -71,16 +88,20 @@ interface BrowserEntryProps { AppProvider: React.ComponentType<any>; PageWrappers: PageWrapper<{}>[]; AppRouter: React.ComponentType<AppRouterProps>; + Document: React.ComponentType<{}>; } -function BrowserEntry({ history, appContext, ...rest }: BrowserEntryProps) { - const { routes, initialPageData } = appContext; +function BrowserEntry({ history, appContext, Document, ...rest }: BrowserEntryProps) { + const { routes, initialPageData, matches: originMatches } = appContext; + const [historyState, setHistoryState] = useState({ action: history.action, location: history.location, pageData: initialPageData, + matches: originMatches, }); - const { action, location, pageData } = historyState; + + const { action, location, pageData, matches } = historyState; // listen the history change and update the state which including the latest action and location useLayoutEffect(() => { @@ -90,28 +111,61 @@ function BrowserEntry({ history, appContext, ...rest }: BrowserEntryProps) { throw new Error(`Routes not found in location ${location.pathname}.`); } - loadRouteModules(matches.map(({ route: { id, load } }) => ({ id, load }))) - .then(() => { - const initialContext = getInitialContext(); - return loadPageData(matches, initialContext); - }) - .then((pageData) => { - // just re-render once, so add pageData to historyState :( - setHistoryState({ action, location, pageData }); - }); + loadNextPage(matches, (pageData) => { + // just re-render once, so add pageData to historyState :( + setHistoryState({ action, location, pageData, matches }); + }); }); }, []); + // update app context for the current route. + Object.assign(appContext, { + matches, + pageData, + }); + return ( - <App - action={action} - location={location} - navigator={history} - appContext={{ - ...appContext, - pageData, - }} - {...rest} - /> + <AppContextProvider value={appContext}> + <Document> + <App + action={action} + location={location} + navigator={history} + {...rest} + /> + </Document> + </AppContextProvider> ); +} + +/** + * Prepare for the next pages. + * Load modules、getPageData and preLoad the custom assets. + */ +async function loadNextPage(matches, callback) { + await loadRouteModules(matches.map(({ route: { id, load } }) => ({ id, load }))); + + const initialContext = getInitialContext(); + const pageData = await loadPageData(matches, initialContext); + + const { pageConfig } = pageData; + await Promise.all([ + loadStyleLinks(pageConfig.links), + loadScripts(pageConfig.scripts), + ]); + + callback(pageData); +} + +function getInitialContext() { + const { href, origin, pathname, search } = window.location; + const path = href.replace(origin, ''); + const query = Object.fromEntries(createSearchParams(search)); + const initialContext: InitialContext = { + pathname, + path, + query, + }; + + return initialContext; } \ No newline at end of file diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 0932bcde2..38f2a3d9d 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -5,50 +5,46 @@ import { Action, createPath, parsePath } from 'history'; import { createSearchParams } from 'react-router-dom'; import Runtime from './runtime.js'; import App from './App.js'; -import { DocumentContextProvider } from './Document.js'; -import { loadRouteModules, loadPageData, matchRoutes } from './routes.js'; -import { getPageAssets, getEntryAssets } from './assets.js'; +import { AppContextProvider } from './AppContext.js'; +import { loadRouteModules, loadPageData, loadPageConfig, matchRoutes } from './routes.js'; import type { AppContext, InitialContext, RouteItem, ServerContext, AppConfig, RuntimePlugin, CommonJsRuntime, AssetsManifest } from './types'; -interface RunServerAppOptions { - requestContext: ServerContext; +interface RenderOptions { appConfig: AppConfig; + assetsManifest: AssetsManifest; routes: RouteItem[]; - documentOnly: boolean; runtimeModules: (RuntimePlugin | CommonJsRuntime)[]; Document: React.ComponentType<{}>; - assetsManifest: AssetsManifest; } -async function runServerApp(options: RunServerAppOptions): Promise<string> { +export default async function runServerApp(requestContext: ServerContext, options: RenderOptions): Promise<string> { + try { + return await renderServerApp(requestContext, options); + } catch (error) { + console.error('renderServerApp error: ', error); + return await renderDocument(requestContext, options); + } +} + +/** + * Render App by SSR. + */ +export async function renderServerApp(requestContext: ServerContext, options: RenderOptions): Promise<string> { + const { req } = requestContext; + const { - appConfig, assetsManifest, - Document, - documentOnly, - requestContext, + appConfig, runtimeModules, routes, + Document, } = options; - const { req } = requestContext; - const { url } = req; - - // ref: https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/server.tsx - const locationProps = parsePath(url); - - const location: Location = { - pathname: locationProps.pathname || '/', - search: locationProps.search || '', - hash: locationProps.hash || '', - state: null, - key: 'default', - }; - + const location = getLocation(req.url); const matches = matchRoutes(routes, location); - // TODO: error handling if (!matches.length) { + // TODO: Render 404 throw new Error('No matched page found.'); } @@ -58,7 +54,7 @@ async function runServerApp(options: RunServerAppOptions): Promise<string> { ...requestContext, pathname: location.pathname, query: Object.fromEntries(createSearchParams(location.search)), - path: url, + path: req.url, }; let initialData; @@ -69,14 +65,14 @@ async function runServerApp(options: RunServerAppOptions): Promise<string> { const pageData = await loadPageData(matches, initialContext); const appContext: AppContext = { - matches, - routes, appConfig, + assetsManifest, initialData, initialPageData: pageData, // pageData and initialPageData are the same when SSR/SSG pageData, - assetsManifest, + matches, + routes, }; const runtime = new Runtime(appContext); @@ -84,67 +80,94 @@ async function runServerApp(options: RunServerAppOptions): Promise<string> { runtime.loadModule(m); }); - const html = await render(Document, runtime, location, documentOnly); - return html; + const staticNavigator = createStaticNavigator(); + const AppProvider = runtime.composeAppProvider() || React.Fragment; + const PageWrappers = runtime.getWrapperPageRegistration(); + const AppRouter = runtime.getAppRouter(); + + const result = ReactDOMServer.renderToString( + <AppContextProvider value={appContext}> + <Document> + <App + action={Action.Pop} + location={location} + navigator={staticNavigator} + static + AppProvider={AppProvider} + PageWrappers={PageWrappers} + AppRouter={AppRouter} + /> + </Document> + </AppContextProvider>, + ); + + // TODO: send html in render function. + return result; } -export default runServerApp; - -async function render( - Document: React.ComponentType<{}>, - runtime: Runtime, - location: Location, - documentOnly: boolean, -) { - const appContext = runtime.getAppContext(); - const { matches, initialData, pageData, assetsManifest } = appContext; - - let html = ''; - - if (!documentOnly) { - const staticNavigator = createStaticNavigator(); - const AppProvider = runtime.composeAppProvider() || React.Fragment; - const PageWrappers = runtime.getWrapperPageRegistration(); - const AppRouter = runtime.getAppRouter(); - - html = ReactDOMServer.renderToString( - <App - action={Action.Pop} - location={location} - navigator={staticNavigator} - static - appContext={appContext} - AppProvider={AppProvider} - PageWrappers={PageWrappers} - AppRouter={AppRouter} - />, - ); +/** + * Render Document for CSR. + */ +export async function renderDocument(requestContext: ServerContext, options: RenderOptions): Promise<string> { + const { req } = requestContext; + + const { + routes, + assetsManifest, + appConfig, + Document, + } = options; + + const location = getLocation(req.url); + const matches = matchRoutes(routes, location); + + if (!matches.length) { + throw new Error('No matched page found.'); } - const pageAssets = getPageAssets(matches, assetsManifest); - const entryAssets = getEntryAssets(assetsManifest); + await loadRouteModules(matches.map(({ route: { id, load } }) => ({ id, load }))); - const appData = { - initialData, + const pageConfig = loadPageConfig(matches); + + const pageData = { + pageConfig, }; - const documentContext = { - appData, + const appContext: AppContext = { + assetsManifest, + appConfig, pageData, - pageAssets, - entryAssets, - html, + matches, + routes, + documentOnly: true, }; const result = ReactDOMServer.renderToString( - <DocumentContextProvider value={documentContext}> + <AppContextProvider value={appContext}> <Document /> - </DocumentContextProvider>, + </AppContextProvider>, ); return result; } +/** + * ref: https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/server.tsx + */ +function getLocation(url) { + const locationProps = parsePath(url); + + const location: Location = { + pathname: locationProps.pathname || '/', + search: locationProps.search || '', + hash: locationProps.hash || '', + state: null, + key: 'default', + }; + + return location; +} + function createStaticNavigator() { return { createHref(to: To) { diff --git a/packages/runtime/src/runtime.tsx b/packages/runtime/src/runtime.tsx index ffe0a6264..f20fc240e 100644 --- a/packages/runtime/src/runtime.tsx +++ b/packages/runtime/src/runtime.tsx @@ -40,9 +40,7 @@ class Runtime { public getAppContext = () => this.appContext; public getRender = () => { - // TODO: set ssr by process env - const isSSR = true; - return isSSR ? ReactDOM.hydrate : this.render; + return ReactDOM.hydrate; }; public getAppRouter = () => this.AppRouter; diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index a7c4059e1..c0dde80ef 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -7,7 +7,6 @@ import type { usePageContext } from './PageContext'; type VoidFunction = () => void; type AppLifecycle = 'onShow' | 'onHide' | 'onPageNotFound' | 'onShareAppMessage' | 'onUnhandledRejection' | 'onLaunch' | 'onError' | 'onTabItemClick'; type App = Partial<{ - rootId?: string; strict?: boolean; addProvider?: ({ children }: { children: ReactNode }) => ReactNode; getInitialData?: (ctx?: InitialContext) => Promise<any>; @@ -77,11 +76,9 @@ export interface RouteModules { } export interface AssetsManifest { - publicPath?: string; - bundles?: Record<string, { - files: string[]; - isEntry: boolean; - }>; + publicPath: string; + entries: string[]; + pages: string[]; } export interface AppContext { appConfig: AppConfig; @@ -91,10 +88,7 @@ export interface AppContext { initialData?: InitialData; pageData?: PageData; initialPageData?: PageData; -} - -export interface AppData { - initialData?: InitialData; + documentOnly?: boolean; } export interface PageData { diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index 1f64bb953..3fa762bbe 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -47,5 +47,5 @@ export interface Config { proxy?: ProxyConfigArrayItem | ProxyConfigMap | ProxyConfigArray | undefined; - isServer?: boolean; + compileIncludes?: (string | RegExp)[]; } diff --git a/packages/types/src/generator.ts b/packages/types/src/generator.ts index aef9c576a..354e604ca 100644 --- a/packages/types/src/generator.ts +++ b/packages/types/src/generator.ts @@ -31,4 +31,3 @@ export type ModifyRenderData = (registration: RenderDataRegistration) => void; export type AddRenderFile = (templatePath: string, targetPath: string, extraData?: ExtraData) => void; export type AddTemplateFiles = (templateOptions: string | TemplateOptions, extraData?: ExtraData) => void; export type RenderFile = (templatePath: string, targetPath: string, extraData?: ExtraData) => void; -export type AddDisableRuntimePlugin = (pluginName: string) => void; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d79505f93..23a4f7ee0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -169,7 +169,7 @@ importers: '@ice/types': ^1.0.0 '@ice/webpack-config': ^1.0.0 '@types/ejs': ^3.1.0 - '@types/lodash.debounce': ^4.0.6 + '@types/lodash.merge': ^4.6.6 address: ^1.1.2 build-scripts: ^2.0.0-16 chalk: ^4.0.0 @@ -182,6 +182,7 @@ importers: fast-glob: ^3.2.11 find-up: ^5.0.0 fs-extra: ^10.0.0 + lodash.merge: ^4.6.2 prettier: ^2.5.1 semver: ^7.3.5 unplugin: ^0.3.2 @@ -203,6 +204,7 @@ importers: fast-glob: 3.2.11 find-up: 5.0.0 fs-extra: 10.0.1 + lodash.merge: 4.6.2 prettier: 2.6.2 semver: 7.3.6 webpack: 5.72.0_esbuild@0.14.34 @@ -210,7 +212,7 @@ importers: devDependencies: '@ice/types': link:../types '@types/ejs': 3.1.0 - '@types/lodash.debounce': 4.0.6 + '@types/lodash.merge': 4.6.6 chokidar: 3.5.3 unplugin: 0.3.3_esbuild@0.14.34+webpack@5.72.0 @@ -1289,8 +1291,8 @@ packages: resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} dev: true - /@types/lodash.debounce/4.0.6: - resolution: {integrity: sha512-4WTmnnhCfDvvuLMaF3KV4Qfki93KebocUF45msxhYyjMttZDQYzHkO639ohhk8+oco2cluAFL3t5+Jn4mleylQ==} + /@types/lodash.merge/4.6.6: + resolution: {integrity: sha512-IB90krzMf7YpfgP3u/EvZEdXVvm4e3gJbUvh5ieuI+o+XqiNEt6fCzqNRaiLlPVScLI59RxIGZMQ3+Ko/DJ8vQ==} dependencies: '@types/lodash': 4.14.181 dev: true @@ -4285,7 +4287,6 @@ packages: /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true /lodash.truncate/4.4.2: resolution: {integrity: sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=} @@ -6344,7 +6345,7 @@ packages: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.0.0 - webpack: 5.72.0_esbuild@0.14.34 + webpack: 5.72.0_@swc+core@1.2.164 /webpack-dev-server/4.8.1_webpack@5.72.0: resolution: {integrity: sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==} @@ -6384,7 +6385,7 @@ packages: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack: 5.72.0_esbuild@0.14.34 + webpack: 5.72.0_@swc+core@1.2.164 webpack-dev-middleware: 5.3.1_webpack@5.72.0 ws: 8.5.0 transitivePeerDependencies: diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.test.ts index d3307af1f..50862c5d2 100644 --- a/tests/integration/basic-project.test.ts +++ b/tests/integration/basic-project.test.ts @@ -41,6 +41,40 @@ describe(`start ${example}`, () => { expect(await page.$$text('h2')).toStrictEqual(['Home Page']); }, 120000); + test('should update pageConfig during client routing', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + + expect( + await page.title() + ).toBe('Home'); + + expect( + await page.$$attr('meta[name="theme-color"]', 'content') + ).toStrictEqual(['#000']); + + await page.click('a[href="/about"]'); + await page.waitForNetworkIdle(); + + expect( + await page.title() + ).toBe('About'); + + expect( + await page.$$attr('meta[name="theme-color"]', 'content') + ).toStrictEqual(['#eee']); + + expect( + await page.$$eval('link[href*="bootstrap"]', (els) => els.length) + ).toBe(1); + + expect( + await page.$$eval('script[src*="lodash"]', (els) => els.length) + ).toBe(1); + }, 120000); + afterAll(async () => { await browser.close(); }); diff --git a/tests/utils/browser.ts b/tests/utils/browser.ts index d7bbb40b1..f1f3a67f4 100644 --- a/tests/utils/browser.ts +++ b/tests/utils/browser.ts @@ -110,25 +110,16 @@ export default class Browser { page.$$eval(selector, (els, trim) => els.map((el) => { return trim ? (el.textContent || '').replace(/^\s+|\s+$/g, '') : el.textContent }), trim); - page.$attr = (selector, attr) => { - return page.$eval( - selector, - (el: Element, ...args: unknown[]) => { - const [] = args; - return el.getAttribute(attr) - }, - attr - ) - }; - page.$$attr = (selector, attr) =>{ - return page.$$eval( + + page.$attr = (selector, attr) => + page.$eval(selector, (el, attr) => el.getAttribute(attr as string), attr); + + page.$$attr = (selector, attr) => + page.$$eval( selector, - (els, ...args: unknown[]) => { - return els.map(el => el.getAttribute(attr)) - }, - attr + (els, attr) => els.map(el => el.getAttribute(attr as string)), + attr, ); - } return page; } } From 1c5bd5f479df4f9807bfaf24ffc85613729e4c01 Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Mon, 11 Apr 2022 11:55:29 +0800 Subject: [PATCH 36/36] fix: comment --- examples/basic-project/ice.config.ts | 8 ++++---- packages/route-manifest/src/routes.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/basic-project/ice.config.ts b/examples/basic-project/ice.config.ts index ea9a5afcd..890e35a45 100644 --- a/examples/basic-project/ice.config.ts +++ b/examples/basic-project/ice.config.ts @@ -1,12 +1,12 @@ import { defineUserConfig } from '@ice/app'; -// import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; export default defineUserConfig({ publicPath: '/', webpack: (webpackConfig) => { - // if (process.env.NODE_ENV !== 'test') { - // webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); - // } + if (process.env.NODE_ENV !== 'test') { + webpackConfig.plugins?.push(new BundleAnalyzerPlugin()); + } return webpackConfig; }, plugins: ['@ice/plugin-auth'], diff --git a/packages/route-manifest/src/routes.ts b/packages/route-manifest/src/routes.ts index ec7c88422..22279f414 100644 --- a/packages/route-manifest/src/routes.ts +++ b/packages/route-manifest/src/routes.ts @@ -1,6 +1,6 @@ // based on https://github.com/remix-run/remix/blob/main/packages/remix-dev/config/routes.ts -import { win32, join } from 'path'; +import { win32 } from 'path'; export interface ConfigRoute { /**