From c7cfed917b283888db725c7e9bee8830c8d9a8f0 Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Tue, 21 Feb 2023 16:41:15 +0800 Subject: [PATCH 01/21] fix: compile non-js file when use plugin fusion (#5937) * fix: compile non-js file when use plugin fusion * chore: add changelog --- .changeset/gentle-teachers-cheer.md | 5 +++++ packages/plugin-fusion/src/index.ts | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/gentle-teachers-cheer.md diff --git a/.changeset/gentle-teachers-cheer.md b/.changeset/gentle-teachers-cheer.md new file mode 100644 index 0000000000..b71b12b37e --- /dev/null +++ b/.changeset/gentle-teachers-cheer.md @@ -0,0 +1,5 @@ +--- +'@ice/plugin-fusion': patch +--- + +fix: compile non-js file when use plugin fusion diff --git a/packages/plugin-fusion/src/index.ts b/packages/plugin-fusion/src/index.ts index c9700eb3d8..08a8432a3f 100644 --- a/packages/plugin-fusion/src/index.ts +++ b/packages/plugin-fusion/src/index.ts @@ -32,12 +32,16 @@ function importIcon(iconPath: string, cssPrefix: string) { return { name: 'transform-import-icon', enforce: 'pre', + transformInclude(id: string) { + // Only transform source code. + return id.match(/\.(js|jsx|ts|tsx)$/) && !id.match(/node_modules/); + }, async transform(code: string, id: string, options: { isServer: boolean }) { const { isServer } = options; // Only import icon scss in client if (!isServer) { // Icon just import once. - if (!entryFile && !id.match(/node_modules/) && id.match(/[js|jsx|ts|tsx]$/)) { + if (!entryFile) { entryFile = id; } if (id === entryFile) { From 73ae8bf4f798ddf4c0d1430131b3c24834f0876c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=93=E9=99=8C=E5=90=8C=E5=AD=A6?= Date: Wed, 22 Feb 2023 10:12:24 +0800 Subject: [PATCH 02/21] Fix/custom appworker (#5946) * fix: fix app-worker can't work when set custom name * chore: add changelog * chore: add changeset --- .changeset/gentle-trains-cross.md | 5 +++++ packages/plugin-pha/src/generateManifest.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/gentle-trains-cross.md diff --git a/.changeset/gentle-trains-cross.md b/.changeset/gentle-trains-cross.md new file mode 100644 index 0000000000..f9da7f5554 --- /dev/null +++ b/.changeset/gentle-trains-cross.md @@ -0,0 +1,5 @@ +--- +'@ice/plugin-pha': major +--- + +[fix] app-worker is not compiled when set a custom name diff --git a/packages/plugin-pha/src/generateManifest.ts b/packages/plugin-pha/src/generateManifest.ts index d12cafd330..505d44e082 100644 --- a/packages/plugin-pha/src/generateManifest.ts +++ b/packages/plugin-pha/src/generateManifest.ts @@ -39,7 +39,7 @@ export async function getAppWorkerPath({ getAppConfig, rootDir, }) { - const appConfig = getAppConfig(['phaManifest']); + const appConfig = await getAppConfig(['phaManifest']); let manifest = appConfig.phaManifest; return getAppWorkerUrl(manifest, path.join(rootDir, 'src')); } From 37c22e3195d383fc4429a5d8ea9c3febaebdb00f Mon Sep 17 00:00:00 2001 From: ZeroLing Date: Wed, 22 Feb 2023 11:00:31 +0800 Subject: [PATCH 03/21] Fix/define page config (#5936) * chore: update templates for unused imports * chore: add changeset --- .changeset/wicked-numbers-approve.md | 5 +++++ packages/ice/templates/core/index.ts.ejs | 12 ++++++++---- packages/ice/templates/core/types.ts.ejs | 9 ++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 .changeset/wicked-numbers-approve.md diff --git a/.changeset/wicked-numbers-approve.md b/.changeset/wicked-numbers-approve.md new file mode 100644 index 0000000000..95c76d42dc --- /dev/null +++ b/.changeset/wicked-numbers-approve.md @@ -0,0 +1,5 @@ +--- +'@ice/app': patch +--- + +chore: update templates for unused imports diff --git a/packages/ice/templates/core/index.ts.ejs b/packages/ice/templates/core/index.ts.ejs index 73bb4081c6..dd9ac73f16 100644 --- a/packages/ice/templates/core/index.ts.ejs +++ b/packages/ice/templates/core/index.ts.ejs @@ -1,14 +1,18 @@ <% if (globalStyle) {-%> import '<%= globalStyle %>' <% } -%> -import type { PageConfig } from './types'; +import type { PageConfig, PageConfigDefinition } from './types'; <%- framework.imports %> <%- framework.variablesStr %> <%- framework.targetImport %> -function definePageConfig(pageConfig: () => PageConfig): () => PageConfig { - return pageConfig; +function definePageConfig(pageConfig: PageConfig | PageConfigDefinition): PageConfigDefinition { + if (typeof pageConfig !== 'function') { + return () => pageConfig; + } else { + return pageConfig; + } } export { @@ -16,7 +20,7 @@ export { <% if (framework.exports) { -%><%- framework.exports %><% } -%> <% if (framework.targetExports) { -%><%- framework.targetExports %><% } -%> - + }; export * from './types'; diff --git a/packages/ice/templates/core/types.ts.ejs b/packages/ice/templates/core/types.ts.ejs index 2a1cc7744a..f35bde06e2 100644 --- a/packages/ice/templates/core/types.ts.ejs +++ b/packages/ice/templates/core/types.ts.ejs @@ -1,4 +1,4 @@ -import type { AppConfig, GetAppData, RouteConfig as DefaultRouteConfig } from '@ice/runtime'; +import type { AppConfig, RouteConfig as DefaultRouteConfig } from '@ice/runtime'; <%- routeConfigTypes.imports -%> <% if (routeConfigTypes.imports) {-%> @@ -7,9 +7,12 @@ type ExtendsRouteConfig = <% if (routeConfigTypes.imports) { %><%- routeConfigTy type ExtendsRouteConfig = {}; <% } -%> type PageConfig = DefaultRouteConfig; +type PageConfigDefinitionContext = { + data?: DataType; +}; +type PageConfigDefinition = (context: PageConfigDefinitionContext) => PageConfig; export type { AppConfig, - GetAppData, PageConfig, -}; \ No newline at end of file +}; From 1b6c57832aa751996f7158f8a09fa6e8bf1a5ea2 Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Wed, 22 Feb 2023 12:17:31 +0800 Subject: [PATCH 04/21] feat: on-demand compilation for server (#5824) * feat: node runner * feat: node transform * fix: unexpected modification * fix: node runner * test: test case * test: test case * test: test case * fix: add dependencies * fix: optimize code * feat: server runner * feat: optimize code * fix: test case * fix: test case * feat: support on demand pre bundle * chore: lint warning * fix: optimize code * fix: compile options * fix: optimize code * fix: add file * fix: optimize code * fix: test case * fix: optimize code * fix: test * fix: compile target * fix: optimize code * fix: lint * fix: optimize code --- examples/basic-project/ice.config.mts | 4 + packages/bundles/package.json | 3 +- packages/bundles/src/index.ts | 2 + packages/ice/package.json | 2 + packages/ice/src/commands/start.ts | 23 +- packages/ice/src/config.ts | 1 + packages/ice/src/createService.ts | 19 ++ packages/ice/src/esbuild/assets.ts | 12 +- packages/ice/src/esbuild/transformPipe.ts | 2 +- .../ice/src/middlewares/ssr/renderOnDemand.ts | 69 ++++ packages/ice/src/service/Runner.ts | 306 ++++++++++++++++++ packages/ice/src/service/ServerRunner.ts | 288 +++++++++++++++++ packages/ice/src/service/analyze.ts | 3 +- packages/ice/src/service/onDemandPreBundle.ts | 130 ++++++++ packages/ice/src/service/preBundleDeps.ts | 84 +++-- packages/ice/src/service/serverCompiler.ts | 80 +++-- packages/ice/src/service/webpackCompiler.ts | 44 ++- packages/ice/src/types/plugin.ts | 36 +-- packages/ice/src/types/userConfig.ts | 1 + packages/ice/src/utils/ServerCompileTask.ts | 8 +- .../ice/src/webpack/ServerRunnerPlugin.ts | 41 +++ .../ice/templates/core/entry.server.ts.ejs | 4 +- .../ice/tests/fixtures/nodeRunner/basic/a.js | 1 + .../tests/fixtures/nodeRunner/basic/entry.js | 3 + .../tests/fixtures/nodeRunner/circular/a.js | 1 + .../tests/fixtures/nodeRunner/circular/b.js | 2 + .../fixtures/nodeRunner/circular/entry.js | 11 + .../ice/tests/fixtures/nodeRunner/cjs/a.js | 4 + .../tests/fixtures/nodeRunner/cjs/entry.js | 7 + .../fixtures/nodeRunner/cjs/package.json | 1 + .../tests/fixtures/nodeRunner/export-all/a.js | 2 + .../fixtures/nodeRunner/export-all/entry.js | 3 + .../fixtures/nodeRunner/externalize/entry.js | 4 + packages/ice/tests/nodeRunner.test.ts | 84 +++++ packages/runtime/src/runServerApp.tsx | 1 - packages/style-import/package.json | 2 +- packages/webpack-config/src/types.ts | 1 + .../src/unPlugins/compilation.ts | 12 +- pnpm-lock.yaml | 92 ++++-- tests/integration/basic-project.test.ts | 1 + 40 files changed, 1246 insertions(+), 148 deletions(-) create mode 100644 packages/ice/src/middlewares/ssr/renderOnDemand.ts create mode 100644 packages/ice/src/service/Runner.ts create mode 100644 packages/ice/src/service/ServerRunner.ts create mode 100644 packages/ice/src/service/onDemandPreBundle.ts create mode 100644 packages/ice/src/webpack/ServerRunnerPlugin.ts create mode 100644 packages/ice/tests/fixtures/nodeRunner/basic/a.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/basic/entry.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/circular/a.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/circular/b.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/circular/entry.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/cjs/a.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/cjs/entry.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/cjs/package.json create mode 100644 packages/ice/tests/fixtures/nodeRunner/export-all/a.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/export-all/entry.js create mode 100644 packages/ice/tests/fixtures/nodeRunner/externalize/entry.js create mode 100644 packages/ice/tests/nodeRunner.test.ts diff --git a/examples/basic-project/ice.config.mts b/examples/basic-project/ice.config.mts index 787858d1a4..8baac7c3c8 100644 --- a/examples/basic-project/ice.config.mts +++ b/examples/basic-project/ice.config.mts @@ -9,6 +9,10 @@ export default defineConfig(() => ({ syntaxFeatures: { exportDefaultFrom: true, }, + server: { + onDemand: true, + format: 'esm', + }, alias: { '@comp': './src/components', }, diff --git a/packages/bundles/package.json b/packages/bundles/package.json index 54030b580c..1972c73f64 100644 --- a/packages/bundles/package.json +++ b/packages/bundles/package.json @@ -18,6 +18,7 @@ "@swc/core": "1.3.19", "@ice/swc-plugin-remove-export": "0.1.2", "@ice/swc-plugin-keep-export": "0.1.4", + "@ice/swc-plugin-node-transform": "0.1.0-5", "ansi-html-community": "^0.0.8", "html-entities": "^2.3.2", "core-js": "3.26.0", @@ -51,7 +52,7 @@ "fs-extra": "^10.0.0", "less-loader": "10.2.0", "lodash": "4.17.21", - "magic-string": "0.26.3", + "magic-string": "0.27.0", "mini-css-extract-plugin": "2.6.1", "ora": "5.4.1", "postcss-loader": "6.2.1", diff --git a/packages/bundles/src/index.ts b/packages/bundles/src/index.ts index 1cb40ee716..410ad920a1 100644 --- a/packages/bundles/src/index.ts +++ b/packages/bundles/src/index.ts @@ -9,6 +9,7 @@ import esbuild from 'esbuild'; const require = createRequire(import.meta.url); const swcPluginRemoveExport = require.resolve('@ice/swc-plugin-remove-export'); const swcPluginKeepExport = require.resolve('@ice/swc-plugin-keep-export'); +const swcPluginNodeTransform = require.resolve('@ice/swc-plugin-node-transform'); const coreJsPath = dirname(require.resolve('core-js/package.json')); export { postcss, @@ -18,6 +19,7 @@ export { swc, swcPluginRemoveExport, swcPluginKeepExport, + swcPluginNodeTransform, coreJsPath, diff --git a/packages/ice/package.json b/packages/ice/package.json index 846841950e..0c196c7d60 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -54,10 +54,12 @@ "dotenv": "^16.0.0", "dotenv-expand": "^8.0.3", "ejs": "^3.1.6", + "estree-walker": "^3.0.2", "fast-glob": "^3.2.11", "find-up": "^5.0.0", "fs-extra": "^10.0.0", "micromatch": "^4.0.5", + "mlly": "^1.1.0", "mrmime": "^1.0.0", "open": "^8.4.0", "path-to-regexp": "^6.2.0", diff --git a/packages/ice/src/commands/start.ts b/packages/ice/src/commands/start.ts index d1d2231977..448c0eba28 100644 --- a/packages/ice/src/commands/start.ts +++ b/packages/ice/src/commands/start.ts @@ -16,10 +16,12 @@ import webpackCompiler from '../service/webpackCompiler.js'; import formatWebpackMessages from '../utils/formatWebpackMessages.js'; import prepareURLs from '../utils/prepareURLs.js'; import createRenderMiddleware from '../middlewares/ssr/renderMiddleware.js'; +import createOnDemandMiddleware from '../middlewares/ssr/renderOnDemand.js'; import createMockMiddleware from '../middlewares/mock/createMiddleware.js'; import getRouterBasename from '../utils/getRouterBasename.js'; import { getExpandedEnvs } from '../utils/runtimeEnv.js'; import { logger } from '../utils/logger.js'; +import type ServerRunner from '../service/ServerRunner.js'; import type RouteManifest from '../utils/routeManifest.js'; const { merge } = lodash; @@ -37,6 +39,7 @@ const start = async ( getRoutesConfig: GetRoutesConfig; getDataloaderConfig: GetDataloaderConfig; userConfigHash: string; + serverRunner?: ServerRunner; }, ) => { const { @@ -49,6 +52,7 @@ const start = async ( getRoutesConfig, getDataloaderConfig, userConfigHash, + serverRunner, routeManifest, } = options; const { commandArgs, rootDir } = context; @@ -69,6 +73,7 @@ const start = async ( const hooksAPI = { serverCompiler, + serverRunner, getAppConfig, getRoutesConfig, getDataloaderConfig, @@ -107,6 +112,7 @@ interface StartDevServerOptions { getAppConfig: GetAppConfig; getRoutesConfig: GetRoutesConfig; getDataloaderConfig: GetDataloaderConfig; + serverRunner?: ServerRunner; }; appConfig: AppConfig; devPath: string; @@ -124,7 +130,7 @@ async function startDevServer({ }: StartDevServerOptions): Promise<{ compiler: Compiler; devServer: WebpackDevServer }> { const { commandArgs, userConfig, rootDir, applyHook, extendsPluginAPI: { serverCompileTask } } = context; const { ssg, ssr } = userConfig; - const { getAppConfig } = hooksAPI; + const { getAppConfig, serverRunner } = hooksAPI; const webTaskConfig = taskConfigs.find(({ name }) => name === WEB); const customMiddlewares = webpackConfigs[0].devServer?.setupMiddlewares; // Get the value of the host and port from the command line, environment variables, and webpack config. @@ -152,16 +158,23 @@ async function startDevServer({ } // both ssr and ssg, should render the whole page in dev mode. const documentOnly = !ssr && !ssg; - - const serverRenderMiddleware = createRenderMiddleware({ - serverCompileTask, + const middlewareOptions = { documentOnly, renderMode, getAppConfig, taskConfig: webTaskConfig, userConfig, routeManifest, - }); + }; + const serverRenderMiddleware = serverRunner + ? createOnDemandMiddleware({ + ...middlewareOptions, + serverRunner, + }) + : createRenderMiddleware({ + ...middlewareOptions, + serverCompileTask, + }); // @ts-ignore const insertIndex = middlewares.findIndex(({ name }) => name === 'serve-index'); middlewares.splice( diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index ef0d098b07..7a45b4e3c2 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -135,6 +135,7 @@ const userConfig = [ name: 'server', validation: 'object', defaultValue: { + onDemand: false, format: 'esm', bundle: false, }, diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 97175ecc15..cb89e06eb7 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -29,6 +29,7 @@ import renderExportsTemplate from './utils/renderExportsTemplate.js'; import { getFileExports } from './service/analyze.js'; import { getFileHash } from './utils/hash.js'; import { logger } from './utils/logger.js'; +import ServerRunner from './service/ServerRunner.js'; import RouteManifest from './utils/routeManifest.js'; const require = createRequire(import.meta.url); @@ -251,6 +252,23 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const renderStart = new Date().getTime(); generator.render(); logger.debug('template render cost:', new Date().getTime() - renderStart); + // Create server runner + let serverRunner: ServerRunner; + if (server.onDemand) { + serverRunner = new ServerRunner({ + rootDir, + task: platformTaskConfig, + server, + }); + addWatchEvent([ + /src\/?[\w*-:.$]+$/, + async (eventName: string, filePath: string) => { + if (eventName === 'change' || eventName === 'add') { + serverRunner.fileChanged(filePath); + } + }], + ); + } // create serverCompiler with task config const serverCompiler = createServerCompiler({ rootDir, @@ -292,6 +310,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt getRoutesConfig, getDataloaderConfig, getAppConfig, + serverRunner, appConfig, devPath: (routePaths[0] || '').replace(/^[/\\]/, ''), spinner: buildSpinner, diff --git a/packages/ice/src/esbuild/assets.ts b/packages/ice/src/esbuild/assets.ts index 8a62201ace..1d35514ce6 100644 --- a/packages/ice/src/esbuild/assets.ts +++ b/packages/ice/src/esbuild/assets.ts @@ -42,7 +42,7 @@ interface CompilationInfo { assetsManifest?: AssetsManifest; } -const createAssetsPlugin = (compilationInfo: CompilationInfo, rootDir: string) => ({ +const createAssetsPlugin = (compilationInfo: CompilationInfo | (() => CompilationInfo), rootDir: string) => ({ name: 'esbuild-assets', setup(build: PluginBuild) { build.onResolve({ filter: /assets-manifest.json$/ }, (args) => { @@ -54,12 +54,14 @@ const createAssetsPlugin = (compilationInfo: CompilationInfo, rootDir: string) = } }); build.onLoad({ filter: /.*/, namespace: 'asset-manifest' }, () => { + const manifest = typeof compilationInfo === 'function' ? compilationInfo() : compilationInfo; return { - contents: JSON.stringify(compilationInfo?.assetsManifest || ''), + contents: JSON.stringify(manifest?.assetsManifest || ''), loader: 'json', }; }); build.onLoad({ filter: ASSETS_RE }, async (args) => { + const manifest = typeof compilationInfo === 'function' ? compilationInfo() : compilationInfo; if (args.suffix == '?raw') { return { loader: 'text', @@ -70,19 +72,19 @@ const createAssetsPlugin = (compilationInfo: CompilationInfo, rootDir: string) = let url = ''; // Suffix `?url` will generate content hash in assets manifest, // keep the same file rule with client side. - const contentHash = compilationInfo?.assetsManifest!.assets[`${relativePath}${args.suffix}`]; + const contentHash = manifest?.assetsManifest!.assets[`${relativePath}${args.suffix}`]; if (contentHash) { const basename = path.basename(args.path); const extname = path.extname(basename); const ext = extname.substring(1); const name = basename.slice(0, -extname.length); // assets/[name].[hash:8][ext] - url = `${compilationInfo?.assetsManifest.publicPath}assets/${name}.${contentHash}.${ext}`; + url = `${manifest?.assetsManifest.publicPath}assets/${name}.${contentHash}.${ext}`; } else { url = `data:${mrmime.lookup(args.path)};base64,${content.toString('base64')}`; } return { - contents: `export default ${JSON.stringify(url)}`, + contents: `module.exports = ${JSON.stringify(url)}`, loader: 'js', }; }); diff --git a/packages/ice/src/esbuild/transformPipe.ts b/packages/ice/src/esbuild/transformPipe.ts index 9529a5b128..f3ae04b542 100644 --- a/packages/ice/src/esbuild/transformPipe.ts +++ b/packages/ice/src/esbuild/transformPipe.ts @@ -133,7 +133,7 @@ const transformPipe = (options: PluginOptions = {}): Plugin => { sourceMap = result.map; } } - if (sourceMap) { + if (sourceMap && typeof sourceMap !== 'string') { if (!sourceMap.sourcesContent || sourceMap.sourcesContent.length === 0) { sourceMap.sourcesContent = [sourceCode]; } diff --git a/packages/ice/src/middlewares/ssr/renderOnDemand.ts b/packages/ice/src/middlewares/ssr/renderOnDemand.ts new file mode 100644 index 0000000000..dcf4444840 --- /dev/null +++ b/packages/ice/src/middlewares/ssr/renderOnDemand.ts @@ -0,0 +1,69 @@ +import type { ExpressRequestHandler, Middleware } from 'webpack-dev-server'; +import type { ServerContext, RenderMode } from '@ice/runtime'; +// @ts-expect-error FIXME: esm type error +import matchRoutes from '@ice/runtime/matchRoutes'; +import type { TaskConfig } from 'build-scripts'; +import type { Config } from '@ice/webpack-config/esm/types'; +import getRouterBasename from '../../utils/getRouterBasename.js'; +import warnOnHashRouterEnabled from '../../utils/warnOnHashRouterEnabled.js'; +import type { UserConfig } from '../../types/userConfig.js'; +import { logger } from '../../utils/logger.js'; +import type ServerRunner from '../../service/ServerRunner.js'; +import type RouteManifest from '../../utils/routeManifest.js'; + +interface Options { + routeManifest: RouteManifest; + getAppConfig: () => Promise; + userConfig: UserConfig; + documentOnly?: boolean; + renderMode?: RenderMode; + taskConfig?: TaskConfig; + serverRunner?: ServerRunner; +} + +export default function createOnDemandRenderMiddleware(options: Options): Middleware { + const { + documentOnly, + renderMode, + getAppConfig, + taskConfig, + userConfig, + serverRunner, + routeManifest, + } = options; + const middleware: ExpressRequestHandler = async function (req, res, next) { + const routes = routeManifest.getNestedRoute(); + const appConfig = (await getAppConfig()).default; + if (appConfig?.router?.type === 'hash') { + warnOnHashRouterEnabled(userConfig); + } + const basename = getRouterBasename(taskConfig, appConfig); + const matches = matchRoutes(routes, req.path, basename); + // When documentOnly is true, it means that the app is CSR and it should return the html. + if (matches.length || documentOnly) { + let serverModule; + try { + serverModule = await serverRunner.run('.ice/entry.server.ts'); + } catch (err) { + logger.error(`server entry error: ${err}`); + return; + } + + const requestContext: ServerContext = { + req, + res, + }; + serverModule.renderToResponse(requestContext, { + renderMode, + documentOnly, + }); + } else { + next(); + } + }; + + return { + name: 'on-demand-render', + middleware, + }; +} diff --git a/packages/ice/src/service/Runner.ts b/packages/ice/src/service/Runner.ts new file mode 100644 index 0000000000..d78346f322 --- /dev/null +++ b/packages/ice/src/service/Runner.ts @@ -0,0 +1,306 @@ +// Inspired by https://github.com/vitest-dev/vitest/tree/main/packages/vite-node +import { createRequire } from 'module'; +import path from 'path'; +import { fileURLToPath, pathToFileURL } from 'url'; +import vm from 'vm'; +import { isNodeBuiltin } from 'mlly'; +import consola from 'consola'; + +export interface ModuleResult { + code?: string; + externalize?: string; + map?: any; +} + +export type ResolveId = { + id: string; + namespace?: string; +} | string | null; + +export interface RunnerOptions { + rootDir: string; + moduleCache?: ModuleCacheMap; + meta?: Record; + load: (args: { + path: string; + namespace?: string; + }) => Promise | ModuleResult; + resolveId?: (id: string, importer?: string) => Promise | ResolveId; + interopDefault?: boolean; +} + +interface ModuleCache { + promise?: Promise; + exports?: any; + evaluated?: boolean; + resolving?: boolean; + code?: string; + map?: any; + /** + * Module ids that imports this module + */ + importers?: Set; +} + +export class ModuleCacheMap extends Map { + set(id: string, mod: ModuleCache) { + return super.set(id, mod); + } + + get(id: string): ModuleCache { + if (!super.has(id)) { + super.set(id, {}); + } + return super.get(id)!; + } + + delete(id: string): boolean { + return super.delete(id); + } +} + +class Runner { + rootDir: string; + moduleCache: ModuleCacheMap; + importMeta: Record; + + constructor(public options: RunnerOptions) { + this.rootDir = options.rootDir; + this.importMeta = options.meta || {}; + this.moduleCache = options.moduleCache || new ModuleCacheMap(); + } + + async run(id: string) { + const filePath = path.isAbsolute(id) ? id : path.join(this.rootDir, id); + return await this.cachedRequest(filePath, []); + } + + async cachedRequest(id: string, callstack: string[], namespace?: string) { + const mod = this.moduleCache.get(id); + if (callstack.includes(id) && mod.exports) return mod.exports; + if (mod.promise) return mod.promise; + const promise = this.requestModule(id, callstack, namespace); + Object.assign(mod, { promise, evaluated: false }); + + try { + return await promise; + } finally { + mod.evaluated = true; + } + } + + async resolveUrl(id: string, importee?: string) { + const resolveKey = `resolve:${id}`; + // put info about new import as soon as possible, so we can start tracking it + this.moduleCache.set(resolveKey, { resolving: true }); + let requestId = ''; + try { + if (isNodeBuiltin(id)) { + requestId = id; + } else if (this.options.resolveId) { + const res = await this.options.resolveId(id, importee); + if (typeof res === 'string') { + requestId = res; + } else { + return res; + } + } else { + requestId = path.resolve(path.dirname(importee!), id); + } + return { id: requestId }; + } finally { + this.moduleCache.delete(resolveKey); + } + } + + async dependencyRequest(id: string, callstack: string[], namespace = '') { + const getStack = () => { + return `stack:\n${[...callstack, id].reverse().map(p => `- ${p}`).join('\n')}`; + }; + + try { + if (callstack.includes(id)) { + const depExports = this.moduleCache.get(id)?.exports; + if (depExports) return depExports; + throw new Error(`[runner] Failed to resolve circular dependency, ${getStack()}`); + } + return await this.cachedRequest(id, callstack, namespace); + } catch (e) { + consola.error(e); + } + } + + async requestModule(id: string, _callstack: string[] = [], namespace = '') { + const mod = this.moduleCache.get(id); + const callstack = [..._callstack, id]; + let { code: transformed, externalize } = await this.options.load({ + path: id, + namespace, + }); + const request = async (dep: string) => { + const { id: requestId, namespace } = await this.resolveUrl(dep, id); + return this.dependencyRequest(requestId, callstack, namespace); + }; + + if (externalize) { + const exports = await this.interopedImport(externalize); + mod.exports = exports; + return exports; + } + + const { href } = pathToFileURL(id); + const meta = { url: href, ...this.importMeta }; + const exports = Object.create(null); + + // this prosxy is triggered only on exports.{name} and module.exports access + const cjsExports = new Proxy(exports, { + set: (_, p, value) => { + // treat "module.exports =" the same as "exports.default =" to not have nested "default.default", + // so "exports.default" becomes the actual module + if (p === 'default' && this.shouldInterop(id, { default: value })) { + exportAll(cjsExports, value); + exports.default = value; + return true; + } + + if (!Reflect.has(exports, 'default')) exports.default = {}; + + // returns undefined, when accessing named exports, if default is not an object + // but is still present inside hasOwnKeys, this is Node behaviour for CJS + if (isPrimitive(exports.default)) { + defineExport(exports, p, () => undefined); + return true; + } + + exports.default[p] = value; + if (p !== 'default') defineExport(exports, p, () => value); + + return true; + }, + }); + + Object.assign(mod, { code: transformed, exports }); + const __filename = fileURLToPath(href); + const moduleProxy = { + set exports(value) { + exportAll(cjsExports, value); + exports.default = value; + }, + get exports() { + return cjsExports; + }, + }; + + const context = { + // esm transformed by ice, https://github.com/ice-lab/swc-plugins/pull/9 + __ice_import__: request, + __ice_dynamic_import__: request, + __ice_exports__: exports, + __ice_exports_all__: (obj: any) => exportAll(exports, obj), + __ice_import_meta__: meta, + + // cjs compact + require: createRequire(href), + exports: cjsExports, + module: moduleProxy, + __filename, + __dirname: path.dirname(__filename), + }; + + if (transformed[0] === '#') transformed = transformed.replace(/^#!.*/, s => ' '.repeat(s.length)); + // add 'use strict' since ESM enables it by default + const codeDefinition = `'use strict';async (${Object.keys(context).join(',')})=>{{\n`; + const code = `${codeDefinition}${transformed}\n}}`; + const fn = vm.runInThisContext(code, { + filename: __filename, + lineOffset: -1, + columnOffset: 0, + }); + + await fn(...Object.values(context)); + + return exports; + } + + shouldInterop(path: string, mod: any) { + if (this.options.interopDefault === false) { + return false; + } + return !path.endsWith('.mjs') && 'default' in mod; + } + + async interopedImport(id: string) { + const importedModule = await import(id); + if (!this.shouldInterop(id, importedModule)) { + return importedModule; + } + const { mod, defaultExport } = interopModule(importedModule); + return new Proxy(mod, { + get(mod, prop) { + if (prop === 'default') return defaultExport; + return mod[prop] ?? defaultExport?.[prop]; + }, + has(mod, prop) { + if (prop === 'default') return defaultExport !== undefined; + return prop in mod || (defaultExport && prop in defaultExport); + }, + getOwnPropertyDescriptor(mod, prop) { + const descriptor = Reflect.getOwnPropertyDescriptor(mod, prop); + if (descriptor) return descriptor; + if (prop === 'default' && defaultExport !== undefined) { + return { + value: defaultExport, + enumerable: true, + configurable: true, + }; + } + }, + }); + } +} + +function isPrimitive(v: any) { + return v !== Object(v); +} + +function interopModule(mod: any) { + if (isPrimitive(mod)) { + return { + mod: { default: mod }, + defaultExport: mod, + }; + } + + let defaultExport = 'default' in mod ? mod.default : mod; + + if (!isPrimitive(defaultExport) && '__esModule' in defaultExport) { + mod = defaultExport; + if ('default' in defaultExport) defaultExport = defaultExport.default; + } + + return { mod, defaultExport }; +} + +function defineExport(exports: any, key: string | symbol, value: () => any) { + Object.defineProperty(exports, key, { + enumerable: true, + configurable: true, + get: value, + }); +} + +function exportAll(exports: any, sourceModule: any) { + if (exports === sourceModule) return; + + if (isPrimitive(sourceModule) || Array.isArray(sourceModule)) return; + + for (const key in sourceModule) { + if (key !== 'default') { + try { + defineExport(exports, key, () => sourceModule[key]); + } catch (_err) { } + } + } +} + +export default Runner; diff --git a/packages/ice/src/service/ServerRunner.ts b/packages/ice/src/service/ServerRunner.ts new file mode 100644 index 0000000000..7986010538 --- /dev/null +++ b/packages/ice/src/service/ServerRunner.ts @@ -0,0 +1,288 @@ +import * as path from 'path'; +import fse from 'fs-extra'; +import fg from 'fast-glob'; +import { getCompilerPlugins, getCSSModuleLocalIdent } from '@ice/webpack-config'; +import moduleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; +import MagicString from '@ice/bundles/compiled/magic-string/index.js'; +import type { TaskConfig } from 'build-scripts'; +import type { Config } from '@ice/webpack-config/esm/types'; +import type { PluginBuild, OnResolveOptions, Plugin, OnLoadResult, OnResolveResult } from 'esbuild'; +import emptyCSSPlugin from '../esbuild/emptyCSS.js'; +import ignorePlugin from '../esbuild/ignore.js'; +import cssModulesPlugin from '../esbuild/cssModules.js'; +import createAssetsPlugin from '../esbuild/assets.js'; +import externalPlugin from '../esbuild/external.js'; +import escapeLocalIdent from '../utils/escapeLocalIdent.js'; +import transformPipePlugin from '../esbuild/transformPipe.js'; +import type { CompilerOptions } from '../types/plugin.js'; +import type { UserConfig } from '../types/userConfig.js'; +import { logger } from '../utils/logger.js'; +import { resolveId as resolveWithAlias } from './analyze.js'; +import Runner from './Runner.js'; +import { RuntimeMeta } from './onDemandPreBundle.js'; +import { filterAlias, getRuntimeDefination } from './serverCompiler.js'; + +interface InitOptions { + rootDir: string; + server: UserConfig['server']; + task: TaskConfig; +} + +type ResolveCallback = Parameters[1]; +type LoadCallback = Parameters[1]; + +function getPluginLifecycle(plugin: Plugin, compiler: 'onLoad'): [OnResolveOptions, LoadCallback][]; +function getPluginLifecycle(plugin: Plugin, compiler: 'onResolve'): [OnResolveOptions, ResolveCallback][]; +function getPluginLifecycle(plugin: Plugin, hookKey: 'onResolve' | 'onLoad') { + // Load options is as same as resolve options. + let lifecycles = []; + const fakePluginBuild = new Proxy({}, { + get: function (_, props) { + if (props === hookKey) { + return (options: OnResolveOptions, callback: ResolveCallback | LoadCallback) => { + lifecycles.push([options, callback]); + }; + } else { + return () => {}; + } + }, + }); + plugin.setup(fakePluginBuild as PluginBuild); + return lifecycles; +} + +const { init, parse } = moduleLexer; +async function transformJsxRuntime(source: string) { + await init; + const [imports] = parse(source); + let s: MagicString | undefined; + const str = () => s || (s = new MagicString(source)); + + imports.forEach((imp) => { + if (!imp.n) { + return; + } + // JSX runtime is added after swc plugins + // use es-module-lexer to replace the import statement. + if (imp.n === '@ice/runtime/jsx-dev-runtime') { + str().overwrite( + imp.ss, + imp.se, + 'const __ice_import_runtime__ = await __ice_import__("@ice/runtime/jsx-dev-runtime");' + + 'const _jsxDEV = __ice_import_runtime__.jsxDEV;' + + 'const _Fragment = __ice_import_runtime__.Fragment', + ); + } + }); + return s ? s.toString() : source; +} + +class ServerRunner extends Runner { + rootDir: string; + server: UserConfig['server']; + private compilationInfo: CompilerOptions['compilationInfo']; + + constructor({ + task, + server, + rootDir, + }: InitOptions) { + const transformPlugins = getCompilerPlugins(rootDir, { + ...task.config, + fastRefresh: false, + enableEnv: false, + polyfill: false, + swcOptions: { + nodeTransform: true, + compilationConfig: { + jsc: { + // https://node.green/#ES2020 + target: 'es2020', + externalHelpers: false, + }, + }, + }, + }, 'esbuild', { isServer: true }); + const { alias, ignores } = filterAlias(task.config.alias || {}); + const runtimeMeta = new RuntimeMeta({ + rootDir, + alias, + ignores, + external: server.externals || [], + define: getRuntimeDefination(task.config.define || {}), + }); + + const esbuildPlugins = [ + emptyCSSPlugin(), + externalPlugin({ + ignores, + externalDependencies: true, + format: 'esm', + externals: server.externals, + }), + server?.ignores && ignorePlugin(server.ignores), + cssModulesPlugin({ + extract: false, + generateLocalIdentName: function (name: string, filename: string) { + // Compatible with webpack css-loader. + return escapeLocalIdent(getCSSModuleLocalIdent(filename, name)); + }, + }), + createAssetsPlugin(() => { + return this.compilationInfo; + }, rootDir), + transformPipePlugin({ + plugins: transformPlugins, + }), + ].filter(Boolean); + let firstResolve = true; + const externals = []; + super({ + rootDir, + meta: { + renderer: 'client', + target: 'web', + }, + resolveId: async (id, importer) => { + // Call esbuild lifecycle `onResolve` of esbuild plugin. + let resolvedId = id; + let resolveNamespace = ''; + firstResolve = false; + + // Resolve aliased id. + if (!path.isAbsolute(resolvedId)) { + if (resolvedId.startsWith('.')) { + resolvedId = path.resolve(path.dirname(importer), resolvedId); + } else { + const id = resolveWithAlias(resolvedId, task.config.alias || {}); + if (id) { + resolvedId = id.startsWith('.') ? path.resolve(rootDir, id) : id; + } else { + resolveNamespace = 'empty-content'; + } + } + } + + for (const plugin of esbuildPlugins) { + let res: OnResolveResult; + const lifecycles = getPluginLifecycle(plugin, 'onResolve'); + for (const [options, callback] of lifecycles) { + if (options && callback) { + const { filter, namespace } = options; + if (namespace ? namespace == resolveNamespace : filter && filter.test(resolvedId)) { + try { + res = await callback({ + path: resolvedId, + importer, + namespace: resolveNamespace, + resolveDir: path.dirname(importer), + // Add kind of entry-point or import-statement to distinguish the type of resolve. + kind: firstResolve ? 'entry-point' : 'import-statement', + pluginData: {}, + }); + + if (res) { + const { path: resolvedPath, namespace: resolvedNamespace, external } = res; + resolvedId = resolvedPath || resolvedId; + resolveNamespace = resolvedNamespace || ''; + if (external) { + externals.push(resolvedId); + } + break; + } + } catch (err) { + logger.error(`Failed to resolve module ${id} from ${importer}, Esbuild name ${plugin.name}: ${err}`); + throw err; + } + } + } + } + if (res) break; + } + + // Glob specified file module aliased with absolute path. + if (!path.extname(resolvedId) && path.isAbsolute(resolvedId)) { + const basename = path.basename(resolvedId); + const patterns = [`${basename}.{js,ts,jsx,tsx,mjs}`, `${basename}/index.{js,ts,jsx,tsx,mjs}`]; + const absoluteId = fg.sync(patterns, { + cwd: path.dirname(resolvedId), + absolute: true, + })[0]; + + if (absoluteId) { + resolvedId = absoluteId; + } + } + return { + id: resolvedId, + namespace: resolveNamespace, + }; + }, + load: async (args) => { + const id = args.path; + + if (externals.includes(id)) { + return { externalize: id }; + } else { + let code = ''; + + // Call esbuild lifecycle `onLoad` of esbuild plugin. + for (const plugin of esbuildPlugins) { + let res: OnLoadResult; + const lifecycles = getPluginLifecycle(plugin, 'onLoad'); + for (const [options, callback] of lifecycles) { + const { filter, namespace } = options; + // Remove suffix of id. + const formatedId = id.replace(/\?\w+$/, ''); + if (namespace ? namespace == args.namespace : filter && filter.test(formatedId)) { + try { + res = await callback({ + namespace: '', + suffix: id.match(/(\?\w+)$/)?.[1] || '', + pluginData: {}, + ...args, + path: formatedId, + }); + + if (res) { + const { contents, loader } = res; + if (['json', 'text'].includes(loader)) { + code = `__ice_exports__.default = ${contents || JSON.stringify(fse.readFileSync(formatedId, 'utf-8'))}`; + } else { + code = typeof contents === 'string' ? contents : contents.toString(); + } + break; + } + } catch (err) { + logger.error(`Failed to load module ${id}, Esbuild name ${plugin.name}`); + throw err; + } + } + } + if (res) { + break; + } + } + if (!code && !path.isAbsolute(id)) { + // If id is runtime dependency, bundle it and return externalized id. + const bundlePath = await runtimeMeta.bundle(id); + return { externalize: bundlePath }; + } + return { + code: await transformJsxRuntime(code), + }; + } + }, + }); + } + + addCompileData(compilationInfo: CompilerOptions['compilationInfo']) { + this.compilationInfo = compilationInfo; + } + + fileChanged(filePath: string) { + this.moduleCache.delete(filePath); + } +} + +export default ServerRunner; diff --git a/packages/ice/src/service/analyze.ts b/packages/ice/src/service/analyze.ts index 465ccd9ac9..7081f65ec7 100644 --- a/packages/ice/src/service/analyze.ts +++ b/packages/ice/src/service/analyze.ts @@ -15,6 +15,7 @@ import { createLogger } from '../utils/logger.js'; const logger = createLogger('scan-modules'); type Alias = Record; +type AliasWithEmpty = Record; interface Options { parallel?: number; @@ -28,7 +29,7 @@ function addLastSlash(filePath: string) { return filePath.endsWith('/') ? filePath : `${filePath}/`; } -export function resolveId(id: string, alias: Alias) { +export function resolveId(id: string, alias: AliasWithEmpty) { let aliasedPath = id; for (const aliasKey of Object.keys(alias)) { const isStrict = aliasKey.endsWith('$'); diff --git a/packages/ice/src/service/onDemandPreBundle.ts b/packages/ice/src/service/onDemandPreBundle.ts new file mode 100644 index 0000000000..fd420ccf7b --- /dev/null +++ b/packages/ice/src/service/onDemandPreBundle.ts @@ -0,0 +1,130 @@ +import path from 'path'; +import { createRequire } from 'module'; +import fse from 'fs-extra'; +import findUp from 'find-up'; +import type { Plugin } from 'esbuild'; +import { logger } from '../utils/logger.js'; +import { CACHE_DIR } from '../constant.js'; +import { bundleDeps, resolvePackageESEntry, getDepsCacheDir } from './preBundleDeps.js'; +import type { PreBundleDepsMetaData } from './preBundleDeps.js'; +import { resolveId } from './analyze.js'; + +const require = createRequire(import.meta.url); + +interface PreBundleResult { + bundlePath?: string; +} + +interface PreBundleOptions { + rootDir: string; + pkgName: string; + alias: Record; + resolveId: string; + ignores: string[]; + plugins?: Plugin[]; + external?: string[]; + define?: Record; +} + +export class RuntimeMeta { + private rootDir: string; + private alias: Record; + private ignores: string[]; + private plugins: Plugin[]; + private metaData: PreBundleDepsMetaData; + private cachePath: string; + private external: string[]; + private define: Record; + + constructor(options: Omit) { + this.rootDir = options.rootDir; + this.alias = options.alias; + this.ignores = options.ignores; + this.plugins = options.plugins; + this.external = options.external; + this.define = options.define; + this.cachePath = path.join(getDepsCacheDir(path.join(this.rootDir, CACHE_DIR)), 'metadata.json'); + } + + async getDepsCache() { + if (fse.pathExistsSync(this.cachePath)) { + this.metaData = await fse.readJSON(this.cachePath) as PreBundleDepsMetaData; + } else { + this.metaData = { + deps: {}, + hash: '', + }; + } + return this.metaData; + } + + async setDepsCache(pkgName: string, resolveSource: string, bundlePath: string) { + this.metaData.deps[pkgName] = { + file: bundlePath, + src: resolveSource, + }; + await fse.writeJSON(this.cachePath, this.metaData); + } + + resolveDepPath(pkgName: string) { + // Check if the package is aliased. + let resolved = resolveId(pkgName, this.alias); + if (resolved && !path.isAbsolute(resolved)) { + const resolvePath = require.resolve(resolved, { paths: [this.rootDir] }); + // If the package is aliased, we need to bundle the aliased package. + try { + const pkgPath = findUp.sync('package.json', { cwd: resolvePath }); + resolved = resolvePackageESEntry(pkgName, pkgPath, this.alias); + } catch (err) { + logger.error(`cant resolve package of path: ${resolved}`, err); + } + } + return resolved; + } + + public async bundle(pkgName: string): Promise { + const resolveId = this.resolveDepPath(pkgName); + const metaData = this.metaData || await this.getDepsCache(); + if (metaData.deps[pkgName] && metaData.deps[pkgName].src === resolveId) { + return metaData.deps[pkgName].file; + } else if (resolveId) { + const { bundlePath } = await preBundleDeps({ + rootDir: this.rootDir, + alias: this.alias, + ignores: this.ignores, + plugins: this.plugins, + external: this.external, + define: this.define, + pkgName: pkgName, + resolveId, + }); + await this.setDepsCache(pkgName, resolveId, bundlePath); + return bundlePath; + } + // If the package is not found, return an empty string. + return ''; + } +} + +export default async function preBundleDeps(options: PreBundleOptions): Promise { + const { rootDir, pkgName, alias, ignores, plugins, resolveId, external, define } = options; + const depsCacheDir = getDepsCacheDir(path.join(rootDir, CACHE_DIR)); + try { + await bundleDeps({ + entryPoints: { [pkgName]: resolveId }, + outdir: depsCacheDir, + alias, + ignores, + plugins: plugins || [], + external, + define, + }); + } catch (err) { + logger.error('Failed to bundle dependencies.'); + logger.error(err); + return {}; + } + return { + bundlePath: path.join(depsCacheDir, `${pkgName}.mjs`), + }; +} \ No newline at end of file diff --git a/packages/ice/src/service/preBundleDeps.ts b/packages/ice/src/service/preBundleDeps.ts index b79b401cd9..077a7c6aec 100644 --- a/packages/ice/src/service/preBundleDeps.ts +++ b/packages/ice/src/service/preBundleDeps.ts @@ -2,7 +2,7 @@ import path from 'path'; import { createHash } from 'crypto'; import fse from 'fs-extra'; import { esbuild } from '@ice/bundles'; -import type { Plugin } from 'esbuild'; +import type { Plugin, BuildOptions } from 'esbuild'; import { resolve as resolveExports, legacy as resolveLegacy } from 'resolve.exports'; import moduleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; import type { Config } from '@ice/webpack-config/esm/types'; @@ -55,7 +55,7 @@ export default async function preBundleDeps( depsInfo: Record, options: PreBundleDepsOptions, ): Promise { - const { rootDir, cacheDir, taskConfig, plugins = [], alias, ignores, define, external = [] } = options; + const { cacheDir, taskConfig, plugins = [], alias, ignores, define, external = [] } = options; const metadata = createDepsMetadata(depsInfo, taskConfig); if (!Object.keys(depsInfo)) { @@ -95,38 +95,14 @@ export default async function preBundleDeps( } try { - await esbuild.build({ - absWorkingDir: rootDir, + await bundleDeps({ entryPoints: flatIdDeps, - bundle: true, - logLevel: 'error', outdir: depsCacheDir, - format: 'esm', - platform: 'node', - loader: { '.js': 'jsx' }, - ignoreAnnotations: true, + plugins, + ignores, alias, + external, define, - metafile: true, - outExtension: { - '.js': '.mjs', - }, - banner: { - js: "import { createRequire } from 'module';const require = createRequire(import.meta.url);", - }, - plugins: [ - emptyCSSPlugin(), - externalPlugin({ ignores, format: 'esm', externalDependencies: false }), - cssModulesPlugin({ - extract: false, - generateLocalIdentName: function (name: string, filename: string) { - // Compatible with webpack css-loader. - return escapeLocalIdent(getCSSModuleLocalIdent(filename, name)); - }, - }), - ...plugins, - ], - external: [...BUILDIN_CJS_DEPS, ...BUILDIN_ESM_DEPS, ...external], }); await fse.writeJSON(metadataJSONPath, metadata, { spaces: 2 }); @@ -141,7 +117,53 @@ export default async function preBundleDeps( } } -function resolvePackageESEntry(depId: string, pkgPath: string, alias: TaskConfig['config']['alias']) { +export async function bundleDeps(options: + { + entryPoints: BuildOptions['entryPoints']; + outdir: BuildOptions['outdir']; + alias: BuildOptions['alias']; + ignores: string[]; + plugins: Plugin[]; + external: string[]; + define: BuildOptions['define']; + }) { + const { entryPoints, outdir, alias, ignores, plugins, external, define } = options; + return await esbuild.build({ + absWorkingDir: process.cwd(), + entryPoints, + bundle: true, + logLevel: 'error', + outdir, + format: 'esm', + platform: 'node', + loader: { '.js': 'jsx' }, + ignoreAnnotations: true, + alias, + define, + metafile: true, + outExtension: { + '.js': '.mjs', + }, + banner: { + js: "import { createRequire } from 'module';const require = createRequire(import.meta.url);", + }, + plugins: [ + emptyCSSPlugin(), + externalPlugin({ ignores, format: 'esm', externalDependencies: false }), + cssModulesPlugin({ + extract: false, + generateLocalIdentName: function (name: string, filename: string) { + // Compatible with webpack css-loader. + return escapeLocalIdent(getCSSModuleLocalIdent(filename, name)); + }, + }), + ...plugins, + ], + external: [...BUILDIN_CJS_DEPS, ...BUILDIN_ESM_DEPS, ...external], + }); +} + +export function resolvePackageESEntry(depId: string, pkgPath: string, alias: TaskConfig['config']['alias']) { const pkgJSON = fse.readJSONSync(pkgPath); const pkgDir = path.dirname(pkgPath); const aliasKey = Object.keys(alias).find(key => depId === key || depId.startsWith(`${depId}/`)); diff --git a/packages/ice/src/service/serverCompiler.ts b/packages/ice/src/service/serverCompiler.ts index 53bfa9aa8d..8c22b6a6a1 100644 --- a/packages/ice/src/service/serverCompiler.ts +++ b/packages/ice/src/service/serverCompiler.ts @@ -39,16 +39,9 @@ interface Options { const { merge, difference } = lodash; -export function createServerCompiler(options: Options) { - const { task, rootDir, command, server, syntaxFeatures } = options; - const externals = task.config?.externals || {}; - const define = task.config?.define || {}; - const sourceMap = task.config?.sourceMap; - const dev = command === 'start'; - +export const filterAlias = (taskAlias: TaskConfig['config']['alias']) => { // Filter empty alias. - const ignores = []; - const taskAlias = task.config?.alias || {}; + const ignores: string[] = []; const alias: Record = {}; Object.keys(taskAlias).forEach((aliasKey) => { const value = taskAlias[aliasKey]; @@ -58,12 +51,52 @@ export function createServerCompiler(options: Options) { ignores.push(aliasKey); } }); + return { alias, ignores }; +}; - const defineVars = {}; +export const getRuntimeDefination = ( + defineVars: Record = {}, + runtimeVars: Record = {}, + transformEnv = true, +) => { + const stringifiedDefine = {}; + const runtimeDefineVars = { + ...runtimeVars, + }; // auto stringify define value - Object.keys(define).forEach((key) => { - defineVars[key] = JSON.stringify(define[key]); + Object.keys(defineVars).forEach((key) => { + stringifiedDefine[key] = JSON.stringify(defineVars[key]); + }); + // get runtime variable for server build + Object.keys(process.env).forEach((key) => { + // Do not transform env when bundle client side code. + if (/^ICE_CORE_/i.test(key) && transformEnv) { + // in server.entry + runtimeDefineVars[`__process.env.${key}__`] = JSON.stringify(process.env[key]); + } else if (/^ICE_/i.test(key)) { + runtimeDefineVars[`process.env.${key}`] = JSON.stringify(process.env[key]); + } }); + const define = { + ...stringifiedDefine, + ...runtimeDefineVars, + }; + const expandedEnvs = getExpandedEnvs(); + // Add user defined envs. + for (const [key, value] of Object.entries(expandedEnvs)) { + define[`import.meta.env.${key}`] = JSON.stringify(value); + } + return define; +}; + +export function createServerCompiler(options: Options) { + const { task, rootDir, command, server, syntaxFeatures } = options; + const externals = task.config?.externals || {}; + const sourceMap = task.config?.sourceMap; + const dev = command === 'start'; + + // Filter empty alias. + const { ignores, alias } = filterAlias(task.config?.alias || {}); const serverCompiler: ServerCompiler = async (customBuildOptions, { preBundle, @@ -88,7 +121,7 @@ export function createServerCompiler(options: Options) { ? customCompilationConfig : () => customCompilationConfig; - return (source, id) => { + return (source: string, id: string) => { return { ...getConfig(source, id), // Force inline when use swc as a transformer. @@ -105,26 +138,7 @@ export function createServerCompiler(options: Options) { swcOptions, redirectImports, }, 'esbuild', { isServer }); - - // get runtime variable for server build - Object.keys(process.env).forEach((key) => { - // Do not transform env when bundle client side code. - if (/^ICE_CORE_/i.test(key) && transformEnv) { - // in server.entry - runtimeDefineVars[`__process.env.${key}__`] = JSON.stringify(process.env[key]); - } else if (/^ICE_/i.test(key)) { - runtimeDefineVars[`process.env.${key}`] = JSON.stringify(process.env[key]); - } - }); - const define = { - ...defineVars, - ...runtimeDefineVars, - }; - const expandedEnvs = getExpandedEnvs(); - // Add user defined envs. - for (const [key, value] of Object.entries(expandedEnvs)) { - define[`import.meta.env.${key}`] = JSON.stringify(value); - } + const define = getRuntimeDefination(task.config?.define || {}, runtimeDefineVars, transformEnv); if (preBundle) { preBundleDepsMetadata = await createPreBundleDepsMetadata({ diff --git a/packages/ice/src/service/webpackCompiler.ts b/packages/ice/src/service/webpackCompiler.ts index 0efa4782cc..8cb149634c 100644 --- a/packages/ice/src/service/webpackCompiler.ts +++ b/packages/ice/src/service/webpackCompiler.ts @@ -11,7 +11,9 @@ import { IMPORT_META_RENDERER, IMPORT_META_TARGET, WEB } from '../constant.js'; import getServerCompilerPlugin from '../utils/getServerCompilerPlugin.js'; import DataLoaderPlugin from '../webpack/DataLoaderPlugin.js'; import ReCompilePlugin from '../webpack/ReCompilePlugin.js'; +import ServerRunnerPlugin from '../webpack/ServerRunnerPlugin.js'; import { logger } from '../utils/logger.js'; +import type ServerRunner from './ServerRunner.js'; import { getRouteExportConfig } from './config.js'; const { debounce } = lodash; @@ -28,6 +30,7 @@ async function webpackCompiler(options: { getAppConfig: GetAppConfig; getRoutesConfig: GetRoutesConfig; getDataloaderConfig: GetDataloaderConfig; + serverRunner?: ServerRunner; }; }) { const { @@ -42,7 +45,7 @@ async function webpackCompiler(options: { const { rootDir, applyHook, commandArgs, command, userConfig, getAllPlugin } = context; // `commandArgs` doesn't guarantee target exists. const { target = WEB } = commandArgs; - const { serverCompiler } = hooksAPI; + const { serverCompiler, serverRunner } = hooksAPI; const { serverCompileTask, dataCache, watch } = context.extendsPluginAPI; await applyHook(`before.${command}.run`, { @@ -63,21 +66,30 @@ async function webpackCompiler(options: { // Add webpack [ServerCompilerPlugin] if (useDevServer) { const outputDir = webpackConfig.output.path; - serverCompilerPlugin = getServerCompilerPlugin(serverCompiler, { - rootDir, - serverEntry: server?.entry, - outputDir, - dataCache, - serverCompileTask: command === 'start' ? serverCompileTask : null, - userConfig, - ensureRoutesConfig, - runtimeDefineVars: { - [IMPORT_META_TARGET]: JSON.stringify(target), - [IMPORT_META_RENDERER]: JSON.stringify('server'), - }, - incremental: command === 'start', - }); - webpackConfig.plugins.push(serverCompilerPlugin); + + if (command === 'start' && serverRunner) { + // Add server runner plugin + webpackConfig.plugins.push(new ServerRunnerPlugin( + serverRunner, + ensureRoutesConfig, + )); + } else { + serverCompilerPlugin = getServerCompilerPlugin(serverCompiler, { + rootDir, + serverEntry: server?.entry, + outputDir, + dataCache, + serverCompileTask: command === 'start' ? serverCompileTask : null, + userConfig, + ensureRoutesConfig, + runtimeDefineVars: { + [IMPORT_META_TARGET]: JSON.stringify(target), + [IMPORT_META_RENDERER]: JSON.stringify('server'), + }, + incremental: command === 'start', + }); + webpackConfig.plugins.push(serverCompilerPlugin); + } // Add re-compile plugin if (command === 'start') { diff --git a/packages/ice/src/types/plugin.ts b/packages/ice/src/types/plugin.ts index e2db37eb82..2606bf96f1 100644 --- a/packages/ice/src/types/plugin.ts +++ b/packages/ice/src/types/plugin.ts @@ -5,6 +5,7 @@ import type { esbuild } from '@ice/bundles'; import type { NestedRouteManifest } from '@ice/route-manifest'; import type { Config } from '@ice/webpack-config/esm/types'; import type { AppConfig, AssetsManifest } from '@ice/runtime/esm/types'; +import type ServerCompileTask from '../utils/ServerCompileTask.js'; import type { DeclarationData, TargetDeclarationData, AddRenderFile, AddTemplateFiles, ModifyRenderData, AddDataLoaderImport, Render } from './generator.js'; type AddExport = (exportData: DeclarationData) => void; @@ -37,22 +38,24 @@ type ServerCompilerBuildOptions = Pick< export type ServerBuildResult = Partial; +export interface CompilerOptions { + swc?: Config['swcOptions']; + preBundle?: boolean; + externalDependencies?: boolean; + transformEnv?: boolean; + compilationInfo?: { + assetsManifest?: AssetsManifest; + }; + redirectImports?: Config['redirectImports']; + removeOutputs?: boolean; + runtimeDefineVars?: Record; + enableEnv?: boolean; + isServer?: boolean; +} + export type ServerCompiler = ( buildOptions: ServerCompilerBuildOptions, - options?: { - swc?: Config['swcOptions']; - preBundle?: boolean; - externalDependencies?: boolean; - transformEnv?: boolean; - compilationInfo?: { - assetsManifest?: AssetsManifest; - }; - redirectImports?: Config['redirectImports']; - removeOutputs?: boolean; - runtimeDefineVars?: Record; - enableEnv?: boolean; - isServer?: boolean; - } + options?: CompilerOptions, ) => Promise; export type WatchEvent = [ pattern: RegExp | string, @@ -140,12 +143,9 @@ export interface ExtendsPluginAPI { addEvent?: (watchEvent: WatchEvent) => void; removeEvent?: (name: string) => void; }; + serverCompileTask: ServerCompileTask; getRouteManifest: () => Routes; getFlattenRoutes: () => string[]; - serverCompileTask: { - set: (task: ReturnType) => void; - get: () => ReturnType; - }; dataCache: Map; } diff --git a/packages/ice/src/types/userConfig.ts b/packages/ice/src/types/userConfig.ts index 2768179b2c..f0fdc6149a 100644 --- a/packages/ice/src/types/userConfig.ts +++ b/packages/ice/src/types/userConfig.ts @@ -63,6 +63,7 @@ export interface UserConfig { ssr?: boolean; ssg?: boolean; server?: { + onDemand: boolean; format?: 'esm' | 'cjs'; bundle?: boolean; ignores?: IgnorePattern[]; diff --git a/packages/ice/src/utils/ServerCompileTask.ts b/packages/ice/src/utils/ServerCompileTask.ts index 490bbe43dd..6cdeb793e5 100644 --- a/packages/ice/src/utils/ServerCompileTask.ts +++ b/packages/ice/src/utils/ServerCompileTask.ts @@ -3,14 +3,14 @@ import type { ServerCompiler } from '../types/plugin.js'; /** * Get server compile promise task in middlewares or plugins. */ -class ServerCompileTask { - private task: ReturnType; +class ServerCompileTask> { + private task: T; - set(task: ReturnType) { + set(task: T) { this.task = task; } - public async get() { + public get(): T { return this.task; } } diff --git a/packages/ice/src/webpack/ServerRunnerPlugin.ts b/packages/ice/src/webpack/ServerRunnerPlugin.ts new file mode 100644 index 0000000000..8297c32046 --- /dev/null +++ b/packages/ice/src/webpack/ServerRunnerPlugin.ts @@ -0,0 +1,41 @@ +import type { Compiler, Compilation } from 'webpack'; +import type ServerRunner from '../service/ServerRunner.js'; + +/** + * Get assets manifest from serevr runner. + */ +export default class ServerRunnerPlugin { + private ensureRoutesConfig: () => Promise; + private isCompiling: boolean; + private serverRunner: ServerRunner; + + public constructor( + serverRunner: ServerRunner, + ensureRoutesConfig: () => Promise, + ) { + this.serverRunner = serverRunner; + this.ensureRoutesConfig = ensureRoutesConfig; + } + + public compileTask = async (compilation?: Compilation) => { + if (!this.isCompiling) { + await this.ensureRoutesConfig(); + if (compilation) { + // Option of compilationInfo need to be object, while it may changed during multi-time compilation. + this.serverRunner.addCompileData({ + assetsManifest: JSON.parse(compilation.assets['assets-manifest.json'].source().toString()), + }); + } + } + }; + + public apply(compiler: Compiler) { + compiler.hooks.watchRun.tap(this.constructor.name, () => { + this.isCompiling = true; + }); + compiler.hooks.emit.tapPromise(this.constructor.name, async (compilation: Compilation) => { + this.isCompiling = false; + return this.compileTask(compilation); + }); + } +} diff --git a/packages/ice/templates/core/entry.server.ts.ejs b/packages/ice/templates/core/entry.server.ts.ejs index 3319564ffa..1f27ebfc86 100644 --- a/packages/ice/templates/core/entry.server.ts.ejs +++ b/packages/ice/templates/core/entry.server.ts.ejs @@ -1,6 +1,8 @@ import './env.server'; import * as runtime from '@ice/runtime/server'; -<% if(hydrate) {-%>import { commons, statics } from './runtimeModules';<% } -%> +<% if(hydrate) {-%> +import { commons, statics } from './runtimeModules'; +<% }-%> import * as app from '@/app'; import Document from '@/document'; import type { RenderMode, DistType } from '@ice/runtime'; diff --git a/packages/ice/tests/fixtures/nodeRunner/basic/a.js b/packages/ice/tests/fixtures/nodeRunner/basic/a.js new file mode 100644 index 0000000000..da543c2f58 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/basic/a.js @@ -0,0 +1 @@ +__ice_exports__.default = 1; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/basic/entry.js b/packages/ice/tests/fixtures/nodeRunner/basic/entry.js new file mode 100644 index 0000000000..0b9f4b5bf1 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/basic/entry.js @@ -0,0 +1,3 @@ +const path = await __ice_import__('path'); +const a = await __ice_import__('./a.js'); +__ice_exports__.default = a.default; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/circular/a.js b/packages/ice/tests/fixtures/nodeRunner/circular/a.js new file mode 100644 index 0000000000..1f416d9a0d --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/circular/a.js @@ -0,0 +1 @@ +__ice_exports__.a = () => 'A'; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/circular/b.js b/packages/ice/tests/fixtures/nodeRunner/circular/b.js new file mode 100644 index 0000000000..cad46a46b0 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/circular/b.js @@ -0,0 +1,2 @@ +const __import_a__ = await __ice_import__('./entry.js'); +__ice_exports__.b = () => `B${__import_a__.foo()}`; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/circular/entry.js b/packages/ice/tests/fixtures/nodeRunner/circular/entry.js new file mode 100644 index 0000000000..11dce533e4 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/circular/entry.js @@ -0,0 +1,11 @@ +const __import_a__ = await __ice_import__('./a.js'); +const __import_b__ = await __ice_import__('./b.js'); + +__ice_exports__.foo = function() { + return 'test'; +} + +__ice_exports__.default = { + a: __import_a__.a(), + b: __import_b__.b(), +} diff --git a/packages/ice/tests/fixtures/nodeRunner/cjs/a.js b/packages/ice/tests/fixtures/nodeRunner/cjs/a.js new file mode 100644 index 0000000000..89c5483ce6 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/cjs/a.js @@ -0,0 +1,4 @@ +const a = 1; +const b = 2; + +module.exports = { a, b }; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/cjs/entry.js b/packages/ice/tests/fixtures/nodeRunner/cjs/entry.js new file mode 100644 index 0000000000..9f146a8f73 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/cjs/entry.js @@ -0,0 +1,7 @@ +const imported = require('./a.js'); +exports.a = imported.a; +exports.default = { + a: imported.a, +}; +console.log(module.exports); +module.exports = imported.a; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/cjs/package.json b/packages/ice/tests/fixtures/nodeRunner/cjs/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/cjs/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/export-all/a.js b/packages/ice/tests/fixtures/nodeRunner/export-all/a.js new file mode 100644 index 0000000000..9b99db3d59 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/export-all/a.js @@ -0,0 +1,2 @@ +__ice_exports__.a = 1; +__ice_exports__.b = 2; \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/export-all/entry.js b/packages/ice/tests/fixtures/nodeRunner/export-all/entry.js new file mode 100644 index 0000000000..45fb4c2914 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/export-all/entry.js @@ -0,0 +1,3 @@ +const __ice_import_all = await __ice_import__('./a.js'); + +__ice_exports_all__(__ice_import_all); \ No newline at end of file diff --git a/packages/ice/tests/fixtures/nodeRunner/externalize/entry.js b/packages/ice/tests/fixtures/nodeRunner/externalize/entry.js new file mode 100644 index 0000000000..479ee79a32 --- /dev/null +++ b/packages/ice/tests/fixtures/nodeRunner/externalize/entry.js @@ -0,0 +1,4 @@ +const consola = await __ice_import__('consola'); + +__ice_exports__.default = Object.getOwnPropertyDescriptor(consola, 'default'); +__ice_exports__.log = consola.log; \ No newline at end of file diff --git a/packages/ice/tests/nodeRunner.test.ts b/packages/ice/tests/nodeRunner.test.ts new file mode 100644 index 0000000000..ea63a08f30 --- /dev/null +++ b/packages/ice/tests/nodeRunner.test.ts @@ -0,0 +1,84 @@ +import * as path from 'path'; +import { fileURLToPath } from 'url'; +import fs from 'fs'; +import { expect, it, describe } from 'vitest'; + +import Runner from '../src/service/Runner'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +describe('node runner', () => { + const basicResolve = async (id, importee) => { + return id.startsWith('./') ? path.resolve(path.dirname(importee!), id) : id; + }; + const basicLoad = async ({ path: id }) => { + if (id.endsWith('.js')) { + const code = fs.readFileSync(id, 'utf-8'); + return { + code, + }; + } else { + return { + externalize: id, + }; + } + }; + + it('basic', async () => { + const rootDir = path.join(__dirname, './fixtures/nodeRunner/basic/'); + const nodeRunner = new Runner({ + rootDir, + resolveId: basicResolve, + load: basicLoad, + }); + const result = await nodeRunner.run('entry.js'); + expect(result.default).toBe(1); + }); + it('cjs', async () => { + const rootDir = path.join(__dirname, './fixtures/nodeRunner/cjs/'); + const nodeRunner = new Runner({ + rootDir, + resolveId: basicResolve, + load: basicLoad, + }); + const result = await nodeRunner.run('entry.js'); + expect(result.default).toBe(1); + expect(result.a).toBe(1); + }); + it('circular', async () => { + const rootDir = path.join(__dirname, './fixtures/nodeRunner/circular/'); + const nodeRunner = new Runner({ + rootDir, + load: basicLoad, + }); + const result = await nodeRunner.run('entry.js'); + expect(result.default).toEqual({ + a: 'A', + b: 'Btest', + }); + }); + it('export all', async () => { + const rootDir = path.join(__dirname, './fixtures/nodeRunner/export-all/'); + const nodeRunner = new Runner({ + rootDir, + resolveId: basicResolve, + load: basicLoad, + }); + const result = await nodeRunner.run('entry.js'); + expect(result).toEqual({ + a: 1, + b: 2, + }); + }); + it('externalize', async () => { + const rootDir = path.join(__dirname, './fixtures/nodeRunner/externalize/'); + const nodeRunner = new Runner({ + rootDir, + resolveId: basicResolve, + load: basicLoad, + }); + const result = await nodeRunner.run('entry.js'); + expect(typeof result.log).toBe('function'); + expect(typeof result.default).toBe('object'); + }); +}); \ No newline at end of file diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 4ff7521e51..7ac029e612 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -217,7 +217,6 @@ async function doRender(serverContext: ServerContext, renderOptions: RenderOptio } const matches = matchRoutes(routes, location, finalBasename); - const routePath = getCurrentRoutePath(matches); if (documentOnly) { return renderDocument({ matches, routePath, renderOptions }); diff --git a/packages/style-import/package.json b/packages/style-import/package.json index 445f3f1448..bf34485fd8 100644 --- a/packages/style-import/package.json +++ b/packages/style-import/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "es-module-lexer": "^1.0.2", - "magic-string": "^0.26.2" + "magic-string": "^0.27.0" }, "publishConfig": { "access": "public" diff --git a/packages/webpack-config/src/types.ts b/packages/webpack-config/src/types.ts index d149fabe34..8fb20fc2de 100644 --- a/packages/webpack-config/src/types.ts +++ b/packages/webpack-config/src/types.ts @@ -41,6 +41,7 @@ interface SwcOptions { compilationConfig?: SwcCompilationConfig | ((source: string, id: string) => SwcCompilationConfig); keepExports?: string[]; getRoutePaths?: Function; + nodeTransform?: boolean; } interface ImportDeclaration { diff --git a/packages/webpack-config/src/unPlugins/compilation.ts b/packages/webpack-config/src/unPlugins/compilation.ts index dcfc0cdbb9..59d1e6bf65 100644 --- a/packages/webpack-config/src/unPlugins/compilation.ts +++ b/packages/webpack-config/src/unPlugins/compilation.ts @@ -1,5 +1,5 @@ import path from 'path'; -import { swc, swcPluginRemoveExport, swcPluginKeepExport, coreJsPath } from '@ice/bundles'; +import { swc, swcPluginRemoveExport, swcPluginKeepExport, swcPluginNodeTransform, coreJsPath } from '@ice/bundles'; import browserslist from 'browserslist'; import consola from 'consola'; import type { SwcConfig, ReactConfig } from '@ice/bundles'; @@ -41,13 +41,13 @@ const compilationPlugin = (options: Options): UnpluginOptions => { enableEnv, } = options; - const { removeExportExprs, compilationConfig, keepExports, getRoutePaths } = swcOptions; + const { removeExportExprs, compilationConfig, keepExports, getRoutePaths, nodeTransform } = swcOptions; const compileRegex = compileIncludes.map((includeRule) => { return includeRule instanceof RegExp ? includeRule : new RegExp(includeRule); }); - function isRouteEntry(id) { + function isRouteEntry(id: string) { const routes = getRoutePaths(); const matched = routes.find(route => { @@ -57,7 +57,7 @@ const compilationPlugin = (options: Options): UnpluginOptions => { return !!matched; } - function isAppEntry(id) { + function isAppEntry(id: string) { return /(.*)src\/app.(ts|tsx|js|jsx)/.test(id); } @@ -102,6 +102,7 @@ const compilationPlugin = (options: Options): UnpluginOptions => { } const swcPlugins = []; + // handle app.tsx and page entries only if (removeExportExprs) { if (isRouteEntry(id) || isAppEntry(id)) { @@ -135,6 +136,9 @@ const compilationPlugin = (options: Options): UnpluginOptions => { } } + if (nodeTransform) { + swcPlugins.push([swcPluginNodeTransform, {}]); + } if (swcPlugins.length > 0) { merge(programmaticOptions, { jsc: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdeafcbd11..38348cfc19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -778,6 +778,7 @@ importers: packages/bundles: specifiers: '@ice/swc-plugin-keep-export': 0.1.4 + '@ice/swc-plugin-node-transform': 0.1.0-5 '@ice/swc-plugin-remove-export': 0.1.2 '@pmmmwh/react-refresh-webpack-plugin': 0.5.7 '@swc/core': 1.3.19 @@ -822,7 +823,7 @@ importers: less-loader: 10.2.0 loader-utils: ^2.0.0 lodash: 4.17.21 - magic-string: 0.26.3 + magic-string: 0.27.0 mini-css-extract-plugin: 2.6.1 open: ^8.0.9 ora: 5.4.1 @@ -857,6 +858,7 @@ importers: ws: ^8.4.2 dependencies: '@ice/swc-plugin-keep-export': 0.1.4 + '@ice/swc-plugin-node-transform': 0.1.0-5 '@ice/swc-plugin-remove-export': 0.1.2 '@swc/core': 1.3.19 ansi-html-community: 0.0.8 @@ -905,7 +907,7 @@ importers: less-loader: 10.2.0_less@4.1.2+webpack@5.75.0 loader-utils: 2.0.2 lodash: 4.17.21 - magic-string: 0.26.3 + magic-string: 0.27.0 mini-css-extract-plugin: 2.6.1_webpack@5.75.0 open: 8.4.0 ora: 5.4.1 @@ -989,11 +991,13 @@ importers: dotenv-expand: ^8.0.3 ejs: ^3.1.6 esbuild: ^0.16.5 + estree-walker: ^3.0.2 fast-glob: ^3.2.11 find-up: ^5.0.0 fs-extra: ^10.0.0 jest: ^29.0.2 micromatch: ^4.0.5 + mlly: ^1.1.0 mrmime: ^1.0.0 open: ^8.4.0 path-to-regexp: ^6.2.0 @@ -1028,10 +1032,12 @@ importers: dotenv: 16.0.2 dotenv-expand: 8.0.3 ejs: 3.1.8 + estree-walker: 3.0.2 fast-glob: 3.2.12 find-up: 5.0.0 fs-extra: 10.1.0 micromatch: 4.0.5 + mlly: 1.1.0 mrmime: 1.0.1 open: 8.4.0 path-to-regexp: 6.2.1 @@ -1416,10 +1422,10 @@ importers: packages/style-import: specifiers: es-module-lexer: ^1.0.2 - magic-string: ^0.26.2 + magic-string: ^0.27.0 dependencies: es-module-lexer: 1.0.3 - magic-string: 0.26.4 + magic-string: 0.27.0 packages/webpack-config: specifiers: @@ -2621,7 +2627,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.12.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.19.0 /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.19.3: resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} @@ -2629,7 +2635,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.19.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.19.0 dev: true /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.12: @@ -2638,7 +2644,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.20.12 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.19.0 /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.19.3: resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -5258,6 +5264,10 @@ packages: resolution: {integrity: sha512-fOc09KALmL2zJK1xNGTEt/C27mXL7NVn/v1eRjjuM4uer+qmWIxYXIa9dpfTX5ZUn8zXhrKH8lGdczoKHCzyQQ==} dev: false + /@ice/swc-plugin-node-transform/0.1.0-5: + resolution: {integrity: sha512-YCZUQwS4r9kjF2RDaPsChP+SEfWHecq2uqwCkZ4+akjL0hZBxbxkN0kXCRMV2O0rNDSBfMpUUdBeAcrCuFuxHw==} + dev: false + /@ice/swc-plugin-remove-export/0.1.2: resolution: {integrity: sha512-HPeYj+z1ylaD5fJkSqyJ+eXbrHiCdy/t/t56uyf20aqsAyx12EiHVnfV4blW31DSWhFt/veAUXYzbaJ8b9KLOQ==} dev: false @@ -5786,7 +5796,6 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/trace-mapping/0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} @@ -7737,6 +7746,12 @@ packages: hasBin: true dev: true + /acorn/8.8.1: + resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + /acorn/8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} @@ -11528,6 +11543,10 @@ packages: /estree-walker/2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + /estree-walker/3.0.2: + resolution: {integrity: sha512-C03BvXCQIH/po+PNPONx/zSM9ziPr9weX8xNhYb/IJtdJ9z+L4z9VKPTB+UTHdmhnIopA2kc419ueyVyHVktwA==} + dev: false + /esutils/2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -14659,6 +14678,10 @@ packages: engines: {node: '>=6'} hasBin: true + /jsonc-parser/3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: false + /jsonfile/4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -15092,19 +15115,11 @@ packages: sourcemap-codec: 1.4.8 dev: true - /magic-string/0.26.3: - resolution: {integrity: sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==} - engines: {node: '>=12'} - dependencies: - sourcemap-codec: 1.4.8 - dev: true - - /magic-string/0.26.4: - resolution: {integrity: sha512-e5uXtVJ22aEpK9u1+eQf0fSxHeqwyV19K+uGnlROCxUhzwRip9tBsaMViK/0vC3viyPd5Gtucp3UmEp/Q2cPTQ==} + /magic-string/0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} dependencies: - sourcemap-codec: 1.4.8 - dev: false + '@jridgewell/sourcemap-codec': 1.4.14 /make-dir/2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} @@ -15436,6 +15451,15 @@ packages: engines: {node: '>=10'} hasBin: true + /mlly/1.1.0: + resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==} + dependencies: + acorn: 8.8.1 + pathe: 1.0.0 + pkg-types: 1.0.1 + ufo: 1.0.1 + dev: false + /moment/2.29.4: resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} @@ -16038,6 +16062,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /pathe/1.0.0: + resolution: {integrity: sha512-nPdMG0Pd09HuSsr7QOKUXO2Jr9eqaDiZvDwdyIhNG5SHYujkQHYKDfGQkulBxvbDHz8oHLsTgKN86LSwYzSHAg==} + dev: false + /pathval/1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true @@ -16092,6 +16120,14 @@ packages: dependencies: find-up: 4.1.0 + /pkg-types/1.0.1: + resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.1.0 + pathe: 1.0.0 + dev: false + /pkg-up/3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -19538,7 +19574,6 @@ packages: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 - dev: true /serialize-javascript/6.0.1: resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==} @@ -19793,6 +19828,7 @@ packages: /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + dev: true /space-separated-tokens/1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} @@ -20457,11 +20493,11 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.15 esbuild: 0.16.10 jest-worker: 27.5.1 schema-utils: 3.1.1 - serialize-javascript: 6.0.1 + serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_esbuild@0.16.10 @@ -20481,12 +20517,12 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.15 '@swc/core': 1.3.19 esbuild: 0.16.10 jest-worker: 27.5.1 schema-utils: 3.1.1 - serialize-javascript: 6.0.1 + serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_ncbsfugu56ddhgadp34k4kpsue @@ -20506,10 +20542,10 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.15 jest-worker: 27.5.1 schema-utils: 3.1.1 - serialize-javascript: 6.0.1 + serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0 @@ -20916,6 +20952,10 @@ packages: resolution: {integrity: sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==} dev: false + /ufo/1.0.1: + resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} + dev: false + /uglify-js/3.17.2: resolution: {integrity: sha512-bbxglRjsGQMchfvXZNusUcYgiB9Hx2K4AHYXQy2DITZ9Rd+JzhX7+hoocE5Winr7z2oHvPsekkBwXtigvxevXg==} engines: {node: '>=0.8.0'} diff --git a/tests/integration/basic-project.test.ts b/tests/integration/basic-project.test.ts index e21b8d20a7..779666f72d 100644 --- a/tests/integration/basic-project.test.ts +++ b/tests/integration/basic-project.test.ts @@ -149,6 +149,7 @@ describe(`start ${example}`, () => { test('ClientOnly Component', async () => { await page.push('/client-only'); + await page.waitForNetworkIdle(); expect(await page.$$text('#mounted')).toStrictEqual(['Client']); const pageUrlText = await page.$$text('#page-url'); expect((pageUrlText as string[])[0].endsWith('/client-only')).toBeTruthy(); From 0dbac5d8cd7d9a577c6dd93b576ef0841f0dc278 Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Fri, 24 Feb 2023 15:11:38 +0800 Subject: [PATCH 05/21] chore: setup git user (#5969) * chore: setup git user * Update release.yml * chore: ci * chore: update lock * chore: git user --- .github/workflows/release.yml | 4 ++++ .github/workflows/version.yml | 5 ++++- package.json | 2 ++ pnpm-lock.yaml | 22 +++++++++++++++------- scripts/setupUser.ts | 18 ++++++++++++++++++ 5 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 scripts/setupUser.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1b94dbf8f5..b9571e3af0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,9 @@ jobs: - name: Setup run: pnpm run setup + - name: Setup git user + run: pnpm run setup-git + - name: Publish to npm id: changesets uses: changesets/action@v1 @@ -41,6 +44,7 @@ jobs: title: 'chore: update versions' publish: pnpm release createGithubReleases: false + setupGitUser: false env: GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index f77bd454df..a43bcf1d07 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -32,12 +32,15 @@ jobs: - name: Install Dependencies run: pnpm install + - name: Setup git user + run: pnpm run setup-git + - name: Create Release Pull Request uses: changesets/action@v1 with: version: pnpm run version commit: 'chore: update versions' title: 'chore: update versions' - + setupGitUser: false env: GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }} diff --git a/package.json b/package.json index 3ae16ef879..cfb615e2bb 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "scripts": { "prepare": "husky install", "setup": "rm -rf node_modules packages/*/node_modules && pnpm install && pnpm prebundle && pnpm build", + "setup-git": "tsx ./scripts/setupUser.ts", "rebuild": "pnpm install && pnpm run build", "watch": "pnpm --parallel --filter=./packages/* run watch", "build": "pnpm run clean && pnpm -r --filter=./packages/* run build", @@ -25,6 +26,7 @@ "release:beta": "changeset pre enter beta && pnpm run version && pnpm run release && changeset pre exit" }, "devDependencies": { + "@actions/exec": "^1.1.1", "@applint/spec": "^1.2.3", "@changesets/cli": "^2.26.0", "@commitlint/cli": "^16.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38348cfc19..9262b6ddcf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,7 @@ importers: .: specifiers: + '@actions/exec': ^1.1.1 '@applint/spec': ^1.2.3 '@changesets/cli': ^2.26.0 '@commitlint/cli': ^16.3.0 @@ -40,6 +41,7 @@ importers: typescript: ^4.7.4 vitest: ^0.15.2 devDependencies: + '@actions/exec': 1.1.1 '@applint/spec': 1.2.3_4z3hyc753cbjxfspnrzfmxudwq '@changesets/cli': 2.26.0 '@commitlint/cli': 16.3.0 @@ -1512,6 +1514,16 @@ importers: packages: + /@actions/exec/1.1.1: + resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} + dependencies: + '@actions/io': 1.1.2 + dev: true + + /@actions/io/1.1.2: + resolution: {integrity: sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw==} + dev: true + /@adobe/css-tools/4.0.1: resolution: {integrity: sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==} dev: true @@ -9423,8 +9435,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - JSONStream: 1.3.5 is-text-path: 1.0.1 + JSONStream: 1.3.5 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -18592,12 +18604,6 @@ packages: /react-dev-utils/12.0.1_hhrrucqyg4eysmfpujvov2ym5u: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} - peerDependencies: - typescript: '>=2.7' - webpack: '>=4' - peerDependenciesMeta: - typescript: - optional: true dependencies: '@babel/code-frame': 7.18.6 address: 1.2.2 @@ -18628,7 +18634,9 @@ packages: transitivePeerDependencies: - eslint - supports-color + - typescript - vue-template-compiler + - webpack /react-dom/17.0.2_react@17.0.2: resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} diff --git a/scripts/setupUser.ts b/scripts/setupUser.ts new file mode 100644 index 0000000000..444ad66c80 --- /dev/null +++ b/scripts/setupUser.ts @@ -0,0 +1,18 @@ +import { exec } from '@actions/exec'; + +const setupUser = async () => { + await exec('git', [ + 'config', + 'user.name', + '"ClarkXia"', + ]); + await exec('git', [ + 'config', + 'user.email', + '"xiawenwu41@gmail.com"', + ]); +}; + +(async () => { + await setupUser(); +})(); From 071a627dacf2c7f4c59bde1804ff391172cb50c3 Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Fri, 24 Feb 2023 17:22:18 +0800 Subject: [PATCH 06/21] feat: support code spiliting strategy (#5957) * feat: support code spiliting strategy * fix: optimize code * fix: compatible with splitChunks * fix: compatible with splitChunks * chore: default value chunks * Update config.md * Update routes.ts --- .changeset/strong-socks-invite.md | 6 +++ examples/with-nested-routes/ice.config.mts | 3 +- packages/ice/src/config.ts | 18 +++++++++ packages/ice/src/createService.ts | 8 +++- packages/ice/src/getWatchEvents.ts | 8 ++-- packages/ice/src/routes.ts | 37 ++++++++++++------- packages/ice/src/types/userConfig.ts | 5 +++ packages/ice/templates/core/routes.ts.ejs | 5 ++- .../webpack-config/src/config/splitChunks.ts | 29 ++++++++++++++- packages/webpack-config/src/index.ts | 6 +-- packages/webpack-config/src/types.ts | 2 +- website/docs/guide/basic/config.md | 17 +++++++-- 12 files changed, 116 insertions(+), 28 deletions(-) create mode 100644 .changeset/strong-socks-invite.md diff --git a/.changeset/strong-socks-invite.md b/.changeset/strong-socks-invite.md new file mode 100644 index 0000000000..bcd01e5acf --- /dev/null +++ b/.changeset/strong-socks-invite.md @@ -0,0 +1,6 @@ +--- +'@ice/webpack-config': patch +'@ice/app': patch +--- + +feat: support code spliting strategy diff --git a/examples/with-nested-routes/ice.config.mts b/examples/with-nested-routes/ice.config.mts index 71bb8d7a4a..e7ac2d9da2 100644 --- a/examples/with-nested-routes/ice.config.mts +++ b/examples/with-nested-routes/ice.config.mts @@ -1,4 +1,5 @@ import { defineConfig } from '@ice/app'; export default defineConfig({ -}); \ No newline at end of file + codeSplitting: false, +}); diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index 7a45b4e3c2..e0c6bf0666 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -352,6 +352,24 @@ const userConfig = [ config.splitChunks = splitChunks; }, }, + { + name: 'codeSplitting', + validation: 'boolean|string', + defaultValue: true, + setConfig: (config: Config, codeSplitting: UserConfig['codeSplitting'], context: UserConfigContext) => { + const { originalUserConfig } = context; + if ('splitChunks' in originalUserConfig) { + logger.warn('splitChunks is deprecated, please use codeSplitting instead.https://ice.work/docs/guide/basic/config#codesplitting'); + } else { + // When codeSplitting is set to false / router, do not config splitChunks. + if (codeSplitting === false || codeSplitting === 'page') { + config.splitChunks = false; + } else { + config.splitChunks = codeSplitting; + } + } + }, + }, { name: 'crossOriginLoading', validation: 'boolean|string', diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index cb89e06eb7..9981c5af43 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -19,7 +19,7 @@ import test from './commands/test.js'; import getWatchEvents from './getWatchEvents.js'; import { setEnv, updateRuntimeEnv, getCoreEnvKeys } from './utils/runtimeEnv.js'; import getRuntimeModules from './utils/getRuntimeModules.js'; -import { generateRoutesInfo } from './routes.js'; +import { generateRoutesInfo, getRoutesDefination } from './routes.js'; import * as config from './config.js'; import { RUNTIME_TMP_DIR, WEB, RUNTIME_EXPORTS } from './constant.js'; import createSpinner from './utils/createSpinner.js'; @@ -197,6 +197,9 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt const platformTaskConfig = taskConfigs[0]; const iceRuntimePath = '@ice/runtime'; + // Only when code splitting use the default strategy or set to `router`, the router will be lazy loaded. + const lazy = [true, 'chunks', 'page'].includes(userConfig.codeSplitting); + const { routeImports, routeDefination } = getRoutesDefination(routesInfo.routes, lazy); // add render data generator.setRenderData({ ...routesInfo, @@ -215,6 +218,8 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt entryCode, jsOutput: distType.includes('javascript'), dataLoader: userConfig.dataLoader, + routeImports, + routeDefination, }); dataCache.set('routes', JSON.stringify(routesInfo)); dataCache.set('hasExportAppData', hasExportAppData ? 'true' : ''); @@ -287,6 +292,7 @@ async function createService({ rootDir, command, commandArgs }: CreateServiceOpt templateDir: coreTemplate, cache: dataCache, routeManifest, + lazyRoutes: lazy, ctx, }), ); diff --git a/packages/ice/src/getWatchEvents.ts b/packages/ice/src/getWatchEvents.ts index a9c3f8f49a..e62f627ff0 100644 --- a/packages/ice/src/getWatchEvents.ts +++ b/packages/ice/src/getWatchEvents.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import type { Context } from 'build-scripts'; import type { Config } from '@ice/webpack-config/esm/types'; import type { WatchEvent } from './types/plugin.js'; -import { generateRoutesInfo } from './routes.js'; +import { generateRoutesInfo, getRoutesDefination } from './routes.js'; import type Generator from './service/runtimeGenerator'; import getGlobalStyleGlobPattern from './utils/getGlobalStyleGlobPattern.js'; import renderExportsTemplate from './utils/renderExportsTemplate.js'; @@ -19,16 +19,18 @@ interface Options { cache: Map; ctx: Context; routeManifest: RouteManifest; + lazyRoutes: boolean; } const getWatchEvents = (options: Options): WatchEvent[] => { - const { generator, targetDir, templateDir, cache, ctx, routeManifest } = options; + const { generator, targetDir, templateDir, cache, ctx, routeManifest, lazyRoutes } = options; const { userConfig: { routes: routesConfig, dataLoader }, configFile, rootDir } = ctx; const watchRoutes: WatchEvent = [ /src\/pages\/?[\w*-:.$]+$/, async (eventName: string) => { if (eventName === 'add' || eventName === 'unlink' || eventName === 'change') { const routesRenderData = await generateRoutesInfo(rootDir, routesConfig); + const { routeImports, routeDefination } = getRoutesDefination(routesRenderData.routes, lazyRoutes); const stringifiedData = JSON.stringify(routesRenderData); if (cache.get('routes') !== stringifiedData) { cache.set('routes', stringifiedData); @@ -38,7 +40,7 @@ const getWatchEvents = (options: Options): WatchEvent[] => { generator.renderFile( path.join(templateDir, 'routes.ts.ejs'), path.join(rootDir, targetDir, 'routes.ts'), - routesRenderData, + { routeImports, routeDefination }, ); // Keep generate route manifest for avoid breaking change. generator.renderFile( diff --git a/packages/ice/src/routes.ts b/packages/ice/src/routes.ts index 1eea5f67f9..798bdc8569 100644 --- a/packages/ice/src/routes.ts +++ b/packages/ice/src/routes.ts @@ -19,7 +19,6 @@ export async function generateRoutesInfo(rootDir: string, routesConfig: UserConf await Promise.all(analyzeTasks); const routes = formatNestedRouteManifest(routeManifest); - const routesStr = generateRoutesStr(routes); let routesCount = 0; Object.keys(routeManifest).forEach((key) => { const routeItem = routeManifest[key]; @@ -31,7 +30,6 @@ export async function generateRoutesInfo(rootDir: string, routesConfig: UserConf return { routesCount, routeManifest, - routesStr, routes, loaders: generateRouteConfig(routes, 'dataLoader', (str, imports) => { return imports.length > 0 ? `${str} @@ -48,36 +46,47 @@ export default { }; } -function generateRoutesStr(nestRouteManifest: NestedRouteManifest[]) { - return `[ - ${recurseRoutesStr(nestRouteManifest)} -]`; -} - -function recurseRoutesStr(nestRouteManifest: NestedRouteManifest[], depth = 0) { - return nestRouteManifest.reduce((prev, route) => { +export function getRoutesDefination(nestRouteManifest: NestedRouteManifest[], lazy = false, depth = 0) { + const routeImports: string[] = []; + const routeDefination = nestRouteManifest.reduce((prev, route) => { const { children, path: routePath, index, componentName, file, id, layout, exports } = route; const componentPath = id.startsWith('__') ? file : `@/pages/${file}`.replace(new RegExp(`${path.extname(file)}$`), ''); + + let loadStatement = ''; + if (lazy) { + loadStatement = `import(/* webpackChunkName: "p_${componentName}" */ '${formatPath(componentPath)}')`; + } else { + const camelComponentName = componentName.replace(/-(\w)/g, (_, letter) => letter.toUpperCase()); + routeImports.push(`import * as ${camelComponentName} from '${formatPath(componentPath)}';`); + loadStatement = camelComponentName; + } const routeProperties: string[] = [ `path: '${formatPath(routePath || '')}',`, - `load: () => import(/* webpackChunkName: "p_${componentName}" */ '${formatPath(componentPath)}'),`, + `load: () => ${loadStatement},`, `componentName: '${componentName}',`, `index: ${index},`, `id: '${id}',`, 'exact: true,', `exports: ${JSON.stringify(exports)},`, ]; + if (layout) { routeProperties.push('layout: true,'); } if (children) { - routeProperties.push(`children: [${recurseRoutesStr(children, depth + 1)}]`); + const res = getRoutesDefination(children, lazy, depth + 1); + routeImports.push(...res.routeImports); + routeProperties.push(`children: [${res.routeDefination}]`); } - prev += formatRoutesStr(depth, routeProperties); return prev; }, ''); + + return { + routeImports, + routeDefination, + }; } function formatRoutesStr(deep: number, strs: string[]) { @@ -123,4 +132,4 @@ function generateRouteConfig( }, ''); } return template(importConfig(routes, ''), imports); -} \ No newline at end of file +} diff --git a/packages/ice/src/types/userConfig.ts b/packages/ice/src/types/userConfig.ts index f0fdc6149a..d970bbf44d 100644 --- a/packages/ice/src/types/userConfig.ts +++ b/packages/ice/src/types/userConfig.ts @@ -74,7 +74,12 @@ export interface UserConfig { experimental?: Config['experimental']; transform?: UnpluginOptions['transform']; syntaxFeatures?: SyntaxFeatures; + /** + * @deprecated + * Please use `codeSplitting` instead + */ splitChunks?: boolean; + codeSplitting?: 'page' | 'vendors' | boolean; dataLoader?: { fetcher?: Fetcher; } | Boolean; diff --git a/packages/ice/templates/core/routes.ts.ejs b/packages/ice/templates/core/routes.ts.ejs index 4dd64bd0d8..f15765f6e9 100644 --- a/packages/ice/templates/core/routes.ts.ejs +++ b/packages/ice/templates/core/routes.ts.ejs @@ -1 +1,4 @@ -export default <%- routesStr %>; +<%- routeImports.length ? routeImports.join('\n') + '\n\n' : ''; -%> +export default [ + <%- routeDefination %> +]; diff --git a/packages/webpack-config/src/config/splitChunks.ts b/packages/webpack-config/src/config/splitChunks.ts index 127ba54832..0f5739471c 100644 --- a/packages/webpack-config/src/config/splitChunks.ts +++ b/packages/webpack-config/src/config/splitChunks.ts @@ -28,7 +28,24 @@ const isModuleCSS = (module: { type: string }): boolean => { module.type === 'css/extract-css-chunks' ); }; -const getSplitChunksConfig = (rootDir: string): webpack.Configuration['optimization']['splitChunks'] => { + +type SplitChunksConfig = webpack.Configuration['optimization']['splitChunks']; + +// Split all node_modules into a single vendors chunk. +export const getVendorStrategy = (): SplitChunksConfig => { + return { + cacheGroups: { + vendors: { + test: /[\\/]node_modules[\\/]/, + priority: 10, + name: 'vendors', + chunks: 'async', + }, + }, + }; +}; + +export const getChunksStrategy = (rootDir: string): SplitChunksConfig => { const frameworkPaths: string[] = []; const visitedFramework = new Set(); @@ -98,4 +115,14 @@ const getSplitChunksConfig = (rootDir: string): webpack.Configuration['optimizat }; }; +const getSplitChunksConfig = (rootDir: string, strategy: string | boolean): SplitChunksConfig => { + if (strategy === false) { + return { minChunks: Infinity, cacheGroups: { default: false } }; + } else if (strategy === 'vendors') { + return getVendorStrategy(); + } + // Default to chunks strategy. + return getChunksStrategy(rootDir); +}; + export default getSplitChunksConfig; diff --git a/packages/webpack-config/src/index.ts b/packages/webpack-config/src/index.ts index 39c245601f..1ee084027e 100644 --- a/packages/webpack-config/src/index.ts +++ b/packages/webpack-config/src/index.ts @@ -281,9 +281,9 @@ export function getWebpackConfig(options: GetWebpackConfigOptions): Configuratio ignored: watchIgnoredRegexp, }, optimization: { - splitChunks: splitChunks == false - ? { minChunks: Infinity, cacheGroups: { default: false } } - : getSplitChunksConfig(rootDir), + splitChunks: typeof splitChunks == 'object' + ? splitChunks + : getSplitChunksConfig(rootDir, splitChunks), minimize: !!minify, minimizer: [ new TerserPlugin({ diff --git a/packages/webpack-config/src/types.ts b/packages/webpack-config/src/types.ts index 8fb20fc2de..09d99a3a6f 100644 --- a/packages/webpack-config/src/types.ts +++ b/packages/webpack-config/src/types.ts @@ -148,7 +148,7 @@ export interface Config { [key: string]: string; }; - splitChunks?: boolean; + splitChunks?: boolean | 'vendors' | 'chunks' | webpack.Configuration['optimization']['splitChunks']; optimization?: Optimization; diff --git a/website/docs/guide/basic/config.md b/website/docs/guide/basic/config.md index f781f4e63c..e21a1d0975 100644 --- a/website/docs/guide/basic/config.md +++ b/website/docs/guide/basic/config.md @@ -496,16 +496,27 @@ route('/about-you', 'about.tsx'); - 类型:`boolean | string` - 默认值:`development` 模式:默认为 'cheap-module-source-map',支持通过 `false` 关闭,不支持设置为其他枚举值。`production` 模式:默认 `false`。 -### splitChunks +### splitChunks @deprecated :::caution +不再建议使用,能力由 codeSplitting 替代。 小程序端不支持该配置。 ::: -- 类型:`boolean` +默认会根据模块体积自动拆分 chunks,有可能会出现多个 bundle。如果不希望打包产物出现过多 bundle ,可设置成 `false`。 + +### codeSplitting + +- 类型:`boolean | 'vendors' | 'page' | 'chunks'` - 默认值:`true` -默认会根据模块体积自动拆分 chunks,有可能会出现多个 bundle。如果不希望打包产物出现过多 bundle ,可设置成 `false`。 +框架内置了三种分包策略分别为 `chunks`(默认策略,无需额外设置),`page` 和 `vendors`。 + +- `vendors` 策略:将异步 chunks 里的三方依赖统一打入到 vendor.js 中,避免重复,在依赖不变的情况下有效利用缓存。缺陷是如果项目过大会导致单文件尺寸过大。 +- `page` 策略:所有路由级别组件按需加载,如果需保留原 `splitChunks: false` 的效果,配置该策略 。 +- `chunks` 策略:在路由级别组件按需加载的基础上,根据模块体积大小自动拆分 chunks,为框架默认推荐策略。 + +如果存在特殊场景期望关闭分包能力,可以设置成 `false`。 ### syntaxFeatures From 6824ad630e020a89def3f4bdd6513afbdda87943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=93=E9=99=8C=E5=90=8C=E5=AD=A6?= Date: Fri, 24 Feb 2023 19:19:06 +0800 Subject: [PATCH 07/21] fix: modify type of config and fix data of prefetch is decamelized (#5973) * fix: modify type of config and fix data of prefetch is decamelized * chore: add changeset * chore: add test * chore: remove only of test * chore: dealwith warning --- .changeset/proud-glasses-retire.md | 5 ++ packages/plugin-pha/src/manifestHelpers.ts | 30 ++++++++--- packages/plugin-pha/src/types.ts | 2 + .../plugin-pha/tests/manifestHelper.test.ts | 52 ++++++++++++++++++- 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 .changeset/proud-glasses-retire.md diff --git a/.changeset/proud-glasses-retire.md b/.changeset/proud-glasses-retire.md new file mode 100644 index 0000000000..b7428556b8 --- /dev/null +++ b/.changeset/proud-glasses-retire.md @@ -0,0 +1,5 @@ +--- +'@ice/plugin-pha': major +--- + +fix: fix data of prefetch decamelize diff --git a/packages/plugin-pha/src/manifestHelpers.ts b/packages/plugin-pha/src/manifestHelpers.ts index 490f53ef96..673eba3118 100644 --- a/packages/plugin-pha/src/manifestHelpers.ts +++ b/packages/plugin-pha/src/manifestHelpers.ts @@ -7,7 +7,7 @@ import cloneDeep from 'lodash.clonedeep'; import { matchRoutes } from '@remix-run/router'; import * as htmlparser2 from 'htmlparser2'; import { decamelizeKeys, camelizeKeys, validPageConfigKeys } from './constants.js'; -import type { Page, PHAPage, PageHeader, PageConfig, Manifest, PHAManifest } from './types'; +import type { Page, PageHeader, PageConfig, Manifest, PHAManifest, Frame } from './types'; const { decamelize } = humps; @@ -35,7 +35,20 @@ interface TabConfig { html?: string; } -type MixedPage = PHAPage & PageConfig; +type ResourcePrefetchConfig = Array<{ + src: string; + mimeType?: string; + headers?: string; + queryParams?: string; +}>; + +interface InternalPageConfig { + path?: string; + document?: string; + resourcePrefetch?: ResourcePrefetchConfig; +} + +type MixedPage = InternalPageConfig & PageConfig; export function transformManifestKeys(manifest: Manifest, options?: TransformOptions): PHAManifest { const { parentKey, isRoot } = options; @@ -57,7 +70,6 @@ export function transformManifestKeys(manifest: Manifest, options?: TransformOpt if (!camelizeKeys.includes(key)) { transformKey = decamelize(key); } - if (typeof value === 'string' || typeof value === 'number') { data[transformKey] = value; } else if (Array.isArray(value)) { @@ -195,7 +207,7 @@ async function getPageManifest(page: string | Page, options: ParseOptions): Prom } } getPreload(htmlparser2.parseDocument(pageManifest.document)); - pageManifest.resource_prefetch = [...scripts, ...stylesheets]; + pageManifest.resourcePrefetch = [...scripts, ...stylesheets]; } // Always need path for page item. @@ -346,14 +358,15 @@ export async function parseManifest(manifest: Manifest, options: ParseOptions): // Single prefetch loader config. staticDataLoaders.push(dataloaderConfig[pageId]); } - pageManifest.data_prefetch = [...(pageManifest.data_prefetch || []), ...staticDataLoaders]; + pageManifest.dataPrefetch = [...(pageManifest.dataPrefetch || []), ...staticDataLoaders]; } }); if (pageManifest.frames && pageManifest.frames.length > 0) { pageManifest.frames = await Promise.all(pageManifest.frames.map((frame) => getPageManifest(frame, options))); - // Set static dataloader to data_prefetch of frames. - pageManifest.frames.forEach(frame => { + // Set static dataloader to dataPrefetch of frames. + pageManifest.frames.forEach((frame: Frame) => { + if (typeof frame === 'string') return; const title = frame.title || ''; const titleIds = getRouteIdByPage(routeManifest, title); titleIds.forEach((titleId) => { @@ -370,7 +383,7 @@ export async function parseManifest(manifest: Manifest, options: ParseOptions): staticDataLoaders.push(dataloaderConfig[title]); } - frame.data_prefetch = [...(frame.data_prefetch || []), ...staticDataLoaders]; + frame.dataPrefetch = [...(frame.dataPrefetch || []), ...staticDataLoaders]; } }); }); @@ -391,6 +404,7 @@ export async function parseManifest(manifest: Manifest, options: ParseOptions): // Delete manifest routes after transform. delete manifest.routes; } + return transformManifestKeys(manifest, { isRoot: true }); } diff --git a/packages/plugin-pha/src/types.ts b/packages/plugin-pha/src/types.ts index 7059c848e0..4f1608b6d4 100644 --- a/packages/plugin-pha/src/types.ts +++ b/packages/plugin-pha/src/types.ts @@ -104,6 +104,8 @@ type Priority = 'high' | 'normal' | 'low'; type FrameConfig = Partial<{ url: string; priority?: Priority; + title?: string; + dataPrefetch?: DataPrefetch[]; }> & WindowConfig; type WindowConfig = Partial<{ diff --git a/packages/plugin-pha/tests/manifestHelper.test.ts b/packages/plugin-pha/tests/manifestHelper.test.ts index be16c007d9..af44578ebd 100644 --- a/packages/plugin-pha/tests/manifestHelper.test.ts +++ b/packages/plugin-pha/tests/manifestHelper.test.ts @@ -538,9 +538,59 @@ describe('parse manifest', async () => { }); expect(manifest.pages![0].frames![1].data_prefetch?.length).toBe(1); - expect(manifest.pages![1].data_prefetch?.length).toBe(1); + expect(manifest.pages![1].data_prefetch?.length).toBe(2); expect(manifest.pages![2].data_prefetch).toBeUndefined(); }); + + it('prefetch of dataloader should not be decamelized', async () => { + const phaManifest = { + title: 'test', + routes: [ + { + pageHeader: {}, + frames: [ + 'blog', + 'home', + 'about', + ], + }, + 'home', + 'about', + ], + }; + + const staticDataloader = { + key: 'dataLoader222', + prefetch_type: 'mtop', + api: 'query222', + v: '0.0.1', + data: { + aaa: 111, + aaB: 222, + }, + ext_headers: {}, + }; + + const manifest = await parseManifest(phaManifest, { + ...options, + dataloaderConfig: { + home: [ + () => { + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + name: 'About', + }); + }, 1 * 100); + }); + }, + staticDataloader, + ], + }, + }); + + expect(manifest.pages![1].data_prefetch![1]?.data.aaB).toBe(222); + }); }); describe('get multiple manifest', async () => { From efba0cc44fccd983ca5593634c62c31cc2f69a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=95=BF=E5=96=86?= <2316371523@qq.com> Date: Mon, 27 Feb 2023 16:17:48 +0800 Subject: [PATCH 08/21] fix: when code has declare @jsx createElement comment, swc config runtime: 'classic' (#5976) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 遇到注释信息 应该走 classic 的编译模式 * chore: add version and changelog * chore: add changesets * feat: hasJSXComment 的逻辑放在 isRaxComponent * feat: 内部声明 --- .changeset/spicy-dryers-melt.md | 5 +++++ packages/plugin-rax-compat/src/index.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 .changeset/spicy-dryers-melt.md diff --git a/.changeset/spicy-dryers-melt.md b/.changeset/spicy-dryers-melt.md new file mode 100644 index 0000000000..d9030b9bb7 --- /dev/null +++ b/.changeset/spicy-dryers-melt.md @@ -0,0 +1,5 @@ +--- +'@ice/plugin-rax-compat': major +--- + +- [fix] Using runtime: 'classic' mode when source has declare `@jsx createElement` comment diff --git a/packages/plugin-rax-compat/src/index.ts b/packages/plugin-rax-compat/src/index.ts index 5a2d2181fb..624ebb7d9d 100644 --- a/packages/plugin-rax-compat/src/index.ts +++ b/packages/plugin-rax-compat/src/index.ts @@ -70,6 +70,18 @@ const plugin: Plugin = (options = {}) => ({ compilationConfig: (source: string) => { const isRaxComponent = /from\s['"]rax['"]/.test(source); if (isRaxComponent) { + const hasJSXComment = source.indexOf('@jsx createElement') !== -1; + if (hasJSXComment) { + return { + jsc: { + transform: { + react: { + runtime: 'classic', + }, + }, + }, + }; + } return { jsc: { transform: { From b8e974393fce935d3d3e9538d92f09aa32433f39 Mon Sep 17 00:00:00 2001 From: ClarkXia Date: Tue, 28 Feb 2023 10:00:43 +0800 Subject: [PATCH 09/21] feat: support routes config (#5968) * feat: support routes config * fix: compatible with win32 * feat: add test case * fix: optimize code * fix: compatible with path * Update routes.ts * Update routes.ts --- examples/routes-config/.browserslistrc | 1 + examples/routes-config/ice.config.mts | 9 ++ examples/routes-config/package.json | 22 ++++ examples/routes-config/src/app.tsx | 3 + examples/routes-config/src/components/bar.tsx | 7 ++ examples/routes-config/src/document.tsx | 22 ++++ examples/routes-config/src/pages/index.tsx | 9 ++ .../src/pages/sales/favorites.tsx | 7 ++ .../src/pages/sales/index.module.css | 24 ++++ .../routes-config/src/pages/sales/layout.tsx | 18 +++ .../src/pages/sales/overview.tsx | 7 ++ .../src/pages/sales/recommends.tsx | 7 ++ examples/routes-config/src/routes.ts | 27 +++++ examples/routes-config/src/types.ts | 6 + examples/routes-config/src/typings.d.ts | 1 + examples/routes-config/tsconfig.json | 32 ++++++ packages/ice/src/routes.ts | 7 +- packages/ice/src/types/userConfig.ts | 3 +- packages/route-manifest/src/index.ts | 53 ++++++++- packages/route-manifest/src/routes.ts | 4 +- .../__snapshots__/parseRoute.spec.ts.snap | 106 ++++++++++++++++++ .../route-manifest/tests/parseRoute.spec.ts | 67 +++++++++++ pnpm-lock.yaml | 17 +++ tests/integration/routes-config.test.ts | 28 +++++ 24 files changed, 481 insertions(+), 6 deletions(-) create mode 100644 examples/routes-config/.browserslistrc create mode 100644 examples/routes-config/ice.config.mts create mode 100644 examples/routes-config/package.json create mode 100644 examples/routes-config/src/app.tsx create mode 100644 examples/routes-config/src/components/bar.tsx create mode 100644 examples/routes-config/src/document.tsx create mode 100644 examples/routes-config/src/pages/index.tsx create mode 100644 examples/routes-config/src/pages/sales/favorites.tsx create mode 100644 examples/routes-config/src/pages/sales/index.module.css create mode 100644 examples/routes-config/src/pages/sales/layout.tsx create mode 100644 examples/routes-config/src/pages/sales/overview.tsx create mode 100644 examples/routes-config/src/pages/sales/recommends.tsx create mode 100644 examples/routes-config/src/routes.ts create mode 100644 examples/routes-config/src/types.ts create mode 100644 examples/routes-config/src/typings.d.ts create mode 100644 examples/routes-config/tsconfig.json create mode 100644 packages/route-manifest/tests/__snapshots__/parseRoute.spec.ts.snap create mode 100644 packages/route-manifest/tests/parseRoute.spec.ts create mode 100644 tests/integration/routes-config.test.ts diff --git a/examples/routes-config/.browserslistrc b/examples/routes-config/.browserslistrc new file mode 100644 index 0000000000..7637baddc3 --- /dev/null +++ b/examples/routes-config/.browserslistrc @@ -0,0 +1 @@ +chrome 55 \ No newline at end of file diff --git a/examples/routes-config/ice.config.mts b/examples/routes-config/ice.config.mts new file mode 100644 index 0000000000..d7297e455f --- /dev/null +++ b/examples/routes-config/ice.config.mts @@ -0,0 +1,9 @@ +import { defineConfig } from '@ice/app'; +import routeConfig from './src/routes'; + +export default defineConfig({ + routes: { + ignoreFiles: ['**'], + config: routeConfig, + }, +}); diff --git a/examples/routes-config/package.json b/examples/routes-config/package.json new file mode 100644 index 0000000000..5f97a44352 --- /dev/null +++ b/examples/routes-config/package.json @@ -0,0 +1,22 @@ +{ + "name": "@examples/routes-config", + "private": true, + "version": "1.0.0", + "scripts": { + "start": "ice start", + "build": "ice build" + }, + "description": "", + "author": "", + "license": "MIT", + "dependencies": { + "@ice/app": "workspace:*", + "@ice/runtime": "workspace:*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0" + } +} diff --git a/examples/routes-config/src/app.tsx b/examples/routes-config/src/app.tsx new file mode 100644 index 0000000000..c1664902e9 --- /dev/null +++ b/examples/routes-config/src/app.tsx @@ -0,0 +1,3 @@ +import { defineAppConfig } from 'ice'; + +export default defineAppConfig({}); diff --git a/examples/routes-config/src/components/bar.tsx b/examples/routes-config/src/components/bar.tsx new file mode 100644 index 0000000000..7861bf5cb4 --- /dev/null +++ b/examples/routes-config/src/components/bar.tsx @@ -0,0 +1,7 @@ +export default function Bar() { + return ( +
+ bar +
+ ); +} diff --git a/examples/routes-config/src/document.tsx b/examples/routes-config/src/document.tsx new file mode 100644 index 0000000000..20131b9d17 --- /dev/null +++ b/examples/routes-config/src/document.tsx @@ -0,0 +1,22 @@ +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-config/src/pages/index.tsx b/examples/routes-config/src/pages/index.tsx new file mode 100644 index 0000000000..058ac57348 --- /dev/null +++ b/examples/routes-config/src/pages/index.tsx @@ -0,0 +1,9 @@ +import { Link } from 'ice'; + +export default function Home() { + return ( + <> + <Link to="/rewrite/overview">link to sales page</Link> + </> + ); +} diff --git a/examples/routes-config/src/pages/sales/favorites.tsx b/examples/routes-config/src/pages/sales/favorites.tsx new file mode 100644 index 0000000000..c070b67299 --- /dev/null +++ b/examples/routes-config/src/pages/sales/favorites.tsx @@ -0,0 +1,7 @@ +export default function Favorites() { + return ( + <> + my favorite items + </> + ); +} diff --git a/examples/routes-config/src/pages/sales/index.module.css b/examples/routes-config/src/pages/sales/index.module.css new file mode 100644 index 0000000000..509f387dc8 --- /dev/null +++ b/examples/routes-config/src/pages/sales/index.module.css @@ -0,0 +1,24 @@ +.tabs { + display: flex; + border-bottom: 1px solid #ccc; +} + +.tabs a { + line-height: 36px; + color: #333; + text-decoration: none; + padding: 0 8px; + margin-right: 10px; + margin-bottom: 10px; + border-radius: 4px; + background-color: rgba(208, 215, 222, 0.32); +} + +.tabs a:hover { + background-color: rgba(208, 215, 222, 0.64); +} + +.container { + border-top: 1px solid #ccc; + padding-top: 20px; +} \ No newline at end of file diff --git a/examples/routes-config/src/pages/sales/layout.tsx b/examples/routes-config/src/pages/sales/layout.tsx new file mode 100644 index 0000000000..ffd92f253b --- /dev/null +++ b/examples/routes-config/src/pages/sales/layout.tsx @@ -0,0 +1,18 @@ +import { Outlet, Link } from 'ice'; +import styles from './index.module.css'; + +export default () => { + return ( + <div> + <h1>Sales</h1> + <div className={styles.tabs}> + <Link to="/rewrite/overview">overview</Link> + <Link to="/rewrite/recommends">recommends</Link> + <Link to="/rewrite/favorites">favorites</Link> + </div> + <div className={styles.container}> + <Outlet /> + </div> + </div> + ); +}; diff --git a/examples/routes-config/src/pages/sales/overview.tsx b/examples/routes-config/src/pages/sales/overview.tsx new file mode 100644 index 0000000000..e2c5f6da69 --- /dev/null +++ b/examples/routes-config/src/pages/sales/overview.tsx @@ -0,0 +1,7 @@ +export default function Overview() { + return ( + <h2> + overview all sale items + </h2> + ); +} diff --git a/examples/routes-config/src/pages/sales/recommends.tsx b/examples/routes-config/src/pages/sales/recommends.tsx new file mode 100644 index 0000000000..89eb7658fd --- /dev/null +++ b/examples/routes-config/src/pages/sales/recommends.tsx @@ -0,0 +1,7 @@ +export default function Recommends() { + return ( + <> + recommend items + </> + ); +} diff --git a/examples/routes-config/src/routes.ts b/examples/routes-config/src/routes.ts new file mode 100644 index 0000000000..4c66f3df0a --- /dev/null +++ b/examples/routes-config/src/routes.ts @@ -0,0 +1,27 @@ +const routes = [ + { + path: 'rewrite', + // 从 src/page 开始计算路径,并且需要写后缀 + component: 'sales/layout.tsx', + children: [ + { + // Test the legacy logic. It is not recommended to add slash for children path. + path: '/favorites', + component: 'sales/favorites.tsx', + }, + { + path: 'overview', + component: 'sales/overview.tsx', + }, + { + path: 'recommends', + component: 'sales/recommends.tsx', + }, + ], + }, + { + path: '/', + component: 'index.tsx', + }, +]; +export default routes; diff --git a/examples/routes-config/src/types.ts b/examples/routes-config/src/types.ts new file mode 100644 index 0000000000..2b7ee052a3 --- /dev/null +++ b/examples/routes-config/src/types.ts @@ -0,0 +1,6 @@ +export interface AppData { + title: string; + auth: { + [key: string]: boolean; + }; +} \ No newline at end of file diff --git a/examples/routes-config/src/typings.d.ts b/examples/routes-config/src/typings.d.ts new file mode 100644 index 0000000000..1f6ba4ffa6 --- /dev/null +++ b/examples/routes-config/src/typings.d.ts @@ -0,0 +1 @@ +/// <reference types="@ice/app/types" /> diff --git a/examples/routes-config/tsconfig.json b/examples/routes-config/tsconfig.json new file mode 100644 index 0000000000..26fd9ec799 --- /dev/null +++ b/examples/routes-config/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compileOnSave": false, + "buildOnSave": false, + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "module": "esnext", + "target": "es6", + "jsx": "react-jsx", + "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": ["build", "public"] +} \ No newline at end of file diff --git a/packages/ice/src/routes.ts b/packages/ice/src/routes.ts index 798bdc8569..4b32c975ca 100644 --- a/packages/ice/src/routes.ts +++ b/packages/ice/src/routes.ts @@ -6,7 +6,12 @@ import { getFileExports } from './service/analyze.js'; import formatPath from './utils/formatPath.js'; export async function generateRoutesInfo(rootDir: string, routesConfig: UserConfig['routes'] = {}) { - const routeManifest = generateRouteManifest(rootDir, routesConfig.ignoreFiles, routesConfig.defineRoutes); + const routeManifest = generateRouteManifest( + rootDir, + routesConfig.ignoreFiles, + routesConfig.defineRoutes, + routesConfig.config, + ); const analyzeTasks = Object.keys(routeManifest).map(async (key) => { const routeItem = routeManifest[key]; diff --git a/packages/ice/src/types/userConfig.ts b/packages/ice/src/types/userConfig.ts index d970bbf44d..4740c1e867 100644 --- a/packages/ice/src/types/userConfig.ts +++ b/packages/ice/src/types/userConfig.ts @@ -1,4 +1,4 @@ -import type { DefineRouteFunction } from '@ice/route-manifest'; +import type { DefineRouteFunction, RouteItem } from '@ice/route-manifest'; import type { PluginList } from 'build-scripts'; import type { UnpluginOptions } from '@ice/bundles/compiled/unplugin/index.js'; import type { ProcessOptions } from '@ice/bundles'; @@ -51,6 +51,7 @@ export interface UserConfig { routes?: { ignoreFiles?: string[]; defineRoutes?: (defineRoute: DefineRouteFunction) => void; + config?: RouteItem[]; injectInitialEntry?: boolean; }; plugins?: PluginList<Config, OverwritePluginAPI>; diff --git a/packages/route-manifest/src/index.ts b/packages/route-manifest/src/index.ts index d111057aa3..a454798fac 100644 --- a/packages/route-manifest/src/index.ts +++ b/packages/route-manifest/src/index.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import minimatch from 'minimatch'; -import { createRouteId, defineRoutes, normalizeSlashes } from './routes.js'; +import { createComponentName, createRouteId, defineRoutes, normalizeSlashes } from './routes.js'; import type { RouteManifest, DefineRouteFunction, NestedRouteManifest, ConfigRoute } from './routes.js'; export type { @@ -12,6 +12,12 @@ export type { ConfigRoute, }; +export interface RouteItem { + path: string; + component: string; + children?: RouteItem[]; +} + const validRouteChar = ['-', '\\w', '/', ':', '*']; const routeModuleExts = [ @@ -28,10 +34,12 @@ export function isRouteModuleFile(filename: string): boolean { return routeModuleExts.includes(path.extname(filename)); } + export function generateRouteManifest( rootDir: string, ignoreFiles: string[] = [], defineExtraRoutes?: (defineRoute: DefineRouteFunction) => void, + routeConfig?: RouteItem[], ) { const srcDir = path.join(rootDir, 'src'); const routeManifest: RouteManifest = {}; @@ -61,9 +69,50 @@ export function generateRouteManifest( }; } } + + // Add routes by routes config. + if (routeConfig) { + routeConfig.forEach((routeItem) => { + const routes = parseRoute(routeItem); + routes.forEach((route) => { + routeManifest[route.id] = route; + }); + }); + } + return routeManifest; } +export function parseRoute(routeItem: RouteItem, parentId?: string, parentPath?: string) { + const routes = []; + const { path: routePath, component, children } = routeItem; + const id = createRouteId(component); + let index; + const currentPath = path.join(parentPath || '/', routePath).split(path.sep).join('/'); + const isRootPath = currentPath === '/'; + if (!children && isRootPath) { + index = true; + } + const route: ConfigRoute = { + // An absolute child route path must start with the combined path of all its parent routes + // Replace the first slash with an empty string to compatible with the route definintion, e.g. /foo + path: parentId && routePath !== '/' ? routePath.replace(/^\//, '') : routePath, + index, + id, + parentId, + file: component, + componentName: createComponentName(id), + layout: !!children, + }; + routes.push(route); + if (children) { + children.forEach((childRoute) => { + routes.push(...parseRoute(childRoute, id, currentPath)); + }); + } + return routes; +} + export function formatNestedRouteManifest(routeManifest: RouteManifest, parentId?: string): NestedRouteManifest[] { return Object.keys(routeManifest) .filter(key => routeManifest[key].parentId === parentId) @@ -133,7 +182,7 @@ function defineConventionalRoutes( if (uniqueRouteId) { if (uniqueRoutes.has(uniqueRouteId)) { throw new Error( - `Path ${JSON.stringify(fullPath)} defined by route ${JSON.stringify(routeFilePath)} + `Path ${JSON.stringify(fullPath)} defined by route ${JSON.stringify(routeFilePath)} conflicts with route ${JSON.stringify(uniqueRoutes.get(uniqueRouteId))}`, ); } else { diff --git a/packages/route-manifest/src/routes.ts b/packages/route-manifest/src/routes.ts index f48bb6439a..d224b165e7 100644 --- a/packages/route-manifest/src/routes.ts +++ b/packages/route-manifest/src/routes.ts @@ -151,9 +151,9 @@ function stripFileExtension(file: string) { return file.replace(/\.[a-z0-9]+$/i, ''); } -function createComponentName(id: string) { +export function createComponentName(id: string) { return id.replace('.', '/') // 'pages/home.news' -> pages/home/news .split('/') .map((item: string) => item.toLowerCase()) .join('-'); -} \ No newline at end of file +} diff --git a/packages/route-manifest/tests/__snapshots__/parseRoute.spec.ts.snap b/packages/route-manifest/tests/__snapshots__/parseRoute.spec.ts.snap new file mode 100644 index 0000000000..64a09399e9 --- /dev/null +++ b/packages/route-manifest/tests/__snapshots__/parseRoute.spec.ts.snap @@ -0,0 +1,106 @@ +// Vitest Snapshot v1 + +exports[`parseRoute function > basic-routes 1`] = ` +[ + { + "componentName": "index", + "file": "index.tsx", + "id": "index", + "index": true, + "layout": false, + "parentId": undefined, + "path": "/", + }, +] +`; + +exports[`parseRoute function > nested layout 1`] = ` +[ + { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", + "index": undefined, + "layout": true, + "parentId": undefined, + "path": "/", + }, + { + "componentName": "home", + "file": "home.tsx", + "id": "home", + "index": undefined, + "layout": true, + "parentId": "layout", + "path": "home", + }, + { + "componentName": "home1", + "file": "home1.tsx", + "id": "home1", + "index": undefined, + "layout": false, + "parentId": "home", + "path": "1", + }, + { + "componentName": "home2", + "file": "home2.tsx", + "id": "home2", + "index": undefined, + "layout": false, + "parentId": "home", + "path": "2", + }, + { + "componentName": "about", + "file": "about.tsx", + "id": "about", + "index": undefined, + "layout": false, + "parentId": "layout", + "path": "about", + }, +] +`; + +exports[`parseRoute function > with layout 1`] = ` +[ + { + "componentName": "layout", + "file": "layout.tsx", + "id": "layout", + "index": undefined, + "layout": true, + "parentId": undefined, + "path": "/", + }, + { + "componentName": "home", + "file": "home.tsx", + "id": "home", + "index": undefined, + "layout": false, + "parentId": "layout", + "path": "home", + }, + { + "componentName": "about", + "file": "about.tsx", + "id": "about", + "index": undefined, + "layout": false, + "parentId": "layout", + "path": "about", + }, + { + "componentName": "index", + "file": "index.tsx", + "id": "index", + "index": true, + "layout": false, + "parentId": "layout", + "path": "/", + }, +] +`; diff --git a/packages/route-manifest/tests/parseRoute.spec.ts b/packages/route-manifest/tests/parseRoute.spec.ts new file mode 100644 index 0000000000..4dce6c2f06 --- /dev/null +++ b/packages/route-manifest/tests/parseRoute.spec.ts @@ -0,0 +1,67 @@ +import { expect, test, describe } from 'vitest'; +import { parseRoute } from '../src/index'; + + +describe('parseRoute function', () => { + test('basic-routes', () => { + const routes = parseRoute( + { + path: '/', + component: 'index.tsx', + }, + ); + expect(routes).toMatchSnapshot(); + }); + test('with layout', () => { + const routes = parseRoute( + { + path: '/', + component: 'layout.tsx', + children: [ + { + path: 'home', + component: 'home.tsx', + }, + { + path: 'about', + component: 'about.tsx', + }, + { + path: '/', + component: 'index.tsx', + }, + ], + }, + ); + expect(routes).toMatchSnapshot(); + }); + test('nested layout', () => { + const routes = parseRoute( + { + path: '/', + component: 'layout.tsx', + children: [ + { + path: 'home', + component: 'home.tsx', + children: [ + { + path: '1', + component: 'home1.tsx', + }, + { + path: '2', + component: 'home2.tsx', + }, + ], + }, + { + path: 'about', + component: 'about.tsx', + }, + ], + }, + ); + expect(routes).toMatchSnapshot(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9262b6ddcf..2fc17a7b11 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -378,6 +378,23 @@ importers: '@types/react-dom': 18.0.6 webpack: 5.75.0 + examples/routes-config: + specifiers: + '@ice/app': workspace:* + '@ice/runtime': workspace:* + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 + dependencies: + '@ice/app': link:../../packages/ice + '@ice/runtime': link:../../packages/runtime + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + devDependencies: + '@types/react': 18.0.21 + '@types/react-dom': 18.0.6 + examples/routes-generate: specifiers: '@ice/app': workspace:* diff --git a/tests/integration/routes-config.test.ts b/tests/integration/routes-config.test.ts new file mode 100644 index 0000000000..e18c28d923 --- /dev/null +++ b/tests/integration/routes-config.test.ts @@ -0,0 +1,28 @@ +import { expect, test, describe, afterAll } from 'vitest'; +import { startFixture, setupStartBrowser } from '../utils/start'; +import type { Page } from '../utils/browser'; +import type Browser from '../utils/browser'; + +const example = 'routes-config'; + +describe(`start ${example}`, () => { + let page: Page; + let browser: Browser; + + test('open /', async () => { + const { devServer, port } = await startFixture(example); + const res = await setupStartBrowser({ server: devServer, port }); + page = res.page; + browser = res.browser; + expect(await page.$$text('a')).toStrictEqual(['link to sales page']); + }); + + test('rewrite link', async () => { + await page.push('/rewrite/overview'); + expect(await page.$$text('h2')).toStrictEqual(['overview all sale items']); + }); + + afterAll(async () => { + await browser.close(); + }); +}); From 1c09e79e3f8c39fb6bf4d05d7a406f2255f67102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=95=BF=E5=96=86?= <2316371523@qq.com> Date: Tue, 28 Feb 2023 10:16:40 +0800 Subject: [PATCH 10/21] Feat/pha: support plugin-pha interface optional (#5978) * feat: interface optional * chore: add changesets * fix: change version type --- .changeset/eleven-spiders-yell.md | 5 +++++ packages/plugin-pha/src/index.ts | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/eleven-spiders-yell.md diff --git a/.changeset/eleven-spiders-yell.md b/.changeset/eleven-spiders-yell.md new file mode 100644 index 0000000000..ba7264facf --- /dev/null +++ b/.changeset/eleven-spiders-yell.md @@ -0,0 +1,5 @@ +--- +'@ice/plugin-pha': patch +--- + +fix: support plugin-pha interface optional diff --git a/packages/plugin-pha/src/index.ts b/packages/plugin-pha/src/index.ts index 6ed5da8ede..99e47b6048 100644 --- a/packages/plugin-pha/src/index.ts +++ b/packages/plugin-pha/src/index.ts @@ -17,8 +17,8 @@ export type Compiler = (options: { }, buildOptions: Parameters<ServerCompiler>[1]) => Promise<string>; interface PluginOptions { - template: boolean; - preload: boolean; + template?: boolean; + preload?: boolean; } function getDevPath(url: string): string { From 56fb406e8ae5e4465118d5317aa8ca7f7d13fabc Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Tue, 28 Feb 2023 15:08:10 +0800 Subject: [PATCH 11/21] fix: import path of types and runtime (#5981) * fix: import path of types and runtime * chore: package.json * chore: add changelog * fix: typings * fix: type declare --- .changeset/forty-doors-hear.md | 18 ++ examples/csr-project/src/app.tsx | 2 +- examples/icestark-child/src/app.tsx | 4 +- examples/icestark-layout/src/app.tsx | 4 +- examples/with-antd-mobile/src/store.tsx | 4 +- examples/with-auth/src/app.tsx | 2 +- examples/with-pha/src/app.tsx | 2 +- examples/with-request/src/app.tsx | 2 +- examples/with-store/src/app.tsx | 2 +- packages/ice/package.json | 2 +- packages/ice/src/commands/build.ts | 4 +- packages/ice/src/commands/start.ts | 2 +- packages/ice/src/commands/test.ts | 2 +- packages/ice/src/config.ts | 2 +- packages/ice/src/createService.ts | 4 +- packages/ice/src/esbuild/assets.ts | 4 +- packages/ice/src/getWatchEvents.ts | 2 +- .../src/middlewares/ssr/renderMiddleware.ts | 2 +- .../ice/src/middlewares/ssr/renderOnDemand.ts | 2 +- packages/ice/src/plugins/web/task.ts | 2 +- packages/ice/src/service/ServerRunner.ts | 2 +- packages/ice/src/service/preBundleDeps.ts | 2 +- packages/ice/src/service/runtimeGenerator.ts | 3 +- packages/ice/src/service/serverCompiler.ts | 2 +- packages/ice/src/service/webpackCompiler.ts | 2 +- packages/ice/src/test/defineJestConfig.ts | 2 +- packages/ice/src/types/index.ts | 2 +- packages/ice/src/types/plugin.ts | 4 +- packages/ice/src/types/userConfig.ts | 2 +- packages/ice/src/utils/getRouterBasename.ts | 2 +- packages/ice/src/utils/mergeTaskConfig.ts | 4 +- packages/ice/src/utils/runtimeEnv.ts | 2 +- packages/ice/templates/core/types.ts.ejs | 3 +- packages/ice/types.d.ts | 302 +++++++++--------- packages/ice/typings.d.ts | 1 + packages/plugin-antd/src/index.ts | 4 +- packages/plugin-auth/package.json | 3 +- packages/plugin-auth/runtime.d.ts | 1 + packages/plugin-auth/src/index.ts | 8 +- packages/plugin-auth/src/runtime/index.tsx | 2 +- packages/plugin-auth/src/types.ts | 2 +- packages/plugin-auth/types.d.ts | 1 + packages/plugin-css-assets-local/src/index.ts | 2 +- packages/plugin-fusion/src/index.ts | 2 +- packages/plugin-icestark/package.json | 10 +- packages/plugin-icestark/runtime.d.ts | 2 + packages/plugin-icestark/src/index.ts | 2 +- .../plugin-icestark/src/runtime/child.tsx | 4 +- .../plugin-icestark/src/runtime/framework.tsx | 4 +- packages/plugin-icestark/types.d.ts | 1 + packages/plugin-jsx-plus/src/index.ts | 2 +- packages/plugin-moment-locales/src/index.ts | 2 +- packages/plugin-pha/package.json | 3 +- packages/plugin-pha/runtime.d.ts | 1 + packages/plugin-pha/src/constants.ts | 2 +- packages/plugin-pha/src/generateManifest.ts | 2 +- packages/plugin-pha/src/index.ts | 5 +- packages/plugin-pha/types.d.ts | 1 + packages/plugin-rax-compat/src/index.ts | 2 +- packages/plugin-request/package.json | 3 +- packages/plugin-request/runtime.d.ts | 1 + packages/plugin-request/src/index.ts | 4 +- packages/plugin-request/src/runtime.ts | 2 +- packages/plugin-request/types.d.ts | 1 + packages/plugin-store/package.json | 3 +- packages/plugin-store/runtime.d.ts | 1 + packages/plugin-store/src/index.ts | 6 +- packages/plugin-store/src/runtime.tsx | 2 +- packages/plugin-store/types.d.ts | 1 + packages/runtime/package.json | 3 +- packages/runtime/router.d.ts | 1 + packages/runtime/types.d.ts | 1 + packages/webpack-config/package.json | 3 +- packages/webpack-config/types.d.ts | 1 + website/docs/guide/advanced/auth.md | 4 +- website/docs/guide/advanced/icestark.md | 6 +- website/docs/guide/advanced/request.md | 8 +- website/docs/guide/advanced/store.md | 2 +- website/docs/guide/basic/app.md | 2 +- website/docs/guide/plugins/plugin-dev.md | 12 +- 80 files changed, 295 insertions(+), 243 deletions(-) create mode 100644 .changeset/forty-doors-hear.md create mode 100644 packages/ice/typings.d.ts create mode 100644 packages/plugin-auth/runtime.d.ts create mode 100644 packages/plugin-auth/types.d.ts create mode 100644 packages/plugin-icestark/runtime.d.ts create mode 100644 packages/plugin-icestark/types.d.ts create mode 100644 packages/plugin-pha/runtime.d.ts create mode 100644 packages/plugin-pha/types.d.ts create mode 100644 packages/plugin-request/runtime.d.ts create mode 100644 packages/plugin-request/types.d.ts create mode 100644 packages/plugin-store/runtime.d.ts create mode 100644 packages/plugin-store/types.d.ts create mode 100644 packages/runtime/router.d.ts create mode 100644 packages/runtime/types.d.ts create mode 100644 packages/webpack-config/types.d.ts diff --git a/.changeset/forty-doors-hear.md b/.changeset/forty-doors-hear.md new file mode 100644 index 0000000000..8b9f17c835 --- /dev/null +++ b/.changeset/forty-doors-hear.md @@ -0,0 +1,18 @@ +--- +'@ice/plugin-css-assets-local': patch +'@ice/plugin-moment-locales': patch +'@ice/plugin-rax-compat': patch +'@ice/plugin-icestark': patch +'@ice/plugin-jsx-plus': patch +'@ice/plugin-request': patch +'@ice/webpack-config': patch +'@ice/plugin-fusion': patch +'@ice/plugin-store': patch +'@ice/plugin-antd': patch +'@ice/plugin-auth': patch +'@ice/plugin-pha': patch +'@ice/runtime': patch +'@ice/app': patch +--- + +fix: support types definition without specify esm folder diff --git a/examples/csr-project/src/app.tsx b/examples/csr-project/src/app.tsx index 7d475cf8de..ca63767920 100644 --- a/examples/csr-project/src/app.tsx +++ b/examples/csr-project/src/app.tsx @@ -1,5 +1,5 @@ import { defineAppConfig } from 'ice'; -import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; +import { defineAuthConfig } from '@ice/plugin-auth/types'; console.log('__LOG__'); console.warn('__WARN__'); diff --git a/examples/icestark-child/src/app.tsx b/examples/icestark-child/src/app.tsx index 4b52a1bc46..a5ce60b9fe 100644 --- a/examples/icestark-child/src/app.tsx +++ b/examples/icestark-child/src/app.tsx @@ -1,5 +1,5 @@ import { defineAppConfig } from 'ice'; -import { defineChildConfig } from '@ice/plugin-icestark/esm/types'; +import { defineChildConfig } from '@ice/plugin-icestark/types'; export const icestark = defineChildConfig(() => { return { @@ -29,4 +29,4 @@ export default defineAppConfig(() => ({ router: { basename, }, -})); \ No newline at end of file +})); diff --git a/examples/icestark-layout/src/app.tsx b/examples/icestark-layout/src/app.tsx index 37fecf18f0..d356844259 100644 --- a/examples/icestark-layout/src/app.tsx +++ b/examples/icestark-layout/src/app.tsx @@ -1,5 +1,5 @@ import { defineAppConfig } from 'ice'; -import { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types'; +import { defineFrameworkConfig } from '@ice/plugin-icestark/types'; import FrameworkLayout from '@/components/FrameworkLayout'; export const icestark = defineFrameworkConfig(() => ({ @@ -21,4 +21,4 @@ export default defineAppConfig(() => ({ app: { rootId: 'app', }, -})); \ No newline at end of file +})); diff --git a/examples/with-antd-mobile/src/store.tsx b/examples/with-antd-mobile/src/store.tsx index de7812fdff..c2a334f6b7 100644 --- a/examples/with-antd-mobile/src/store.tsx +++ b/examples/with-antd-mobile/src/store.tsx @@ -1,4 +1,4 @@ -import type { ComponentWithChildren } from '@ice/runtime/esm/types'; +import type { ComponentWithChildren } from '@ice/runtime/types'; import { useState } from 'react'; import constate from 'constate'; @@ -18,4 +18,4 @@ export const StoreProvider: ComponentWithChildren = ({ children }) => { export { useCounterContext, -}; \ No newline at end of file +}; diff --git a/examples/with-auth/src/app.tsx b/examples/with-auth/src/app.tsx index c52b1e0971..0df3324bbc 100644 --- a/examples/with-auth/src/app.tsx +++ b/examples/with-auth/src/app.tsx @@ -1,5 +1,5 @@ import { defineAppConfig, defineDataLoader, Link } from 'ice'; -import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; +import { defineAuthConfig } from '@ice/plugin-auth/types'; export default defineAppConfig(() => ({})); diff --git a/examples/with-pha/src/app.tsx b/examples/with-pha/src/app.tsx index a5ed7a8707..ddc79fcbf7 100644 --- a/examples/with-pha/src/app.tsx +++ b/examples/with-pha/src/app.tsx @@ -1,4 +1,4 @@ -import type { Manifest } from '@ice/plugin-pha/esm/types'; +import type { Manifest } from '@ice/plugin-pha/types'; export const phaManifest: Manifest = { title: 'test', diff --git a/examples/with-request/src/app.tsx b/examples/with-request/src/app.tsx index 1ae162ee12..c95d85f2b6 100644 --- a/examples/with-request/src/app.tsx +++ b/examples/with-request/src/app.tsx @@ -1,5 +1,5 @@ import { request as requestAPI, defineDataLoader } from 'ice'; -import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +import { defineRequestConfig } from '@ice/plugin-request/types'; export const dataLader = defineDataLoader(async () => { try { diff --git a/examples/with-store/src/app.tsx b/examples/with-store/src/app.tsx index 09ff4ef4a4..87805d7ca9 100644 --- a/examples/with-store/src/app.tsx +++ b/examples/with-store/src/app.tsx @@ -1,5 +1,5 @@ import { defineAppConfig, defineDataLoader } from 'ice'; -import { defineStoreConfig } from '@ice/plugin-store/esm/types'; +import { defineStoreConfig } from '@ice/plugin-store/types'; export const storeConfig = defineStoreConfig(async (appData) => { return { diff --git a/packages/ice/package.json b/packages/ice/package.json index 0c196c7d60..10dea01d17 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -17,7 +17,7 @@ "!esm/**/*.map", "templates", "openChrome.applescript", - "types.d.ts" + "*.d.ts" ], "engines": { "node": ">=14.19.0", diff --git a/packages/ice/src/commands/build.ts b/packages/ice/src/commands/build.ts index 168ada1e63..e9a986d331 100644 --- a/packages/ice/src/commands/build.ts +++ b/packages/ice/src/commands/build.ts @@ -4,9 +4,9 @@ import { getWebpackConfig } from '@ice/webpack-config'; import type { Context, TaskConfig } from 'build-scripts'; import webpack from '@ice/bundles/compiled/webpack/index.js'; import type { StatsError, Stats } from 'webpack'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type ora from '@ice/bundles/compiled/ora/index.js'; -import type { AppConfig } from '@ice/runtime/esm/types'; +import type { AppConfig } from '@ice/runtime/types'; import type { RenderMode } from '@ice/runtime'; import type { ServerCompiler, GetAppConfig, GetRoutesConfig, ExtendsPluginAPI, GetDataloaderConfig } from '../types/plugin.js'; import webpackCompiler from '../service/webpackCompiler.js'; diff --git a/packages/ice/src/commands/start.ts b/packages/ice/src/commands/start.ts index 448c0eba28..45b54871ff 100644 --- a/packages/ice/src/commands/start.ts +++ b/packages/ice/src/commands/start.ts @@ -3,7 +3,7 @@ import detectPort from 'detect-port'; import type { Configuration as DevServerConfiguration } from 'webpack-dev-server'; import type { Context, TaskConfig } from 'build-scripts'; import type { StatsError, Compiler, Configuration } from 'webpack'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { AppConfig, RenderMode } from '@ice/runtime'; import type ora from '@ice/bundles/compiled/ora/index.js'; import WebpackDevServer from '@ice/bundles/compiled/webpack-dev-server/lib/Server.js'; diff --git a/packages/ice/src/commands/test.ts b/packages/ice/src/commands/test.ts index c73b9861a7..2bf84c4343 100644 --- a/packages/ice/src/commands/test.ts +++ b/packages/ice/src/commands/test.ts @@ -1,5 +1,5 @@ import type { Context, TaskConfig } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type ora from '@ice/bundles/compiled/ora/index.js'; function test( diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index e0c6bf0666..7ab8d30259 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -1,7 +1,7 @@ import { createRequire } from 'module'; import trustCert from '@ice/bundles/compiled/trusted-cert/index.js'; import fse from 'fs-extra'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { UserConfigContext } from 'build-scripts'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import type { UserConfig } from './types/userConfig.js'; diff --git a/packages/ice/src/createService.ts b/packages/ice/src/createService.ts index 9981c5af43..90a9d8721f 100644 --- a/packages/ice/src/createService.ts +++ b/packages/ice/src/createService.ts @@ -3,8 +3,8 @@ import { fileURLToPath } from 'url'; import { createRequire } from 'module'; import { Context } from 'build-scripts'; import type { CommandArgs, CommandName } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; -import type { AppConfig } from '@ice/runtime/esm/types'; +import type { Config } from '@ice/webpack-config/types'; +import type { AppConfig } from '@ice/runtime/types'; import webpack from '@ice/bundles/compiled/webpack/index.js'; import fg from 'fast-glob'; import type { DeclarationData, PluginData, ExtendsPluginAPI, TargetDeclarationData } from './types'; diff --git a/packages/ice/src/esbuild/assets.ts b/packages/ice/src/esbuild/assets.ts index 1d35514ce6..1290eb8f21 100644 --- a/packages/ice/src/esbuild/assets.ts +++ b/packages/ice/src/esbuild/assets.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import * as mrmime from 'mrmime'; import fs from 'fs-extra'; import type { PluginBuild } from 'esbuild'; -import type { AssetsManifest } from '@ice/runtime/esm/types'; +import type { AssetsManifest } from '@ice/runtime/types'; export const ASSET_TYPES = [ // images @@ -91,4 +91,4 @@ const createAssetsPlugin = (compilationInfo: CompilationInfo | (() => Compilatio }, }); -export default createAssetsPlugin; \ No newline at end of file +export default createAssetsPlugin; diff --git a/packages/ice/src/getWatchEvents.ts b/packages/ice/src/getWatchEvents.ts index e62f627ff0..a5b3e3a4d4 100644 --- a/packages/ice/src/getWatchEvents.ts +++ b/packages/ice/src/getWatchEvents.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import type { Context } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { WatchEvent } from './types/plugin.js'; import { generateRoutesInfo, getRoutesDefination } from './routes.js'; import type Generator from './service/runtimeGenerator'; diff --git a/packages/ice/src/middlewares/ssr/renderMiddleware.ts b/packages/ice/src/middlewares/ssr/renderMiddleware.ts index 4557d7d83e..f8b057d705 100644 --- a/packages/ice/src/middlewares/ssr/renderMiddleware.ts +++ b/packages/ice/src/middlewares/ssr/renderMiddleware.ts @@ -4,7 +4,7 @@ import type { ServerContext, RenderMode } from '@ice/runtime'; // @ts-expect-error FIXME: esm type error import matchRoutes from '@ice/runtime/matchRoutes'; import type { TaskConfig } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { ExtendsPluginAPI } from '../../types/plugin.js'; import getRouterBasename from '../../utils/getRouterBasename.js'; import dynamicImport from '../../utils/dynamicImport.js'; diff --git a/packages/ice/src/middlewares/ssr/renderOnDemand.ts b/packages/ice/src/middlewares/ssr/renderOnDemand.ts index dcf4444840..90dfb7ea28 100644 --- a/packages/ice/src/middlewares/ssr/renderOnDemand.ts +++ b/packages/ice/src/middlewares/ssr/renderOnDemand.ts @@ -3,7 +3,7 @@ import type { ServerContext, RenderMode } from '@ice/runtime'; // @ts-expect-error FIXME: esm type error import matchRoutes from '@ice/runtime/matchRoutes'; import type { TaskConfig } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import getRouterBasename from '../../utils/getRouterBasename.js'; import warnOnHashRouterEnabled from '../../utils/warnOnHashRouterEnabled.js'; import type { UserConfig } from '../../types/userConfig.js'; diff --git a/packages/ice/src/plugins/web/task.ts b/packages/ice/src/plugins/web/task.ts index 320488c8f5..2853c5f88d 100644 --- a/packages/ice/src/plugins/web/task.ts +++ b/packages/ice/src/plugins/web/task.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import { createRequire } from 'module'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import { CACHE_DIR, RUNTIME_TMP_DIR } from '../../constant.js'; import { getRoutePathsFromCache } from '../../utils/getRoutePaths.js'; diff --git a/packages/ice/src/service/ServerRunner.ts b/packages/ice/src/service/ServerRunner.ts index 7986010538..4831d4fabb 100644 --- a/packages/ice/src/service/ServerRunner.ts +++ b/packages/ice/src/service/ServerRunner.ts @@ -5,7 +5,7 @@ import { getCompilerPlugins, getCSSModuleLocalIdent } from '@ice/webpack-config' import moduleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; import MagicString from '@ice/bundles/compiled/magic-string/index.js'; import type { TaskConfig } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { PluginBuild, OnResolveOptions, Plugin, OnLoadResult, OnResolveResult } from 'esbuild'; import emptyCSSPlugin from '../esbuild/emptyCSS.js'; import ignorePlugin from '../esbuild/ignore.js'; diff --git a/packages/ice/src/service/preBundleDeps.ts b/packages/ice/src/service/preBundleDeps.ts index 077a7c6aec..253d64da9a 100644 --- a/packages/ice/src/service/preBundleDeps.ts +++ b/packages/ice/src/service/preBundleDeps.ts @@ -5,7 +5,7 @@ import { esbuild } from '@ice/bundles'; import type { Plugin, BuildOptions } from 'esbuild'; import { resolve as resolveExports, legacy as resolveLegacy } from 'resolve.exports'; import moduleLexer from '@ice/bundles/compiled/es-module-lexer/index.js'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { TaskConfig } from 'build-scripts'; import { getCSSModuleLocalIdent } from '@ice/webpack-config'; import flattenId from '../utils/flattenId.js'; diff --git a/packages/ice/src/service/runtimeGenerator.ts b/packages/ice/src/service/runtimeGenerator.ts index 50d69ba5d0..c82941c963 100644 --- a/packages/ice/src/service/runtimeGenerator.ts +++ b/packages/ice/src/service/runtimeGenerator.ts @@ -90,10 +90,11 @@ export function generateDeclaration(exportList: Array<TargetDeclarationData | De specifiers.forEach((specifierStr) => { if (alias && alias[specifierStr]) { exportDeclarations.push(`${alias[specifierStr]}: ${specifierStr}${symbol}`); + exportNames.push(alias[specifierStr]); } else { exportDeclarations.push(`${specifierStr}${symbol}`); + exportNames.push(specifierStr); } - exportNames.push(specifierStr); }); } }); diff --git a/packages/ice/src/service/serverCompiler.ts b/packages/ice/src/service/serverCompiler.ts index 8c22b6a6a1..8c6cbe3952 100644 --- a/packages/ice/src/service/serverCompiler.ts +++ b/packages/ice/src/service/serverCompiler.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import { esbuild } from '@ice/bundles'; import fse from 'fs-extra'; import fg from 'fast-glob'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import type { TaskConfig } from 'build-scripts'; import { getCompilerPlugins, getCSSModuleLocalIdent } from '@ice/webpack-config'; diff --git a/packages/ice/src/service/webpackCompiler.ts b/packages/ice/src/service/webpackCompiler.ts index 8cb149634c..5dde9176f8 100644 --- a/packages/ice/src/service/webpackCompiler.ts +++ b/packages/ice/src/service/webpackCompiler.ts @@ -2,7 +2,7 @@ import webpackBundler from '@ice/bundles/compiled/webpack/index.js'; import type ora from '@ice/bundles/compiled/ora/index.js'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import type { TaskConfig, Context } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type webpack from 'webpack'; import type { Urls, ServerCompiler, GetAppConfig, GetRoutesConfig, ExtendsPluginAPI, GetDataloaderConfig } from '../types/plugin.js'; import formatWebpackMessages from '../utils/formatWebpackMessages.js'; diff --git a/packages/ice/src/test/defineJestConfig.ts b/packages/ice/src/test/defineJestConfig.ts index de7efcb7eb..358db55021 100644 --- a/packages/ice/src/test/defineJestConfig.ts +++ b/packages/ice/src/test/defineJestConfig.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import type { Config as JestConfig } from 'jest'; import fse from 'fs-extra'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import lodash from '@ice/bundles/compiled/lodash/index.js'; import getTaskConfig from './getTaskConfig.js'; diff --git a/packages/ice/src/types/index.ts b/packages/ice/src/types/index.ts index c329bdc2f2..b24b6ed76b 100644 --- a/packages/ice/src/types/index.ts +++ b/packages/ice/src/types/index.ts @@ -2,4 +2,4 @@ export * from './generator.js'; export * from './plugin.js'; export * from './userConfig.js'; // Export type webpack for same instance of webpack. -export type { Config, webpack } from '@ice/webpack-config/esm/types'; \ No newline at end of file +export type { Config, webpack } from '@ice/webpack-config/types'; diff --git a/packages/ice/src/types/plugin.ts b/packages/ice/src/types/plugin.ts index 2606bf96f1..dac0032dc9 100644 --- a/packages/ice/src/types/plugin.ts +++ b/packages/ice/src/types/plugin.ts @@ -3,8 +3,8 @@ import type { _Plugin, CommandArgs, TaskConfig } from 'build-scripts'; import type { Configuration, Stats, WebpackOptionsNormalized } from '@ice/bundles/compiled/webpack'; import type { esbuild } from '@ice/bundles'; import type { NestedRouteManifest } from '@ice/route-manifest'; -import type { Config } from '@ice/webpack-config/esm/types'; -import type { AppConfig, AssetsManifest } from '@ice/runtime/esm/types'; +import type { Config } from '@ice/webpack-config/types'; +import type { AppConfig, AssetsManifest } from '@ice/runtime/types'; import type ServerCompileTask from '../utils/ServerCompileTask.js'; import type { DeclarationData, TargetDeclarationData, AddRenderFile, AddTemplateFiles, ModifyRenderData, AddDataLoaderImport, Render } from './generator.js'; diff --git a/packages/ice/src/types/userConfig.ts b/packages/ice/src/types/userConfig.ts index 4740c1e867..53ed82b66f 100644 --- a/packages/ice/src/types/userConfig.ts +++ b/packages/ice/src/types/userConfig.ts @@ -2,7 +2,7 @@ import type { DefineRouteFunction, RouteItem } from '@ice/route-manifest'; import type { PluginList } from 'build-scripts'; import type { UnpluginOptions } from '@ice/bundles/compiled/unplugin/index.js'; import type { ProcessOptions } from '@ice/bundles'; -import type { Config, ModifyWebpackConfig, MinimizerOptions } from '@ice/webpack-config/esm/types'; +import type { Config, ModifyWebpackConfig, MinimizerOptions } from '@ice/webpack-config/types'; import type { OverwritePluginAPI } from './plugin'; interface SyntaxFeatures { diff --git a/packages/ice/src/utils/getRouterBasename.ts b/packages/ice/src/utils/getRouterBasename.ts index 6d3024d56d..c6feb76929 100644 --- a/packages/ice/src/utils/getRouterBasename.ts +++ b/packages/ice/src/utils/getRouterBasename.ts @@ -1,5 +1,5 @@ import type { AppConfig } from '@ice/runtime'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import type { TaskConfig } from 'build-scripts'; const getRouterBasename = (taskConfig: TaskConfig<Config>, appConfig: AppConfig) => { diff --git a/packages/ice/src/utils/mergeTaskConfig.ts b/packages/ice/src/utils/mergeTaskConfig.ts index e7ce124ec5..b7782a704d 100644 --- a/packages/ice/src/utils/mergeTaskConfig.ts +++ b/packages/ice/src/utils/mergeTaskConfig.ts @@ -1,5 +1,5 @@ import type { TaskConfig } from 'build-scripts'; -import type { Config } from '@ice/webpack-config/esm/types'; +import type { Config } from '@ice/webpack-config/types'; import lodash from '@ice/bundles/compiled/lodash/index.js'; const { mergeWith } = lodash; @@ -24,4 +24,4 @@ function mergeTaskConfig( }); } -export default mergeTaskConfig; \ No newline at end of file +export default mergeTaskConfig; diff --git a/packages/ice/src/utils/runtimeEnv.ts b/packages/ice/src/utils/runtimeEnv.ts index 972e85ea45..74f1eb3373 100644 --- a/packages/ice/src/utils/runtimeEnv.ts +++ b/packages/ice/src/utils/runtimeEnv.ts @@ -3,7 +3,7 @@ import * as fs from 'fs'; import * as dotenv from 'dotenv'; import { expand as dotenvExpand } from 'dotenv-expand'; import type { CommandArgs } from 'build-scripts'; -import type { AppConfig } from '@ice/runtime/esm/types'; +import type { AppConfig } from '@ice/runtime/types'; export interface Envs { [key: string]: string; diff --git a/packages/ice/templates/core/types.ts.ejs b/packages/ice/templates/core/types.ts.ejs index f35bde06e2..33a0cc6c60 100644 --- a/packages/ice/templates/core/types.ts.ejs +++ b/packages/ice/templates/core/types.ts.ejs @@ -1,5 +1,5 @@ -import type { AppConfig, RouteConfig as DefaultRouteConfig } from '@ice/runtime'; <%- routeConfigTypes.imports -%> +import type { AppConfig, RouteConfig as DefaultRouteConfig } from '@ice/runtime'; <% if (routeConfigTypes.imports) {-%> type ExtendsRouteConfig = <% if (routeConfigTypes.imports) { %><%- routeConfigTypes.exportNames.join(' & ') %><% } %>; @@ -15,4 +15,5 @@ type PageConfigDefinition = (context: PageConfigDefinitionContext) => PageConfig export type { AppConfig, PageConfig, + PageConfigDefinition, }; diff --git a/packages/ice/types.d.ts b/packages/ice/types.d.ts index 19f77d3629..ae71c88fd7 100644 --- a/packages/ice/types.d.ts +++ b/packages/ice/types.d.ts @@ -1,162 +1,166 @@ -// CSS modules -declare module '*.module.less' { - const classes: { [key: string]: string }; - export default classes; -} +declare global { + // CSS modules + declare module '*.module.less' { + const classes: { [key: string]: string }; + export default classes; + } -declare module '*.module.css' { - const classes: { [key: string]: string }; - export default classes; -} + declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; + } -declare module '*.module.scss' { - const classes: { [key: string]: string }; - export default classes; -} + declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; + } -// images -declare module '*.jpg' { - const src: string; - export default src; -} -declare module '*.jpeg' { - const src: string; - export default src; -} -declare module '*.png' { - const src: string; - export default src; -} -declare module '*.gif' { - const src: string; - export default src; -} -declare module '*.svg' { - const src: string; - export default src; -} -declare module '*.ico' { - const src: string; - export default src; -} -declare module '*.webp' { - const src: string; - export default src; -} -declare module '*.avif' { - const src: string; - export default src; -} + // images + declare module '*.jpg' { + const src: string; + export default src; + } + declare module '*.jpeg' { + const src: string; + export default src; + } + declare module '*.png' { + const src: string; + export default src; + } + declare module '*.gif' { + const src: string; + export default src; + } + declare module '*.svg' { + const src: string; + export default src; + } + declare module '*.ico' { + const src: string; + export default src; + } + declare module '*.webp' { + const src: string; + export default src; + } + declare module '*.avif' { + const src: string; + export default src; + } -// media -declare module '*.mp4' { - const src: string; - export default src; -} -declare module '*.webm' { - const src: string; - export default src; -} -declare module '*.ogg' { - const src: string; - export default src; -} -declare module '*.mp3' { - const src: string; - export default src; -} -declare module '*.wav' { - const src: string; - export default src; -} -declare module '*.flac' { - const src: string; - export default src; -} -declare module '*.aac' { - const src: string; - export default src; -} + // media + declare module '*.mp4' { + const src: string; + export default src; + } + declare module '*.webm' { + const src: string; + export default src; + } + declare module '*.ogg' { + const src: string; + export default src; + } + declare module '*.mp3' { + const src: string; + export default src; + } + declare module '*.wav' { + const src: string; + export default src; + } + declare module '*.flac' { + const src: string; + export default src; + } + declare module '*.aac' { + const src: string; + export default src; + } -// fonts -declare module '*.woff' { - const src: string; - export default src; -} -declare module '*.woff2' { - const src: string; - export default src; -} -declare module '*.eot' { - const src: string; - export default src; -} -declare module '*.ttf' { - const src: string; - export default src; -} -declare module '*.otf' { - const src: string; - export default src; -} + // fonts + declare module '*.woff' { + const src: string; + export default src; + } + declare module '*.woff2' { + const src: string; + export default src; + } + declare module '*.eot' { + const src: string; + export default src; + } + declare module '*.ttf' { + const src: string; + export default src; + } + declare module '*.otf' { + const src: string; + export default src; + } -// web worker -declare module '*?worker' { - const workerConstructor: { - new(): Worker; - }; - export default workerConstructor; -} -declare module '*?worker&inline' { - const workerConstructor: { - new(): Worker; - }; - export default workerConstructor; -} -declare module '*?sharedworker' { - const sharedWorkerConstructor: { - new(): SharedWorker; - }; - export default sharedWorkerConstructor; -} + // web worker + declare module '*?worker' { + const workerConstructor: { + new(): Worker; + }; + export default workerConstructor; + } + declare module '*?worker&inline' { + const workerConstructor: { + new(): Worker; + }; + export default workerConstructor; + } + declare module '*?sharedworker' { + const sharedWorkerConstructor: { + new(): SharedWorker; + }; + export default sharedWorkerConstructor; + } -// other -declare module '*.pdf' { - const src: string; - export default src; -} -declare module '*.txt' { - const src: string; - export default src; -} -declare module '*?url' { - const src: string; - export default src; -} -declare module '*?raw' { - const src: string; - export default src; -} + // other + declare module '*.pdf' { + const src: string; + export default src; + } + declare module '*.txt' { + const src: string; + export default src; + } + declare module '*?url' { + const src: string; + export default src; + } + declare module '*?raw' { + const src: string; + export default src; + } -declare namespace NodeJS { - export interface ProcessEnv { - ICE_CORE_NODE_ENV: 'development' | 'production'; - ICE_CORE_MODE: string; - ICE_CORE_ROUTER: 'true' | 'false'; - ICE_CORE_ERROR_BOUNDARY: 'true' | 'false'; - ICE_CORE_INITIAL_DATA: 'true' | 'false'; - ICE_CORE_DEV_PORT: number; + declare namespace NodeJS { + export interface ProcessEnv { + ICE_CORE_NODE_ENV: 'development' | 'production'; + ICE_CORE_MODE: string; + ICE_CORE_ROUTER: 'true' | 'false'; + ICE_CORE_ERROR_BOUNDARY: 'true' | 'false'; + ICE_CORE_INITIAL_DATA: 'true' | 'false'; + ICE_CORE_DEV_PORT: string; + } } -} -interface ImportMeta { - // The build target for ice.js - // Usually `web` or `node` or `weex` - target: string; + interface ImportMeta { + // The build target for ice.js + // Usually `web` or `node` or `weex` + target: string; - // The renderer for ice.js - renderer: 'client' | 'server'; + // The renderer for ice.js + renderer: 'client' | 'server'; - // ice.js defined env variables - env: Record<string, string>; + // ice.js defined env variables + env: Record<string, string>; + } } + +export * from './esm/types'; diff --git a/packages/ice/typings.d.ts b/packages/ice/typings.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/ice/typings.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/plugin-antd/src/index.ts b/packages/plugin-antd/src/index.ts index 38f1a850fd..b9a5ddf48a 100644 --- a/packages/plugin-antd/src/index.ts +++ b/packages/plugin-antd/src/index.ts @@ -1,5 +1,5 @@ import { createRequire } from 'module'; -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; import styleImportPlugin from '@ice/style-import'; interface PluginOptions { @@ -72,4 +72,4 @@ const plugin: Plugin<PluginOptions> = ({ theme, dark, compact, importStyle }) => }, }); -export default plugin; \ No newline at end of file +export default plugin; diff --git a/packages/plugin-auth/package.json b/packages/plugin-auth/package.json index 7235ac1998..a4c229bc97 100644 --- a/packages/plugin-auth/package.json +++ b/packages/plugin-auth/package.json @@ -35,7 +35,8 @@ "types": "./esm/index.d.ts", "files": [ "esm", - "!esm/**/*.map" + "!esm/**/*.map", + "*.d.ts" ], "devDependencies": { "@ice/app": "^3.1.1-beta.9", diff --git a/packages/plugin-auth/runtime.d.ts b/packages/plugin-auth/runtime.d.ts new file mode 100644 index 0000000000..72417e24df --- /dev/null +++ b/packages/plugin-auth/runtime.d.ts @@ -0,0 +1 @@ +export * from './esm/runtime'; diff --git a/packages/plugin-auth/src/index.ts b/packages/plugin-auth/src/index.ts index 08bc1751a6..33b48609ab 100644 --- a/packages/plugin-auth/src/index.ts +++ b/packages/plugin-auth/src/index.ts @@ -1,4 +1,4 @@ -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; const PLUGIN_NAME = '@ice/plugin-auth'; @@ -8,16 +8,16 @@ const plugin: Plugin = () => ({ // Register API: `import { useAuth, withAuth } from 'ice';` generator.addExport({ specifier: ['withAuth', 'useAuth'], - source: '@ice/plugin-auth/esm/runtime', + source: '@ice/plugin-auth/runtime', }); generator.addRouteTypes({ specifier: ['ConfigAuth'], type: true, - source: '@ice/plugin-auth/esm/types', + source: '@ice/plugin-auth/types', }); }, - runtime: `${PLUGIN_NAME}/esm/runtime`, + runtime: `${PLUGIN_NAME}/runtime`, }); export default plugin; diff --git a/packages/plugin-auth/src/runtime/index.tsx b/packages/plugin-auth/src/runtime/index.tsx index 70c8c85d93..cf0fda848d 100644 --- a/packages/plugin-auth/src/runtime/index.tsx +++ b/packages/plugin-auth/src/runtime/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { RuntimePlugin, AppProvider, RouteWrapper } from '@ice/runtime/esm/types'; +import type { RuntimePlugin, AppProvider, RouteWrapper } from '@ice/runtime/types'; import type { AuthConfig, AuthType, Auth } from '../types.js'; import { AuthProvider, useAuth, withAuth } from './Auth.js'; import type { InjectProps } from './Auth.js'; diff --git a/packages/plugin-auth/src/types.ts b/packages/plugin-auth/src/types.ts index dd5d8727ec..318a0a670d 100644 --- a/packages/plugin-auth/src/types.ts +++ b/packages/plugin-auth/src/types.ts @@ -1,5 +1,5 @@ import type * as React from 'react'; -import type { RouteConfig } from '@ice/runtime/esm/types'; +import type { RouteConfig } from '@ice/runtime/types'; export interface AuthConfig { initialAuth: { diff --git a/packages/plugin-auth/types.d.ts b/packages/plugin-auth/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/plugin-auth/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/plugin-css-assets-local/src/index.ts b/packages/plugin-css-assets-local/src/index.ts index 4b810451da..a072472695 100644 --- a/packages/plugin-css-assets-local/src/index.ts +++ b/packages/plugin-css-assets-local/src/index.ts @@ -1,4 +1,4 @@ -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; // @ts-expect-error cjs module error import ExtractCssAssetsWebpackPlugin from 'extract-css-assets-webpack-plugin'; import consola from 'consola'; diff --git a/packages/plugin-fusion/src/index.ts b/packages/plugin-fusion/src/index.ts index 08a8432a3f..ce16102745 100644 --- a/packages/plugin-fusion/src/index.ts +++ b/packages/plugin-fusion/src/index.ts @@ -1,5 +1,5 @@ import { createRequire } from 'module'; -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; import styleImportPlugin from '@ice/style-import'; interface PluginOptions { diff --git a/packages/plugin-icestark/package.json b/packages/plugin-icestark/package.json index c65a5d8044..6323a22449 100644 --- a/packages/plugin-icestark/package.json +++ b/packages/plugin-icestark/package.json @@ -9,7 +9,8 @@ "type": "module", "files": [ "esm", - "!esm/**/*.map" + "!esm/**/*.map", + "*.d.ts" ], "exports": { ".": { @@ -27,6 +28,11 @@ "import": "./esm/runtime/framework.js", "default": "./esm/runtime/framework.js" }, + "./types": { + "types": "./esm/types.d.ts", + "import": "./esm/types.js", + "default": "./esm/types.js" + }, "./esm/types": { "types": "./esm/types.d.ts", "import": "./esm/types.js", @@ -54,4 +60,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/packages/plugin-icestark/runtime.d.ts b/packages/plugin-icestark/runtime.d.ts new file mode 100644 index 0000000000..c490c5c819 --- /dev/null +++ b/packages/plugin-icestark/runtime.d.ts @@ -0,0 +1,2 @@ +export * from './esm/runtime/child'; +export * from './esm/runtime/framework'; diff --git a/packages/plugin-icestark/src/index.ts b/packages/plugin-icestark/src/index.ts index 5a270c651a..e8c14cf328 100644 --- a/packages/plugin-icestark/src/index.ts +++ b/packages/plugin-icestark/src/index.ts @@ -1,4 +1,4 @@ -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; interface PluginOptions { type: 'child' | 'framework'; diff --git a/packages/plugin-icestark/src/runtime/child.tsx b/packages/plugin-icestark/src/runtime/child.tsx index 94bc8d816a..11dc169362 100644 --- a/packages/plugin-icestark/src/runtime/child.tsx +++ b/packages/plugin-icestark/src/runtime/child.tsx @@ -1,5 +1,5 @@ import * as ReactDOM from 'react-dom/client'; -import type { RuntimePlugin } from '@ice/runtime/esm/types'; +import type { RuntimePlugin } from '@ice/runtime/types'; import type { LifecycleOptions } from '../types'; const runtime: RuntimePlugin<LifecycleOptions> = ({ setRender }, runtimeOptions) => { @@ -13,4 +13,4 @@ const runtime: RuntimePlugin<LifecycleOptions> = ({ setRender }, runtimeOptions) } }; -export default runtime; \ No newline at end of file +export default runtime; diff --git a/packages/plugin-icestark/src/runtime/framework.tsx b/packages/plugin-icestark/src/runtime/framework.tsx index 4cc706ee84..c801e1bf6a 100644 --- a/packages/plugin-icestark/src/runtime/framework.tsx +++ b/packages/plugin-icestark/src/runtime/framework.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { AppRouter, AppRoute } from '@ice/stark'; -import type { RuntimePlugin, AppRouterProps } from '@ice/runtime/esm/types'; +import type { RuntimePlugin, AppRouterProps } from '@ice/runtime/types'; import type { RouteInfo, AppConfig } from '../types'; const { useState, useEffect } = React; @@ -79,4 +79,4 @@ const runtime: RuntimePlugin = ({ getAppRouter, setAppRouter, appContext }) => { } }; -export default runtime; \ No newline at end of file +export default runtime; diff --git a/packages/plugin-icestark/types.d.ts b/packages/plugin-icestark/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/plugin-icestark/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/plugin-jsx-plus/src/index.ts b/packages/plugin-jsx-plus/src/index.ts index 7406a93fc3..735e7e3706 100644 --- a/packages/plugin-jsx-plus/src/index.ts +++ b/packages/plugin-jsx-plus/src/index.ts @@ -1,6 +1,6 @@ import path from 'path'; import { createRequire } from 'module'; -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; import { transformSync } from '@babel/core'; const require = createRequire(import.meta.url); diff --git a/packages/plugin-moment-locales/src/index.ts b/packages/plugin-moment-locales/src/index.ts index 4625a6de3a..e3cb1bdd16 100644 --- a/packages/plugin-moment-locales/src/index.ts +++ b/packages/plugin-moment-locales/src/index.ts @@ -1,4 +1,4 @@ -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; interface PluginOptions { locales: string | string[]; diff --git a/packages/plugin-pha/package.json b/packages/plugin-pha/package.json index 994e129b83..0649ba90d0 100644 --- a/packages/plugin-pha/package.json +++ b/packages/plugin-pha/package.json @@ -9,7 +9,8 @@ "files": [ "esm", "!esm/**/*.map", - "template" + "template", + "*.d.ts" ], "scripts": { "watch": "tsc -w", diff --git a/packages/plugin-pha/runtime.d.ts b/packages/plugin-pha/runtime.d.ts new file mode 100644 index 0000000000..72417e24df --- /dev/null +++ b/packages/plugin-pha/runtime.d.ts @@ -0,0 +1 @@ +export * from './esm/runtime'; diff --git a/packages/plugin-pha/src/constants.ts b/packages/plugin-pha/src/constants.ts index ad9b5b5b8b..a6a2c17a88 100644 --- a/packages/plugin-pha/src/constants.ts +++ b/packages/plugin-pha/src/constants.ts @@ -1,4 +1,4 @@ -import type { PluginData } from '@ice/app/esm/types'; +import type { PluginData } from '@ice/app/types'; import type { Context } from 'build-scripts'; // Keys of appConfig need transform to manifest. diff --git a/packages/plugin-pha/src/generateManifest.ts b/packages/plugin-pha/src/generateManifest.ts index 505d44e082..9e131c87d6 100644 --- a/packages/plugin-pha/src/generateManifest.ts +++ b/packages/plugin-pha/src/generateManifest.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import * as fs from 'fs'; -import type { GetAppConfig, GetDataloaderConfig, GetRoutesConfig, ServerCompiler } from '@ice/app/esm/types'; +import type { GetAppConfig, GetDataloaderConfig, GetRoutesConfig, ServerCompiler } from '@ice/app/types'; import type { Context } from 'build-scripts'; import { parseManifest, rewriteAppWorker, getAppWorkerUrl, getMultipleManifest, type ParseOptions } from './manifestHelpers.js'; import { getCompilerConfig } from './constants.js'; diff --git a/packages/plugin-pha/src/index.ts b/packages/plugin-pha/src/index.ts index 99e47b6048..e278f1e726 100644 --- a/packages/plugin-pha/src/index.ts +++ b/packages/plugin-pha/src/index.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import { fileURLToPath } from 'url'; import consola from 'consola'; import chalk from 'chalk'; -import type { Plugin, GetAppConfig, GetRoutesConfig, GetDataloaderConfig, ServerCompiler } from '@ice/app/esm/types'; +import type { Plugin, GetAppConfig, GetRoutesConfig, GetDataloaderConfig, ServerCompiler } from '@ice/app/types'; import generateManifest, { getAppWorkerPath } from './generateManifest.js'; import createPHAMiddleware from './phaMiddleware.js'; @@ -42,8 +42,9 @@ const plugin: Plugin<PluginOptions> = (options) => ({ generator.addRouteTypes({ specifier: ['PageConfig'], + alias: { PageConfig: 'PHAPageConfig' }, type: true, - source: '@ice/plugin-pha/esm/types', + source: '@ice/plugin-pha/types', }); // TODO: get route manifest by API. diff --git a/packages/plugin-pha/types.d.ts b/packages/plugin-pha/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/plugin-pha/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/plugin-rax-compat/src/index.ts b/packages/plugin-rax-compat/src/index.ts index 624ebb7d9d..d4571e4f37 100644 --- a/packages/plugin-rax-compat/src/index.ts +++ b/packages/plugin-rax-compat/src/index.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import { createRequire } from 'module'; -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; import type { RuleSetRule } from 'webpack'; import consola from 'consola'; import merge from 'lodash.merge'; diff --git a/packages/plugin-request/package.json b/packages/plugin-request/package.json index b112869ec6..9d4356c972 100644 --- a/packages/plugin-request/package.json +++ b/packages/plugin-request/package.json @@ -45,7 +45,8 @@ "types": "./esm/index.d.ts", "files": [ "esm", - "!esm/**/*.map" + "!esm/**/*.map", + "*.d.ts" ], "dependencies": { "ahooks": "^3.0.0", diff --git a/packages/plugin-request/runtime.d.ts b/packages/plugin-request/runtime.d.ts new file mode 100644 index 0000000000..72417e24df --- /dev/null +++ b/packages/plugin-request/runtime.d.ts @@ -0,0 +1 @@ +export * from './esm/runtime'; diff --git a/packages/plugin-request/src/index.ts b/packages/plugin-request/src/index.ts index b06820f4b0..bf7c80ce41 100644 --- a/packages/plugin-request/src/index.ts +++ b/packages/plugin-request/src/index.ts @@ -1,4 +1,4 @@ -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; import type { Request, Interceptors, InterceptorRequest, InterceptorResponse } from './types'; // @ts-ignore @@ -24,7 +24,7 @@ const plugin: Plugin<PluginRequestOptions | void> = () => ({ type: false, }); }, - runtime: `${PLUGIN_NAME}/esm/runtime`, + runtime: `${PLUGIN_NAME}/runtime`, staticRuntime: true, keepExports: ['requestConfig'], }); diff --git a/packages/plugin-request/src/runtime.ts b/packages/plugin-request/src/runtime.ts index 2bd703aa7a..5c4c8800f3 100644 --- a/packages/plugin-request/src/runtime.ts +++ b/packages/plugin-request/src/runtime.ts @@ -1,4 +1,4 @@ -import type { StaticRuntimePlugin } from '@ice/runtime/esm/types'; +import type { StaticRuntimePlugin } from '@ice/runtime/types'; import { createAxiosInstance, setAxiosInstance } from './request.js'; import type { RequestConfig } from './types'; diff --git a/packages/plugin-request/types.d.ts b/packages/plugin-request/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/plugin-request/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/plugin-store/package.json b/packages/plugin-store/package.json index 1116bab3f6..605aeb3e65 100644 --- a/packages/plugin-store/package.json +++ b/packages/plugin-store/package.json @@ -35,7 +35,8 @@ "types": "./esm/index.d.ts", "files": [ "esm", - "!esm/**/*.map" + "!esm/**/*.map", + "*.d.ts" ], "dependencies": { "@ice/store": "^2.0.3", diff --git a/packages/plugin-store/runtime.d.ts b/packages/plugin-store/runtime.d.ts new file mode 100644 index 0000000000..72417e24df --- /dev/null +++ b/packages/plugin-store/runtime.d.ts @@ -0,0 +1 @@ +export * from './esm/runtime'; diff --git a/packages/plugin-store/src/index.ts b/packages/plugin-store/src/index.ts index e53116d93f..67d899c505 100644 --- a/packages/plugin-store/src/index.ts +++ b/packages/plugin-store/src/index.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import type { Config, Plugin } from '@ice/app/esm/types'; +import type { Config, Plugin } from '@ice/app/types'; import micromatch from 'micromatch'; import fg from 'fast-glob'; import { PAGE_STORE_MODULE, PAGE_STORE_PROVIDER, PAGE_STORE_INITIAL_STATES } from './constants.js'; @@ -60,11 +60,11 @@ const plugin: Plugin<Options> = (options) => ({ // Export store api: createStore, createModel from `.ice/index.ts`. generator.addExport({ specifier: ['createStore', 'createModel'], - source: '@ice/plugin-store/esm/runtime', + source: '@ice/plugin-store/runtime', type: false, }); }, - runtime: `${PLUGIN_NAME}/esm/runtime`, + runtime: `${PLUGIN_NAME}/runtime`, }); const formatId = (id: string) => id.split(path.sep).join('/'); function exportStoreProviderPlugin({ pageDir, resetPageState }: { pageDir: string; resetPageState: boolean }): Config['transformPlugins'][0] { diff --git a/packages/plugin-store/src/runtime.tsx b/packages/plugin-store/src/runtime.tsx index ef521f99cd..e375712827 100644 --- a/packages/plugin-store/src/runtime.tsx +++ b/packages/plugin-store/src/runtime.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { RuntimePlugin, AppProvider, RouteWrapper } from '@ice/runtime/esm/types'; +import type { RuntimePlugin, AppProvider, RouteWrapper } from '@ice/runtime/types'; import { PAGE_STORE_INITIAL_STATES, PAGE_STORE_PROVIDER } from './constants.js'; import type { StoreConfig } from './types.js'; diff --git a/packages/plugin-store/types.d.ts b/packages/plugin-store/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/plugin-store/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 0787e0cf41..5ca2e6993d 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -20,7 +20,8 @@ "files": [ "esm", "!esm/**/*.map", - "templates" + "templates", + "*.d.ts" ], "author": "ICE", "license": "MIT", diff --git a/packages/runtime/router.d.ts b/packages/runtime/router.d.ts new file mode 100644 index 0000000000..89acae640c --- /dev/null +++ b/packages/runtime/router.d.ts @@ -0,0 +1 @@ +export * from './esm/router'; diff --git a/packages/runtime/types.d.ts b/packages/runtime/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/runtime/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/packages/webpack-config/package.json b/packages/webpack-config/package.json index ed861551f9..9bc8f4fcb5 100644 --- a/packages/webpack-config/package.json +++ b/packages/webpack-config/package.json @@ -12,7 +12,8 @@ }, "files": [ "esm", - "!esm/**/*.map" + "!esm/**/*.map", + "*.d.ts" ], "dependencies": { "@ice/bundles": "0.1.4", diff --git a/packages/webpack-config/types.d.ts b/packages/webpack-config/types.d.ts new file mode 100644 index 0000000000..8554e6cd41 --- /dev/null +++ b/packages/webpack-config/types.d.ts @@ -0,0 +1 @@ +export * from './esm/types'; diff --git a/website/docs/guide/advanced/auth.md b/website/docs/guide/advanced/auth.md index 1b1730b701..cb27dcaf8c 100644 --- a/website/docs/guide/advanced/auth.md +++ b/website/docs/guide/advanced/auth.md @@ -53,7 +53,7 @@ export default defineConfig(() => ({ 大多数情况下权限管理通常需要从服务端获取权限数据,然后在前端通过权限对比以此控制页面、操作等等权限行为。约定在 `src/app.ts` 中导出 `auth` 对象,该对象包含从服务端异步获取初始化的权限数据,并且约定最终返回格式为 `{ initialAuth: { [key: string]: boolean } }`。 ```ts title="src/app.ts" -import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; +import { defineAuthConfig } from '@ice/plugin-auth/types'; export const authConfig = defineAuthConfig(async () => { // 模拟请求权限数据 @@ -196,7 +196,7 @@ function Foo() { 支持自定义无权限时的展示组件,默认为 `<>No Auth</>` ```diff title="src/app.tsx" -import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; +import { defineAuthConfig } from '@ice/plugin-auth/types'; export const authConfig = defineAuthConfig(async () => { return { diff --git a/website/docs/guide/advanced/icestark.md b/website/docs/guide/advanced/icestark.md index fa1b76ba2a..934f1b9976 100644 --- a/website/docs/guide/advanced/icestark.md +++ b/website/docs/guide/advanced/icestark.md @@ -58,7 +58,7 @@ export default defineConfig(() => ({ 应用入口配置微应用相关信息: ```ts title="src/app.ts" -import { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types'; +import { defineFrameworkConfig } from '@ice/plugin-icestark/types'; import FrameworkLayout from '@/components/FrameworkLayout'; export const icestark = defineFrameworkConfig(() => ({ @@ -98,7 +98,7 @@ export default defineConfig(() => ({ 应用入口可以配置相关生命周期执行行为(可选): ```ts title="ice.config.mts" -import { defineChildConfig } from '@ice/plugin-icestark/esm/types'; +import { defineChildConfig } from '@ice/plugin-icestark/types'; export const icestark = defineChildConfig(() => ({ mount: () => { @@ -144,7 +144,7 @@ export default function FrameworkLayout({ children }) { ```ts title="src/app.ts" -import { defineFrameworkConfig } from '@ice/plugin-icestark/esm/types'; +import { defineFrameworkConfig } from '@ice/plugin-icestark/types'; import FrameworkLayout from '@/components/FrameworkLayout'; export const icestark = defineFrameworkConfig(() => ({ diff --git a/website/docs/guide/advanced/request.md b/website/docs/guide/advanced/request.md index b11b093eac..88aa63eee0 100644 --- a/website/docs/guide/advanced/request.md +++ b/website/docs/guide/advanced/request.md @@ -365,7 +365,7 @@ const { data, error, loading, request } = useRequest((id) => ({ 在实际项目中通常需要对请求进行全局统一的封装,例如配置请求的 baseURL、统一 header、拦截请求和响应等等,这时只需要在应用的的 appConfig 中进行配置即可。 ```ts title="src/app.tsx" -import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +import { defineRequestConfig } from '@ice/plugin-request/types'; export const requestConfig = defineRequestConfig({ // 可选的,全局设置 request 是否返回 response 对象,默认为 false @@ -412,7 +412,7 @@ export const requestConfig = defineRequestConfig({ 在某些复杂场景的应用中,我们也可以配置多个请求,每个配置请求都是单一的实例对象。 ```ts title="src/app.tsx" -import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +import { defineRequestConfig } from '@ice/plugin-request/types'; export const requestConfig = defineRequestConfig([ { @@ -492,7 +492,7 @@ const error = { 大部分情况下,前端代码里用到的后端接口写的都是相对路径如 `/api/getFoo.json`,然后访问不同环境时浏览器会根据当前域名发起对应的请求。如果域名跟实际请求的接口地址不一致,则需要通过 `request.baseURL` 来配置: ```ts title="src/app.tsx" -import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +import { defineRequestConfig } from '@ice/plugin-request/types'; export const requestConfig = defineRequestConfig({ baseURL: '//service.example.com/api', @@ -513,7 +513,7 @@ BASEURL=https://example.com/api 在 `src/app.tsx` 中配置 `request.baseURL`: ```ts title="src/app.tsx" -import { defineRequestConfig } from '@ice/plugin-request/esm/types'; +import { defineRequestConfig } from '@ice/plugin-request/types'; export const requestConfig = defineRequestConfig({ baseURL: process.env.BASEURL, diff --git a/website/docs/guide/advanced/store.md b/website/docs/guide/advanced/store.md index dfd6821552..638e1fb40c 100644 --- a/website/docs/guide/advanced/store.md +++ b/website/docs/guide/advanced/store.md @@ -251,7 +251,7 @@ export default createModel({ 我们可以在 `src/app.ts` 中设置两个 Model 初始状态: ```ts title="src/app.ts" -import { defineStoreConfig } from '@ice/plugin-store/esm/types'; +import { defineStoreConfig } from '@ice/plugin-store/types'; export const storeConfig = defineStoreConfig(async () => { // 模拟请求后端数据 diff --git a/website/docs/guide/basic/app.md b/website/docs/guide/basic/app.md index fe3cb8d337..017b7ce00f 100644 --- a/website/docs/guide/basic/app.md +++ b/website/docs/guide/basic/app.md @@ -103,7 +103,7 @@ export default defineAppConfig(() => ({ ```js import { defineAppConfig } from 'ice'; -import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; +import { defineAuthConfig } from '@ice/plugin-auth/types'; // 导出 auth 相关的能力,该能力由 @ice/plugin-auth 插件提供 export const authConfig = defineAuthConfig(() => { diff --git a/website/docs/guide/plugins/plugin-dev.md b/website/docs/guide/plugins/plugin-dev.md index e5c6259f0c..6cc8b17660 100644 --- a/website/docs/guide/plugins/plugin-dev.md +++ b/website/docs/guide/plugins/plugin-dev.md @@ -17,7 +17,7 @@ ice.js 提供了插件机制,在提供丰富的框架能力的基础上也可 ice.js 插件本质是一个 JS 模块,官方推荐以 TS 进行开发以获得良好的类型提示: ```ts -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; interface PluginOptions { id: string; @@ -40,7 +40,7 @@ export default plugin; 假设在项目根目录下有一个自定义插件 `my-plugin`: ```ts title="my-plugin.ts" -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; const plugin: Plugin = () => ({ name: 'my-plugin', @@ -112,7 +112,7 @@ export default defineConfig(() => ({ <TabItem value="index.ts" label="src/index.ts"> ```ts -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; const plugin: Plugin = () => ({ name: '@ice/my-plugin', @@ -129,7 +129,7 @@ export default plugin; <TabItem value="runtime.tsx" label="src/runtime.tsx"> ```tsx -import type { RuntimePlugin } from '@ice/runtime/esm/types'; +import type { RuntimePlugin } from '@ice/runtime/types'; const runtime: RuntimePlugin = async ({ appContext }) => { console.log(appContext); @@ -470,7 +470,7 @@ export default () => ({ 插件运行时可以定制框架的运行时能力: ```ts -import type { Plugin } from '@ice/app/esm/types'; +import type { Plugin } from '@ice/app/types'; const plugin: Plugin = () => ({ name: 'plugin-name' runtime: '/absolute/path/to/runtime', @@ -482,7 +482,7 @@ export default plugin; 框架运行时指向的文件地址为一个 JS 模块,源码阶段推荐用 TS 进行开发: ```ts -import type { RuntimePlugin } from '@ice/runtime/esm/types'; +import type { RuntimePlugin } from '@ice/runtime/types'; const runtime: RuntimePlugin = () => {}; export default runtime; From de520d66ec92f6357704972e120a7c67ab4bb913 Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Tue, 28 Feb 2023 15:11:35 +0800 Subject: [PATCH 12/21] fix: support unknown cli options registered by plugins (#5989) * fix: support unknown cli options registed by plugins * Update quick-shoes-matter.md --- .changeset/quick-shoes-matter.md | 5 +++++ packages/ice/bin/ice-cli.mjs | 23 ++++++++++++++++++++--- packages/ice/package.json | 3 ++- pnpm-lock.yaml | 3 ++- 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 .changeset/quick-shoes-matter.md diff --git a/.changeset/quick-shoes-matter.md b/.changeset/quick-shoes-matter.md new file mode 100644 index 0000000000..3bcaa061d2 --- /dev/null +++ b/.changeset/quick-shoes-matter.md @@ -0,0 +1,5 @@ +--- +'@ice/app': patch +--- + +fix: support unknown cli options registered by plugins diff --git a/packages/ice/bin/ice-cli.mjs b/packages/ice/bin/ice-cli.mjs index 2d2232460b..5136839bab 100755 --- a/packages/ice/bin/ice-cli.mjs +++ b/packages/ice/bin/ice-cli.mjs @@ -5,6 +5,7 @@ import semver from 'semver'; import fse from 'fs-extra'; import { fileURLToPath } from 'url'; import { program, Option } from 'commander'; +import yargsParser from 'yargs-parser'; // hijack webpack before import other modules import '../esm/requireHook.js'; import createService from '../esm/createService.js'; @@ -33,7 +34,10 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); .action(async ({ rootDir, ...commandArgs }, ctx) => { renamePlatformToTarget(commandArgs); process.env.NODE_ENV = 'production'; - const service = await createService({ rootDir, command: 'build', commandArgs }); + const service = await createService({ rootDir, command: 'build', commandArgs: { + ...parseUnknownOptions(ctx.args), + ...commandArgs, + } }); service.run(); }); @@ -53,10 +57,13 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); .option('--analyzer', 'visualize size of output files', false) .option('--https [https]', 'enable https', false) .option('--force', 'force remove cache directory', false) - .action(async ({ rootDir, ...commandArgs }) => { + .action(async ({ rootDir, ...commandArgs }, ctx) => { renamePlatformToTarget(commandArgs); process.env.NODE_ENV = 'development'; - const service = await createService({ rootDir, command: 'start', commandArgs }); + const service = await createService({ rootDir, command: 'start', commandArgs: { + ...parseUnknownOptions(ctx.args), + ...commandArgs + } }); service.run(); }); @@ -77,6 +84,16 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); } })(); +function parseUnknownOptions(args) { + let unKnownOptions = {}; + if (args.length > 0) { + unKnownOptions = yargsParser(args); + // Custom options do not support positional arguments. + delete unKnownOptions._; + } + return unKnownOptions; +} + // Rename `platform` to `target`, for compatibility. // For ice.js <3.0.3, using --platform to set build target. function renamePlatformToTarget(commandArgs) { diff --git a/packages/ice/package.json b/packages/ice/package.json index 10dea01d17..9aaf677de4 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -66,7 +66,8 @@ "regenerator-runtime": "^0.13.0", "resolve.exports": "^1.1.0", "semver": "^7.3.5", - "temp": "^0.9.4" + "temp": "^0.9.4", + "yargs-parser": "^21.1.1" }, "devDependencies": { "@types/babel__generator": "^7.6.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2fc17a7b11..8e6973b83b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1029,6 +1029,7 @@ importers: unplugin: ^0.9.0 webpack: ^5.73.0 webpack-dev-server: ^4.7.4 + yargs-parser: ^21.1.1 dependencies: '@babel/generator': 7.18.10 '@babel/parser': 7.18.10 @@ -1064,6 +1065,7 @@ importers: resolve.exports: 1.1.0 semver: 7.3.7 temp: 0.9.4 + yargs-parser: 21.1.1 devDependencies: '@types/babel__generator': 7.6.4 '@types/babel__traverse': 7.18.2 @@ -22314,7 +22316,6 @@ packages: /yargs-parser/21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: true /yargs/15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} From 36323ccbc79d80c73e70aea1d6418ba726e0fbe1 Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Wed, 1 Mar 2023 14:18:58 +0800 Subject: [PATCH 13/21] chore: version (#5995) * chore: version * Update spicy-dryers-melt.md --- .changeset/gentle-trains-cross.md | 2 +- .changeset/spicy-dryers-melt.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/gentle-trains-cross.md b/.changeset/gentle-trains-cross.md index f9da7f5554..252d0c7ab5 100644 --- a/.changeset/gentle-trains-cross.md +++ b/.changeset/gentle-trains-cross.md @@ -2,4 +2,4 @@ '@ice/plugin-pha': major --- -[fix] app-worker is not compiled when set a custom name +fix: app-worker is not compiled when set a custom name diff --git a/.changeset/spicy-dryers-melt.md b/.changeset/spicy-dryers-melt.md index d9030b9bb7..72f918389e 100644 --- a/.changeset/spicy-dryers-melt.md +++ b/.changeset/spicy-dryers-melt.md @@ -1,5 +1,5 @@ --- -'@ice/plugin-rax-compat': major +'@ice/plugin-rax-compat': patch --- -- [fix] Using runtime: 'classic' mode when source has declare `@jsx createElement` comment +fix: Using runtime: 'classic' mode when source has declare `@jsx createElement` comment From 98cb1e4b793530c8bb22c65b4ae93f9f149a1756 Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Wed, 1 Mar 2023 14:19:22 +0800 Subject: [PATCH 14/21] fix: remove dashed keys and using camelcase expansion (#5991) --- packages/ice/bin/ice-cli.mjs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ice/bin/ice-cli.mjs b/packages/ice/bin/ice-cli.mjs index 5136839bab..3e2f451d14 100755 --- a/packages/ice/bin/ice-cli.mjs +++ b/packages/ice/bin/ice-cli.mjs @@ -87,7 +87,11 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)); function parseUnknownOptions(args) { let unKnownOptions = {}; if (args.length > 0) { - unKnownOptions = yargsParser(args); + unKnownOptions = yargsParser(args, { + // Transform dashed arguments to camel case. + // e.g. --foo-bar => { fooBar: true }. + configuration: { 'strip-dashed': true }, + }); // Custom options do not support positional arguments. delete unKnownOptions._; } From c6b70bcec77056f678ae4d0ddae0d0acaabfc1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=93=E9=99=8C=E5=90=8C=E5=AD=A6?= <answershuto@gmail.com> Date: Wed, 1 Mar 2023 17:02:37 +0800 Subject: [PATCH 15/21] fix: should not build html file when distType has not html (#5994) * fix: should not build html file when distType has not html * chore: add default value for distType --- .changeset/cuddly-rocks-warn.md | 5 +++++ packages/runtime/src/runServerApp.tsx | 14 ++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 .changeset/cuddly-rocks-warn.md diff --git a/.changeset/cuddly-rocks-warn.md b/.changeset/cuddly-rocks-warn.md new file mode 100644 index 0000000000..50cf762cc5 --- /dev/null +++ b/.changeset/cuddly-rocks-warn.md @@ -0,0 +1,5 @@ +--- +'@ice/runtime': patch +--- + +fix: should not build html when distType has not html diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 7ac029e612..91211b3d23 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -70,14 +70,20 @@ export async function renderToEntry( const { value } = result; let jsOutput; - - const { distType } = renderOptions; - if (value && distType && distType.includes('javascript')) { + const { + distType = ['html'], + } = renderOptions; + if (value && distType.includes('javascript')) { jsOutput = await renderHTMLToJS(value); } + let htmlOutput; + if (distType.includes('html')) { + htmlOutput = result; + } + return { - ...result, + ...htmlOutput, jsOutput, }; } From dae91e218c92f30f03eedd9bfd033c0538bd159a Mon Sep 17 00:00:00 2001 From: luhc228 <luhengchang228@126.com> Date: Wed, 1 Mar 2023 18:00:59 +0800 Subject: [PATCH 16/21] fix: request plugin type and usage (#5992) * feat: add d.ts type * fix: request type * fix: useRequest usage * chore: changeset * feat: support useRequest param is string --- .changeset/nasty-lemons-agree.md | 6 ++++++ packages/plugin-request/hooks.d.ts | 1 + packages/plugin-request/request.d.ts | 1 + packages/plugin-request/src/hooks.ts | 19 ++++++++++++------- packages/plugin-request/src/index.ts | 4 ++-- packages/plugin-request/src/request.ts | 4 ++-- website/docs/guide/advanced/request.md | 18 ++++++++++++------ 7 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 .changeset/nasty-lemons-agree.md create mode 100644 packages/plugin-request/hooks.d.ts create mode 100644 packages/plugin-request/request.d.ts diff --git a/.changeset/nasty-lemons-agree.md b/.changeset/nasty-lemons-agree.md new file mode 100644 index 0000000000..a9eeaf77df --- /dev/null +++ b/.changeset/nasty-lemons-agree.md @@ -0,0 +1,6 @@ +--- +'@ice/plugin-request': patch +--- + +fix: request and useRequest type +fix: useRequest usage diff --git a/packages/plugin-request/hooks.d.ts b/packages/plugin-request/hooks.d.ts new file mode 100644 index 0000000000..82f45d2ab4 --- /dev/null +++ b/packages/plugin-request/hooks.d.ts @@ -0,0 +1 @@ +export * from './esm/hooks'; \ No newline at end of file diff --git a/packages/plugin-request/request.d.ts b/packages/plugin-request/request.d.ts new file mode 100644 index 0000000000..68fdaad5a5 --- /dev/null +++ b/packages/plugin-request/request.d.ts @@ -0,0 +1 @@ +export * from './esm/request'; diff --git a/packages/plugin-request/src/hooks.ts b/packages/plugin-request/src/hooks.ts index 3bc2f77aa7..c6e2d2a43b 100644 --- a/packages/plugin-request/src/hooks.ts +++ b/packages/plugin-request/src/hooks.ts @@ -1,28 +1,31 @@ import { useRequest as useAhooksRequest } from 'ahooks'; import type { Options, Result, Service, Plugin } from 'ahooks/lib/useRequest/src/types'; import type { AxiosRequestConfig } from 'axios'; -import request from './request.js'; +import { request } from './request.js'; interface RequestResult<R, P extends any[]> extends Result<R, P> { request: (...args: P) => Promise<R>; } -function useRequest<TData, TParams extends any[]>( - service: AxiosRequestConfig | Service<TData, TParams>, +export function useRequest<TData, TParams extends any[]>( + service: string | AxiosRequestConfig | Service<TData, TParams>, options?: Options<TData, TParams>, plugins?: Plugin<TData, TParams>[]) { let s: Service<TData, TParams>; if (isFunction(service)) { s = service as Service<TData, TParams>; + } else if (isString(service)) { + s = async (...extraOptions: TParams) => { + return request({ url: service, ...extraOptions }); + }; } else { const options = service as AxiosRequestConfig; s = async (...extraOptions: TParams) => { - const response = await request({ ...options, ...extraOptions }); - return response.data as TData; + return request({ ...options, ...extraOptions }); }; } const req = useAhooksRequest(s, { - // Note: + // Note: // ahooks/useRequest manual default to true. // ICE3/useRequest Default to manual request. manual: true, @@ -35,7 +38,9 @@ function useRequest<TData, TParams extends any[]>( } as RequestResult<TData, TParams>; } -export default useRequest; +function isString(str: any): str is string { + return typeof str === 'string'; +} function isFunction(fn: any): fn is Function { return typeof fn === 'function'; diff --git a/packages/plugin-request/src/index.ts b/packages/plugin-request/src/index.ts index bf7c80ce41..bc4be6e1df 100644 --- a/packages/plugin-request/src/index.ts +++ b/packages/plugin-request/src/index.ts @@ -13,13 +13,13 @@ const plugin: Plugin<PluginRequestOptions | void> = () => ({ // Add useRequest export for 'ice'. // import { useRequest } from 'ice'; generator.addExport({ - specifier: 'useRequest', + specifier: ['useRequest'], source: '@ice/plugin-request/hooks', type: false, }); // import { request } from 'ice'; generator.addExport({ - specifier: 'request', + specifier: ['request'], source: '@ice/plugin-request/request', type: false, }); diff --git a/packages/plugin-request/src/request.ts b/packages/plugin-request/src/request.ts index 39dba35347..2395da679e 100644 --- a/packages/plugin-request/src/request.ts +++ b/packages/plugin-request/src/request.ts @@ -96,7 +96,7 @@ const request = async function <T = any, D = any>(options: RequestConfig<D>): Pr console.error(error); throw error; } -}; +} as Request; // Provide aliases for supported request methods ['delete', 'get', 'head', 'options'].forEach((method) => { @@ -121,4 +121,4 @@ const request = async function <T = any, D = any>(options: RequestConfig<D>): Pr request.CancelToken = axios.CancelToken; request.isCancel = axios.isCancel; -export default request as Request; +export { request }; diff --git a/website/docs/guide/advanced/request.md b/website/docs/guide/advanced/request.md index 88aa63eee0..70e5a95f26 100644 --- a/website/docs/guide/advanced/request.md +++ b/website/docs/guide/advanced/request.md @@ -341,21 +341,27 @@ const { ```ts import { useRequest } from 'ice'; -// 用法 1:传入字符串 -const { data, error, loading } = useRequest('/api/repo'); +// 用法 1:传入请求地址 +const { data, error, loading, request } = useRequest('/api/repo'); -// 用法 2:传入配置对象 -const { data, error, loading } = useRequest({ +request(); + +// 用法 2:传入 Axios 配置对象 +const { data, error, loading, request } = useRequest({ url: '/api/repo', method: 'get', }); +request(); + // 用法 3:传入 service 函数 -const { data, error, loading, request } = useRequest((id) => ({ +const { data, error, loading, request } = useRequest((id) => Promise.resolve({ url: '/api/repo', method: 'get', data: { id }, -}); +})); + +request(); ``` 更多使用方式详见 [ahooks/useRequest](https://ahooks.js.org/zh-CN/hooks/use-request/index) From 7d7296975ca25c7f5a479b9c63f447deae1cd114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B0=B4=E6=BE=9C?= <shuilan.cj@taobao.com> Date: Wed, 1 Mar 2023 18:02:39 +0800 Subject: [PATCH 17/21] fix: stream render (#5956) * fix: resolve after render * fix: basename without / * fix: request path * fix: error order * feat: support pass manifest * feat: exports analyze * chore: update lock * fix: should keep state when rerender * feat: request ctx for suspense * fix: type * feat: support pass server data * revert: version * chore: add changeset * fix: lint * fix: type * chore: add comments * chore: add comments * chore: print error separately * refactor: support runtime public path * revert: export assets manifest --- .changeset/proud-wasps-work.md | 12 +++++ .../src/components/Comments.tsx | 3 +- .../src/pages/with-data-error.tsx | 5 +- packages/ice/package.json | 3 +- packages/ice/src/service/analyze.ts | 1 + .../ice/templates/core/entry.server.ts.ejs | 11 ++++- packages/runtime/src/Document.tsx | 4 +- packages/runtime/src/Suspense.tsx | 41 ++++++++++------ packages/runtime/src/runClientApp.tsx | 3 ++ packages/runtime/src/runServerApp.tsx | 48 ++++++++++++------- packages/runtime/src/server/streamRender.tsx | 3 ++ packages/runtime/src/types.ts | 4 +- pnpm-lock.yaml | 42 +++++++++++----- 13 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 .changeset/proud-wasps-work.md diff --git a/.changeset/proud-wasps-work.md b/.changeset/proud-wasps-work.md new file mode 100644 index 0000000000..700534e1df --- /dev/null +++ b/.changeset/proud-wasps-work.md @@ -0,0 +1,12 @@ +--- +'@ice/runtime': patch +'@ice/app': patch +--- + +feat: support pass server data +feat: support change public path runtime +feat: support get request ctx in suspense +feat: export code analyzer for reuse in other plugin +fix: suspense error handle +fix: duplicate data request in suspense csr +fix: support await render to response \ No newline at end of file diff --git a/examples/with-suspense-ssr/src/components/Comments.tsx b/examples/with-suspense-ssr/src/components/Comments.tsx index 97f3cab4c5..537315ab67 100644 --- a/examples/with-suspense-ssr/src/components/Comments.tsx +++ b/examples/with-suspense-ssr/src/components/Comments.tsx @@ -24,7 +24,8 @@ const fakeData = [ 'I like marshmallows', ]; -async function getData() { +async function getData(ctx) { + console.log(ctx); console.log('load comments'); await new Promise<any>((resolve) => { diff --git a/examples/with-suspense-ssr/src/pages/with-data-error.tsx b/examples/with-suspense-ssr/src/pages/with-data-error.tsx index 79531ee0a4..cdcd2e5e57 100644 --- a/examples/with-suspense-ssr/src/pages/with-data-error.tsx +++ b/examples/with-suspense-ssr/src/pages/with-data-error.tsx @@ -8,7 +8,7 @@ export default function Home() { <div> <h2>Home Page</h2> <SuspenseComments id="comments" fallback={<Loading />} /> - <Footer /> + <Footer id="footer" /> </div> ); } @@ -43,7 +43,7 @@ const fakeData = [ 'I like marshmallows', ]; -async function getCommentsData() { +async function getCommentsData(ctx) { console.log('load comments'); if (process.env.ICE_CORE_SSR === 'true') { @@ -51,6 +51,7 @@ async function getCommentsData() { setTimeout(() => reject('get data error'), 100); }); } else { + console.log('client ctx', ctx); await new Promise<any>((resolve) => { setTimeout(() => resolve(null), 100); }); diff --git a/packages/ice/package.json b/packages/ice/package.json index 9aaf677de4..1a1091cc78 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -6,7 +6,8 @@ "main": "./esm/index.js", "exports": { ".": "./esm/index.js", - "./types": "./esm/types/index.js" + "./types": "./esm/types/index.js", + "./analyze": "./esm/service/analyze.js" }, "bin": { "ice": "./bin/ice-cli.mjs" diff --git a/packages/ice/src/service/analyze.ts b/packages/ice/src/service/analyze.ts index 7081f65ec7..edccf922ef 100644 --- a/packages/ice/src/service/analyze.ts +++ b/packages/ice/src/service/analyze.ts @@ -219,6 +219,7 @@ interface FileOptions { type CachedRouteExports = { hash: string; exports: string[] }; +// Exports for other plugin to get exports info. export async function getFileExports(options: FileOptions): Promise<CachedRouteExports['exports']> { const { rootDir, file } = options; const filePath = path.join(rootDir, file); diff --git a/packages/ice/templates/core/entry.server.ts.ejs b/packages/ice/templates/core/entry.server.ts.ejs index 1f27ebfc86..9625ba7450 100644 --- a/packages/ice/templates/core/entry.server.ts.ejs +++ b/packages/ice/templates/core/entry.server.ts.ejs @@ -40,6 +40,8 @@ interface RenderOptions { routePath?: string; disableFallback?: boolean; distType?: DistType; + publicPath?: string; + serverData?: any; } export async function renderToHTML(requestContext, options: RenderOptions = {}) { @@ -55,7 +57,7 @@ export async function renderToResponse(requestContext, options: RenderOptions = setRuntimeEnv(renderMode); const mergedOptions = mergeOptions(options); - runtime.renderToResponse(requestContext, mergedOptions); + return runtime.renderToResponse(requestContext, mergedOptions); } <% if (jsOutput) { -%> @@ -69,7 +71,11 @@ export async function renderToEntry(requestContext, options: RenderOptions = {}) <% } -%> function mergeOptions(options) { - const { documentOnly, renderMode = 'SSR', basename, serverOnlyBasename, routePath, disableFallback, distType } = options; + const { documentOnly, renderMode = 'SSR', basename, serverOnlyBasename, routePath, disableFallback, distType, serverData, publicPath } = options; + + if (publicPath) { + assetsManifest.publicPath = publicPath; + } return { app, @@ -85,6 +91,7 @@ function mergeOptions(options) { disableFallback, routesConfig, distType, + serverData, <% if (runtimeOptions.exports) { -%> runtimeOptions: { <%- runtimeOptions.exports %> diff --git a/packages/runtime/src/Document.tsx b/packages/runtime/src/Document.tsx index 081a2d8c07..71c122bc67 100644 --- a/packages/runtime/src/Document.tsx +++ b/packages/runtime/src/Document.tsx @@ -146,7 +146,7 @@ export type DataType = (props: DataProps) => JSX.Element; // use app context separately export const Data: DataType = (props: DataProps) => { - const { routesData, documentOnly, matches, routesConfig, downgrade, renderMode } = useAppContext(); + const { routesData, documentOnly, matches, routesConfig, downgrade, renderMode, serverData } = useAppContext(); const appData = useAppData(); const { ScriptElement = 'script', @@ -163,6 +163,7 @@ export const Data: DataType = (props: DataProps) => { matchedIds, documentOnly, renderMode, + serverData, }; return ( @@ -191,7 +192,6 @@ export const Main: MainType = (props: React.HTMLAttributes<HTMLDivElement>) => { * merge assets info for matched route */ export function getPageAssets(matches: RouteMatch[], assetsManifest: AssetsManifest): string[] { - // TODO:publicPath from runtime const { pages, publicPath } = assetsManifest; let result = []; diff --git a/packages/runtime/src/Suspense.tsx b/packages/runtime/src/Suspense.tsx index 7838e5555d..90546fa789 100644 --- a/packages/runtime/src/Suspense.tsx +++ b/packages/runtime/src/Suspense.tsx @@ -1,5 +1,7 @@ import * as React from 'react'; import type { ReactNode } from 'react'; +import { useAppContext } from './AppContext.js'; +import type { RequestContext } from './types.js'; const LOADER = '__ICE_SUSPENSE_LOADER__'; const isClient = typeof window !== 'undefined' && 'onload' in window; @@ -13,40 +15,44 @@ interface SuspenseState { update: Function; } -type Request = () => Promise<any>; +type Request = (ctx: RequestContext) => Promise<any>; const SuspenseContext = React.createContext<SuspenseState | undefined>(undefined); export function useSuspenseData(request?: Request) { + const appContext = useAppContext(); + const { requestContext } = appContext; const suspenseState = React.useContext(SuspenseContext); const { data, done, promise, update, error, id } = suspenseState; - // use data from server side directly when hydrate. + // 1. Use data from server side directly when hydrate. if (isClient && (window[LOADER] as Map<string, any>) && window[LOADER].has(id)) { return window[LOADER].get(id); } - if (done) { - return data; - } - + // 2. Check data request error, if error throw it to react. if (error) { throw error; } - // request is pending. + // 3. If request is done, return data. + if (done) { + return data; + } + + // 4. If request is pending, throw the promise to react. if (promise) { throw promise; } - // when called by Data, request is null. + // 5. If no request, return null. if (!request) { return null; } - // send request and throw promise - const thenable = request(); + // 6. Create a promise for the request and throw it to react. + const thenable = request(requestContext); thenable.then((response) => { update({ @@ -79,16 +85,21 @@ export function withSuspense(Component) { return (props: SuspenseProps) => { const { fallback, id, ...componentProps } = props; - const suspenseState = { + const [suspenseState, updateSuspenseData] = React.useState({ id: id, data: null, done: false, promise: null, error: null, - update: (value) => { - Object.assign(suspenseState, value); - }, - }; + update, + }); + + function update(value) { + // For SSR, setState is not working, so here we need to update the state manually. + const newState = Object.assign(suspenseState, value); + // For CSR. + updateSuspenseData(newState); + } return ( <React.Suspense fallback={fallback || null}> diff --git a/packages/runtime/src/runClientApp.tsx b/packages/runtime/src/runClientApp.tsx index 1d6601a4ce..af594fe24b 100644 --- a/packages/runtime/src/runClientApp.tsx +++ b/packages/runtime/src/runClientApp.tsx @@ -55,6 +55,7 @@ export default async function runClientApp(options: RunClientAppOptions) { downgrade, documentOnly, renderMode, + serverData, } = windowContext; const requestContext = getRequestContext(window.location); @@ -79,6 +80,8 @@ export default async function runClientApp(options: RunClientAppOptions) { basename, routePath, renderMode, + requestContext, + serverData, }; const runtime = new Runtime(appContext, runtimeOptions); diff --git a/packages/runtime/src/runServerApp.tsx b/packages/runtime/src/runServerApp.tsx index 91211b3d23..4dfc0726b2 100644 --- a/packages/runtime/src/runServerApp.tsx +++ b/packages/runtime/src/runServerApp.tsx @@ -48,6 +48,7 @@ interface RenderOptions { }; runtimeOptions?: Record<string, any>; distType?: Array<'html' | 'javascript'>; + serverData?: any; } interface Piper { @@ -140,22 +141,31 @@ export async function renderToResponse(requestContext: ServerContext, renderOpti res.statusCode = 200; res.setHeader('Content-Type', 'text/html; charset=utf-8'); - // Send stream result to ServerResponse. - pipe(res, { - onShellError: async (err) => { - if (renderOptions.disableFallback) { - throw err; - } - - // downgrade to CSR. - console.error('PipeToResponse onShellError, downgrade to CSR.', err); - const result = await fallback(); - sendResult(res, result); - }, - onError: async (err) => { - // onError triggered after shell ready, should not downgrade to csr. - console.error('PipeToResponse error.', err); - }, + return new Promise<void>((resolve, reject) => { + // Send stream result to ServerResponse. + pipe(res, { + onShellError: async (err) => { + if (renderOptions.disableFallback) { + reject(err); + } + + // downgrade to CSR. + console.error('PipeToResponse onShellError, downgrade to CSR.'); + console.error(err); + const result = await fallback(); + sendResult(res, result); + resolve(); + }, + onError: async (err) => { + // onError triggered after shell ready, should not downgrade to csr + // and should not be throw to break the render process + console.error('PipeToResponse error.'); + console.error(err); + }, + onAllReady: () => { + resolve(); + }, + }); }); } } @@ -182,6 +192,7 @@ async function doRender(serverContext: ServerContext, renderOptions: RenderOptio runtimeModules, renderMode, runtimeOptions, + serverData, } = renderOptions; const finalBasename = serverOnlyBasename || basename; const location = getLocation(req.url); @@ -201,6 +212,8 @@ async function doRender(serverContext: ServerContext, renderOptions: RenderOptio assetsManifest, basename: finalBasename, matches: [], + requestContext, + serverData, }; const runtime = new Runtime(appContext, runtimeOptions); runtime.setAppRouter(DefaultAppRouter); @@ -350,6 +363,7 @@ function renderDocument(options: RenderDocumentOptions): RenderResult { Document, basename, routesConfig = {}, + serverData, } = renderOptions; const routesData = null; @@ -376,13 +390,13 @@ function renderDocument(options: RenderDocumentOptions): RenderResult { routePath, basename, downgrade, + serverData, }; const documentContext = { main: null, }; - const htmlStr = ReactDOMServer.renderToString( <AppContextProvider value={appContext}> <DocumentContextProvider value={documentContext}> diff --git a/packages/runtime/src/server/streamRender.tsx b/packages/runtime/src/server/streamRender.tsx index c1c50e3fa6..b17d58563e 100644 --- a/packages/runtime/src/server/streamRender.tsx +++ b/packages/runtime/src/server/streamRender.tsx @@ -25,6 +25,9 @@ export function renderToNodeStream( onError(error) { options?.onError && options?.onError(error); }, + onAllReady() { + options?.onAllReady && options?.onAllReady(); + }, }); }; } diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index c6e8364f61..f3bf661009 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -75,6 +75,7 @@ export interface RoutesData { export interface AppContext { appConfig: AppConfig; appData: any; + serverData?: any; assetsManifest?: AssetsManifest; routesData?: RoutesData; routesConfig?: RoutesConfig; @@ -88,11 +89,12 @@ export interface AppContext { basename?: string; downgrade?: boolean; renderMode?: string; + requestContext?: RequestContext; } export type WindowContext = Pick< AppContext, - 'appData' | 'routesData' | 'routesConfig' | 'routePath' | 'downgrade' | 'matchedIds' | 'documentOnly' | 'renderMode' + 'appData' | 'routesData' | 'routesConfig' | 'routePath' | 'downgrade' | 'matchedIds' | 'documentOnly' | 'renderMode' | 'serverData' >; export type Renderer = ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e6973b83b..7327963e4e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5965,7 +5965,6 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] requiresBuild: true dev: false optional: true @@ -5975,7 +5974,6 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] requiresBuild: true dev: false optional: true @@ -5985,7 +5983,6 @@ packages: engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] requiresBuild: true dev: false optional: true @@ -5995,7 +5992,6 @@ packages: engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] requiresBuild: true dev: false optional: true @@ -6564,6 +6560,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: false optional: true /@swc/core-darwin-arm64/1.3.3: @@ -6581,6 +6578,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: false optional: true /@swc/core-darwin-x64/1.3.3: @@ -6609,6 +6607,7 @@ packages: cpu: [arm] os: [linux] requiresBuild: true + dev: false optional: true /@swc/core-linux-arm-gnueabihf/1.3.3: @@ -6627,8 +6626,8 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [glibc] requiresBuild: true + dev: false optional: true /@swc/core-linux-arm64-gnu/1.3.3: @@ -6636,7 +6635,6 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [glibc] requiresBuild: true dev: true optional: true @@ -6646,8 +6644,8 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [musl] requiresBuild: true + dev: false optional: true /@swc/core-linux-arm64-musl/1.3.3: @@ -6655,7 +6653,6 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [musl] requiresBuild: true dev: true optional: true @@ -6665,8 +6662,8 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [glibc] requiresBuild: true + dev: false optional: true /@swc/core-linux-x64-gnu/1.3.3: @@ -6674,7 +6671,6 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [glibc] requiresBuild: true dev: true optional: true @@ -6684,8 +6680,8 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [musl] requiresBuild: true + dev: false optional: true /@swc/core-linux-x64-musl/1.3.3: @@ -6693,7 +6689,6 @@ packages: engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [musl] requiresBuild: true dev: true optional: true @@ -6704,6 +6699,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: false optional: true /@swc/core-win32-arm64-msvc/1.3.3: @@ -6723,6 +6719,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: false optional: true /@swc/core-win32-ia32-msvc/1.3.3: @@ -6742,6 +6739,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: false optional: true /@swc/core-win32-x64-msvc/1.3.3: @@ -6769,6 +6767,7 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.19 '@swc/core-win32-ia32-msvc': 1.3.19 '@swc/core-win32-x64-msvc': 1.3.19 + dev: false /@swc/core/1.3.3: resolution: {integrity: sha512-OGx3Qpw+czNSaea1ojP2X2wxrGtYicQxH1QnzX4F3rXGEcSUFIllmrae6iJHW91zS4SNcOocnQoRz1IYnrILYw==} @@ -9481,6 +9480,7 @@ packages: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} dependencies: is-what: 3.14.1 + dev: false /copy-text-to-clipboard/3.0.1: resolution: {integrity: sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==} @@ -10649,6 +10649,7 @@ packages: requiresBuild: true dependencies: prr: 1.0.1 + dev: false optional: true /error-ex/1.3.2: @@ -13007,6 +13008,7 @@ packages: engines: {node: '>=0.10.0'} hasBin: true requiresBuild: true + dev: false optional: true /image-size/1.0.2: @@ -13029,6 +13031,7 @@ packages: /immutable/4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} + dev: false /import-cwd/3.0.0: resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} @@ -13538,6 +13541,7 @@ packages: /is-what/3.14.1: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} + dev: false /is-whitespace-character/1.0.4: resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} @@ -14839,6 +14843,7 @@ packages: source-map: 0.6.1 transitivePeerDependencies: - supports-color + dev: false /leven/3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -15159,6 +15164,7 @@ packages: dependencies: pify: 4.0.1 semver: 5.7.1 + dev: false optional: true /make-dir/3.1.0: @@ -15537,6 +15543,7 @@ packages: sax: 1.2.4 transitivePeerDependencies: - supports-color + dev: false optional: true /negotiator/0.6.3: @@ -16013,6 +16020,7 @@ packages: /parse-node-version/1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} + dev: false /parse-numeric-range/1.3.0: resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} @@ -17859,6 +17867,7 @@ packages: /prr/1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + dev: false optional: true /pseudomap/1.0.2: @@ -18666,6 +18675,7 @@ packages: object-assign: 4.1.1 react: 17.0.2 scheduler: 0.20.2 + dev: false /react-dom/18.2.0_react@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} @@ -18779,6 +18789,7 @@ packages: /react-refresh/0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} + dev: false /react-router-config/5.1.1_2dl5roaqnyqqppnjni7uetnb3a: resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} @@ -18876,6 +18887,7 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 + dev: false /react/18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} @@ -19461,6 +19473,7 @@ packages: chokidar: 3.5.3 immutable: 4.1.0 source-map-js: 1.0.2 + dev: false /sax/1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} @@ -19477,6 +19490,7 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 + dev: false /scheduler/0.21.0: resolution: {integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==} @@ -20527,6 +20541,7 @@ packages: serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_esbuild@0.16.10 + dev: true /terser-webpack-plugin/5.3.6_peqg53aznxdu6ibj7wrnfxrfiq: resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} @@ -20552,6 +20567,7 @@ packages: serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_ncbsfugu56ddhgadp34k4kpsue + dev: true /terser-webpack-plugin/5.3.6_webpack@5.75.0: resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} @@ -21966,6 +21982,7 @@ packages: - '@swc/core' - esbuild - uglify-js + dev: true /webpack/5.75.0_ncbsfugu56ddhgadp34k4kpsue: resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} @@ -22005,6 +22022,7 @@ packages: - '@swc/core' - esbuild - uglify-js + dev: true /webpackbar/5.0.2_webpack@5.75.0: resolution: {integrity: sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==} From 1e9924729e5847c3ba258f1b7bc55e81cf202a1b Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Thu, 2 Mar 2023 10:21:29 +0800 Subject: [PATCH 18/21] chore: add changeset for @ice/bundles (#5998) --- .changeset/funny-monkeys-sit.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/funny-monkeys-sit.md diff --git a/.changeset/funny-monkeys-sit.md b/.changeset/funny-monkeys-sit.md new file mode 100644 index 0000000000..1b6bea578f --- /dev/null +++ b/.changeset/funny-monkeys-sit.md @@ -0,0 +1,5 @@ +--- +'@ice/bundles': patch +--- + +feat: add swc plugin of node transform From 5f72569cfefd6a4c4dd6b709c1970f52e953d816 Mon Sep 17 00:00:00 2001 From: ClarkXia <xiawenwu41@gmail.com> Date: Thu, 2 Mar 2023 11:49:59 +0800 Subject: [PATCH 19/21] fix: make sure config.splitChunks is not overwritten (#6001) --- packages/ice/src/config.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/ice/src/config.ts b/packages/ice/src/config.ts index 7ab8d30259..1803b19abd 100644 --- a/packages/ice/src/config.ts +++ b/packages/ice/src/config.ts @@ -348,8 +348,12 @@ const userConfig = [ name: 'splitChunks', validation: 'boolean', defaultValue: true, - setConfig: (config: Config, splitChunks: UserConfig['splitChunks']) => { - config.splitChunks = splitChunks; + setConfig: (config: Config, splitChunks: UserConfig['splitChunks'], context: UserConfigContext) => { + const { originalUserConfig } = context; + // Make sure config.splitChunks is not overwritten when codeSplitting is set. + if (!('codeSplitting' in originalUserConfig)) { + config.splitChunks = splitChunks; + } }, }, { From 03acb89886e7e76940333b713ed65c00214981cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=93=E9=99=8C=E5=90=8C=E5=AD=A6?= <answershuto@gmail.com> Date: Thu, 2 Mar 2023 11:56:29 +0800 Subject: [PATCH 20/21] Fix/component transform (#6000) * fix: Only the dom needs to be transformed, not the components * chore: add changeset --- .changeset/breezy-tips-boil.md | 5 +++++ packages/rax-compat/src/compat/element.ts | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .changeset/breezy-tips-boil.md diff --git a/.changeset/breezy-tips-boil.md b/.changeset/breezy-tips-boil.md new file mode 100644 index 0000000000..5cc8c9109e --- /dev/null +++ b/.changeset/breezy-tips-boil.md @@ -0,0 +1,5 @@ +--- +'rax-compat': patch +--- + +fix: Only the dom needs to be transformed, not the components diff --git a/packages/rax-compat/src/compat/element.ts b/packages/rax-compat/src/compat/element.ts index ac245e319e..2992339ded 100644 --- a/packages/rax-compat/src/compat/element.ts +++ b/packages/rax-compat/src/compat/element.ts @@ -18,7 +18,10 @@ export function createJSXElementFactory(factory: typeof ElementFactory) { delete rest.onDisappear; // Compat for props. - rest = transformProps(rest); + // Only the dom needs to be transformed, not the components. + if (typeof type === 'string') { + rest = transformProps(rest); + } // Compat for style unit. if (rest.style) { From e3ca513f564fd69a4e192fd694d71f833bc02224 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 13:55:59 +0800 Subject: [PATCH 21/21] chore: update versions (#5949) * chore: update versions * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md --------- Co-authored-by: ClarkXia <xiawenwu41@gmail.com> --- .changeset/breezy-tips-boil.md | 5 -- .changeset/cuddly-rocks-warn.md | 5 -- .changeset/eleven-spiders-yell.md | 5 -- .changeset/forty-doors-hear.md | 18 ---- .changeset/funny-monkeys-sit.md | 5 -- .changeset/gentle-teachers-cheer.md | 5 -- .changeset/gentle-trains-cross.md | 5 -- .changeset/nasty-lemons-agree.md | 6 -- .changeset/proud-glasses-retire.md | 5 -- .changeset/proud-wasps-work.md | 12 --- .changeset/quick-shoes-matter.md | 5 -- .changeset/spicy-dryers-melt.md | 5 -- .changeset/strong-socks-invite.md | 6 -- .changeset/wicked-numbers-approve.md | 5 -- packages/bundles/CHANGELOG.md | 6 ++ packages/bundles/package.json | 2 +- packages/ice/CHANGELOG.md | 14 ++++ packages/ice/package.json | 8 +- packages/plugin-antd/CHANGELOG.md | 8 +- packages/plugin-antd/package.json | 4 +- packages/plugin-auth/CHANGELOG.md | 8 +- packages/plugin-auth/package.json | 6 +- packages/plugin-css-assets-local/CHANGELOG.md | 6 ++ packages/plugin-css-assets-local/package.json | 4 +- packages/plugin-fusion/CHANGELOG.md | 7 ++ packages/plugin-fusion/package.json | 4 +- packages/plugin-icestark/CHANGELOG.md | 8 +- packages/plugin-icestark/package.json | 6 +- packages/plugin-jsx-plus/CHANGELOG.md | 6 ++ packages/plugin-jsx-plus/package.json | 4 +- packages/plugin-moment-locales/CHANGELOG.md | 8 +- packages/plugin-moment-locales/package.json | 4 +- packages/plugin-pha/CHANGELOG.md | 9 ++ packages/plugin-pha/package.json | 4 +- packages/plugin-rax-compat/CHANGELOG.md | 11 +++ packages/plugin-rax-compat/package.json | 8 +- packages/plugin-request/CHANGELOG.md | 8 ++ packages/plugin-request/package.json | 6 +- packages/plugin-store/CHANGELOG.md | 6 ++ packages/plugin-store/package.json | 6 +- packages/rax-compat/CHANGELOG.md | 6 ++ packages/rax-compat/package.json | 2 +- packages/runtime/CHANGELOG.md | 16 +++- packages/runtime/package.json | 2 +- packages/webpack-config/CHANGELOG.md | 9 ++ packages/webpack-config/package.json | 4 +- pnpm-lock.yaml | 82 +++++++------------ 47 files changed, 193 insertions(+), 191 deletions(-) delete mode 100644 .changeset/breezy-tips-boil.md delete mode 100644 .changeset/cuddly-rocks-warn.md delete mode 100644 .changeset/eleven-spiders-yell.md delete mode 100644 .changeset/forty-doors-hear.md delete mode 100644 .changeset/funny-monkeys-sit.md delete mode 100644 .changeset/gentle-teachers-cheer.md delete mode 100644 .changeset/gentle-trains-cross.md delete mode 100644 .changeset/nasty-lemons-agree.md delete mode 100644 .changeset/proud-glasses-retire.md delete mode 100644 .changeset/proud-wasps-work.md delete mode 100644 .changeset/quick-shoes-matter.md delete mode 100644 .changeset/spicy-dryers-melt.md delete mode 100644 .changeset/strong-socks-invite.md delete mode 100644 .changeset/wicked-numbers-approve.md diff --git a/.changeset/breezy-tips-boil.md b/.changeset/breezy-tips-boil.md deleted file mode 100644 index 5cc8c9109e..0000000000 --- a/.changeset/breezy-tips-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'rax-compat': patch ---- - -fix: Only the dom needs to be transformed, not the components diff --git a/.changeset/cuddly-rocks-warn.md b/.changeset/cuddly-rocks-warn.md deleted file mode 100644 index 50cf762cc5..0000000000 --- a/.changeset/cuddly-rocks-warn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/runtime': patch ---- - -fix: should not build html when distType has not html diff --git a/.changeset/eleven-spiders-yell.md b/.changeset/eleven-spiders-yell.md deleted file mode 100644 index ba7264facf..0000000000 --- a/.changeset/eleven-spiders-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/plugin-pha': patch ---- - -fix: support plugin-pha interface optional diff --git a/.changeset/forty-doors-hear.md b/.changeset/forty-doors-hear.md deleted file mode 100644 index 8b9f17c835..0000000000 --- a/.changeset/forty-doors-hear.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@ice/plugin-css-assets-local': patch -'@ice/plugin-moment-locales': patch -'@ice/plugin-rax-compat': patch -'@ice/plugin-icestark': patch -'@ice/plugin-jsx-plus': patch -'@ice/plugin-request': patch -'@ice/webpack-config': patch -'@ice/plugin-fusion': patch -'@ice/plugin-store': patch -'@ice/plugin-antd': patch -'@ice/plugin-auth': patch -'@ice/plugin-pha': patch -'@ice/runtime': patch -'@ice/app': patch ---- - -fix: support types definition without specify esm folder diff --git a/.changeset/funny-monkeys-sit.md b/.changeset/funny-monkeys-sit.md deleted file mode 100644 index 1b6bea578f..0000000000 --- a/.changeset/funny-monkeys-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/bundles': patch ---- - -feat: add swc plugin of node transform diff --git a/.changeset/gentle-teachers-cheer.md b/.changeset/gentle-teachers-cheer.md deleted file mode 100644 index b71b12b37e..0000000000 --- a/.changeset/gentle-teachers-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/plugin-fusion': patch ---- - -fix: compile non-js file when use plugin fusion diff --git a/.changeset/gentle-trains-cross.md b/.changeset/gentle-trains-cross.md deleted file mode 100644 index 252d0c7ab5..0000000000 --- a/.changeset/gentle-trains-cross.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/plugin-pha': major ---- - -fix: app-worker is not compiled when set a custom name diff --git a/.changeset/nasty-lemons-agree.md b/.changeset/nasty-lemons-agree.md deleted file mode 100644 index a9eeaf77df..0000000000 --- a/.changeset/nasty-lemons-agree.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@ice/plugin-request': patch ---- - -fix: request and useRequest type -fix: useRequest usage diff --git a/.changeset/proud-glasses-retire.md b/.changeset/proud-glasses-retire.md deleted file mode 100644 index b7428556b8..0000000000 --- a/.changeset/proud-glasses-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/plugin-pha': major ---- - -fix: fix data of prefetch decamelize diff --git a/.changeset/proud-wasps-work.md b/.changeset/proud-wasps-work.md deleted file mode 100644 index 700534e1df..0000000000 --- a/.changeset/proud-wasps-work.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@ice/runtime': patch -'@ice/app': patch ---- - -feat: support pass server data -feat: support change public path runtime -feat: support get request ctx in suspense -feat: export code analyzer for reuse in other plugin -fix: suspense error handle -fix: duplicate data request in suspense csr -fix: support await render to response \ No newline at end of file diff --git a/.changeset/quick-shoes-matter.md b/.changeset/quick-shoes-matter.md deleted file mode 100644 index 3bcaa061d2..0000000000 --- a/.changeset/quick-shoes-matter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/app': patch ---- - -fix: support unknown cli options registered by plugins diff --git a/.changeset/spicy-dryers-melt.md b/.changeset/spicy-dryers-melt.md deleted file mode 100644 index 72f918389e..0000000000 --- a/.changeset/spicy-dryers-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/plugin-rax-compat': patch ---- - -fix: Using runtime: 'classic' mode when source has declare `@jsx createElement` comment diff --git a/.changeset/strong-socks-invite.md b/.changeset/strong-socks-invite.md deleted file mode 100644 index bcd01e5acf..0000000000 --- a/.changeset/strong-socks-invite.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@ice/webpack-config': patch -'@ice/app': patch ---- - -feat: support code spliting strategy diff --git a/.changeset/wicked-numbers-approve.md b/.changeset/wicked-numbers-approve.md deleted file mode 100644 index 95c76d42dc..0000000000 --- a/.changeset/wicked-numbers-approve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@ice/app': patch ---- - -chore: update templates for unused imports diff --git a/packages/bundles/CHANGELOG.md b/packages/bundles/CHANGELOG.md index edb02a5b02..b7d71759df 100644 --- a/packages/bundles/CHANGELOG.md +++ b/packages/bundles/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.1.5 + +### Patch Changes + +- 1e992472: feat: add swc plugin of node transform + ## 0.1.4 - [fix] remove dependency of `@ice/swc-plugin-keep-platform` diff --git a/packages/bundles/package.json b/packages/bundles/package.json index 1972c73f64..05eae3f51c 100644 --- a/packages/bundles/package.json +++ b/packages/bundles/package.json @@ -1,6 +1,6 @@ { "name": "@ice/bundles", - "version": "0.1.4", + "version": "0.1.5", "license": "MIT", "author": "ICE", "description": "Basic dependencies for ice.", diff --git a/packages/ice/CHANGELOG.md b/packages/ice/CHANGELOG.md index c7f0b8a89a..28beb4a423 100644 --- a/packages/ice/CHANGELOG.md +++ b/packages/ice/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 3.1.2 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder +- 7d729697: feat: export code analyzer for reuse in other plugin +- de520d66: fix: support unknown cli options registered by plugins +- 071a627d: feat: support code spliting strategy +- 37c22e31: chore: update templates for unused imports +- Updated dependencies [071a627d] + - @ice/runtime@1.1.3 + - @ice/webpack-config@1.0.8 + - @ice/bundles@0.1.5 + ## 3.1.1 ### Patch Changes diff --git a/packages/ice/package.json b/packages/ice/package.json index 1a1091cc78..ff125fdca6 100644 --- a/packages/ice/package.json +++ b/packages/ice/package.json @@ -1,6 +1,6 @@ { "name": "@ice/app", - "version": "3.1.1", + "version": "3.1.2", "description": "provide scripts and configuration used by web framework ice", "type": "module", "main": "./esm/index.js", @@ -38,10 +38,10 @@ "@babel/parser": "7.18.10", "@babel/traverse": "7.18.10", "@babel/types": "7.18.10", - "@ice/bundles": "0.1.4", + "@ice/bundles": "0.1.5", "@ice/route-manifest": "1.0.0", - "@ice/runtime": "^1.1.2", - "@ice/webpack-config": "1.0.7", + "@ice/runtime": "^1.1.3", + "@ice/webpack-config": "1.0.8", "@swc/helpers": "0.4.14", "@types/express": "^4.17.14", "address": "^1.1.2", diff --git a/packages/plugin-antd/CHANGELOG.md b/packages/plugin-antd/CHANGELOG.md index 3f9aba2808..291de20e6e 100644 --- a/packages/plugin-antd/CHANGELOG.md +++ b/packages/plugin-antd/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.1 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.0 -- [feat] `plugin-antd` to support `themeConfig` \ No newline at end of file +- [feat] `plugin-antd` to support `themeConfig` diff --git a/packages/plugin-antd/package.json b/packages/plugin-antd/package.json index 2e304df08a..55ab1bcab7 100644 --- a/packages/plugin-antd/package.json +++ b/packages/plugin-antd/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-antd", - "version": "1.0.0", + "version": "1.0.1", "description": "ice.js plugin for use antd", "type": "module", "scripts": { @@ -16,7 +16,7 @@ "url": "https://github.com/alibaba/ice/tree/master/packages/plugin-antd" }, "devDependencies": { - "@ice/app": "^3.0.0" + "@ice/app": "^3.1.2" }, "dependencies": { "@ice/style-import": "^1.0.0" diff --git a/packages/plugin-auth/CHANGELOG.md b/packages/plugin-auth/CHANGELOG.md index 60cfdf3575..95559e287b 100644 --- a/packages/plugin-auth/CHANGELOG.md +++ b/packages/plugin-auth/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.1 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.0-rc.3 -- [feat] support initialize auth by app data. \ No newline at end of file +- [feat] support initialize auth by app data. diff --git a/packages/plugin-auth/package.json b/packages/plugin-auth/package.json index a4c229bc97..90dbce8ba2 100644 --- a/packages/plugin-auth/package.json +++ b/packages/plugin-auth/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-auth", - "version": "1.0.0", + "version": "1.0.1", "description": "", "license": "MIT", "type": "module", @@ -39,8 +39,8 @@ "*.d.ts" ], "devDependencies": { - "@ice/app": "^3.1.1-beta.9", - "@ice/runtime": "^1.1.2-beta.0", + "@ice/app": "^3.1.2", + "@ice/runtime": "^1.1.3", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "regenerator-runtime": "^0.13.9" diff --git a/packages/plugin-css-assets-local/CHANGELOG.md b/packages/plugin-css-assets-local/CHANGELOG.md index 3ef0834bf2..a2e25c3980 100644 --- a/packages/plugin-css-assets-local/CHANGELOG.md +++ b/packages/plugin-css-assets-local/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.1 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.0 - feat: init plugin diff --git a/packages/plugin-css-assets-local/package.json b/packages/plugin-css-assets-local/package.json index 24964c7327..9bffcfb8af 100644 --- a/packages/plugin-css-assets-local/package.json +++ b/packages/plugin-css-assets-local/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-css-assets-local", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "repository": { "type": "http", @@ -25,7 +25,7 @@ "consola": "^2.15.3" }, "devDependencies": { - "@ice/app": "^3.0.0" + "@ice/app": "^3.1.2" }, "scripts": { "watch": "tsc -w", diff --git a/packages/plugin-fusion/CHANGELOG.md b/packages/plugin-fusion/CHANGELOG.md index 40b878e173..67978d1620 100644 --- a/packages/plugin-fusion/CHANGELOG.md +++ b/packages/plugin-fusion/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.0.2 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder +- c7cfed91: fix: compile non-js file when use plugin fusion + ## 1.0.1 - [fix] error occur when use plugin without config `theme` diff --git a/packages/plugin-fusion/package.json b/packages/plugin-fusion/package.json index a2816b2d84..123a8448bb 100644 --- a/packages/plugin-fusion/package.json +++ b/packages/plugin-fusion/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-fusion", - "version": "1.0.1", + "version": "1.0.2", "description": "plugin for ICE while use fusion component", "license": "MIT", "type": "module", @@ -14,7 +14,7 @@ "@ice/style-import": "^1.0.0" }, "devDependencies": { - "@ice/app": "^3.0.0" + "@ice/app": "^3.1.2" }, "repository": { "type": "http", diff --git a/packages/plugin-icestark/CHANGELOG.md b/packages/plugin-icestark/CHANGELOG.md index e5fa9c01da..9a2c1bff21 100644 --- a/packages/plugin-icestark/CHANGELOG.md +++ b/packages/plugin-icestark/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.3 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.2 - [feat] support lifecycle of `bootstrap` for qiankun micro app. @@ -10,4 +16,4 @@ ## 1.0.0 -- [feat] plugin for micro-fontends, support both `Framework app` and `Sub app`. \ No newline at end of file +- [feat] plugin for micro-fontends, support both `Framework app` and `Sub app`. diff --git a/packages/plugin-icestark/package.json b/packages/plugin-icestark/package.json index 6323a22449..752456a9a4 100644 --- a/packages/plugin-icestark/package.json +++ b/packages/plugin-icestark/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-icestark", - "version": "1.0.2", + "version": "1.0.3", "description": "Easy use `icestark` in icejs.", "author": "ice-admin@alibaba-inc.com", "homepage": "", @@ -44,8 +44,8 @@ "@ice/stark-app": "^1.2.0" }, "devDependencies": { - "@ice/app": "^3.1.1-beta.9", - "@ice/runtime": "^1.1.2-beta.0", + "@ice/app": "^3.1.2", + "@ice/runtime": "^1.1.3", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0" }, diff --git a/packages/plugin-jsx-plus/CHANGELOG.md b/packages/plugin-jsx-plus/CHANGELOG.md index 7ebc5fe0e8..540edab108 100644 --- a/packages/plugin-jsx-plus/CHANGELOG.md +++ b/packages/plugin-jsx-plus/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.2 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.1 ### Patch Changes diff --git a/packages/plugin-jsx-plus/package.json b/packages/plugin-jsx-plus/package.json index 456b663ec1..2cb033f036 100644 --- a/packages/plugin-jsx-plus/package.json +++ b/packages/plugin-jsx-plus/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-jsx-plus", - "version": "1.0.1", + "version": "1.0.2", "description": "JSX Plus support for ice.js", "license": "MIT", "type": "module", @@ -28,7 +28,7 @@ "!esm/**/*.map" ], "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "^3.1.2", "@types/react": "^18.0.20", "@types/react-dom": "^18.0.6" }, diff --git a/packages/plugin-moment-locales/CHANGELOG.md b/packages/plugin-moment-locales/CHANGELOG.md index f74d4b0892..dc61264e17 100644 --- a/packages/plugin-moment-locales/CHANGELOG.md +++ b/packages/plugin-moment-locales/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.1 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.0 -- [feat] support config locales of moment. \ No newline at end of file +- [feat] support config locales of moment. diff --git a/packages/plugin-moment-locales/package.json b/packages/plugin-moment-locales/package.json index ddd6cae7a9..de9f62ac6d 100644 --- a/packages/plugin-moment-locales/package.json +++ b/packages/plugin-moment-locales/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-moment-locales", - "version": "1.0.0", + "version": "1.0.1", "description": "ice.js plugin for reduce moment locale size.", "type": "module", "scripts": { @@ -16,7 +16,7 @@ "url": "https://github.com/alibaba/ice/tree/master/packages/plugin-moment-locales" }, "devDependencies": { - "@ice/app": "^3.0.0" + "@ice/app": "^3.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/plugin-pha/CHANGELOG.md b/packages/plugin-pha/CHANGELOG.md index d24093dca5..7846dedbee 100644 --- a/packages/plugin-pha/CHANGELOG.md +++ b/packages/plugin-pha/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.0.0 + +### Major Changes + +- 6824ad63: fix: fix data of prefetch decamelize (break change) +- 73ae8bf4: fix: app-worker is not compiled when set a custom name +- 1c09e79e: fix: support plugin-pha interface optional +- 56fb406e: fix: support types definition without specify esm folder + ## 1.1.3 ### Patch Changes diff --git a/packages/plugin-pha/package.json b/packages/plugin-pha/package.json index 0649ba90d0..d80338dd2d 100644 --- a/packages/plugin-pha/package.json +++ b/packages/plugin-pha/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-pha", - "version": "1.1.3", + "version": "2.0.0", "description": "ice.js plugin for PHA.", "license": "MIT", "type": "module", @@ -25,7 +25,7 @@ "htmlparser2": "^8.0.1" }, "devDependencies": { - "@ice/app": "^3.1.1", + "@ice/app": "^3.1.2", "build-scripts": "^2.1.0", "esbuild": "^0.16.5", "webpack": "^5.73.0", diff --git a/packages/plugin-rax-compat/CHANGELOG.md b/packages/plugin-rax-compat/CHANGELOG.md index d168ab7a3e..09aa14ba0c 100644 --- a/packages/plugin-rax-compat/CHANGELOG.md +++ b/packages/plugin-rax-compat/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.1.4 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder +- efba0cc4: fix: Using runtime: 'classic' mode when source has declare `@jsx createElement` comment +- Updated dependencies [03acb898] +- Updated dependencies [1e992472] + - rax-compat@0.1.8 + - @ice/bundles@0.1.5 + ## 0.1.3 - [refactor] Using rax-compat/jsx-runtime to support rax components diff --git a/packages/plugin-rax-compat/package.json b/packages/plugin-rax-compat/package.json index bb9db8f9c5..28bdbe174f 100644 --- a/packages/plugin-rax-compat/package.json +++ b/packages/plugin-rax-compat/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-rax-compat", - "version": "0.1.3", + "version": "0.1.4", "description": "Provide rax compat support for ice.js", "license": "MIT", "type": "module", @@ -20,17 +20,17 @@ "dependencies": { "@babel/core": "^7.0.0", "@babel/plugin-proposal-export-default-from": "^7.18.9", - "@ice/bundles": "^0.1.0", + "@ice/bundles": "^0.1.5", "babel-plugin-transform-jsx-stylesheet": "1.0.6", "consola": "^2.15.3", "css": "^2.2.1", "lodash.merge": "^4.6.2", - "rax-compat": "^0.1.0", + "rax-compat": "^0.1.8", "style-unit": "^3.0.5", "stylesheet-loader": "^0.9.1" }, "devDependencies": { - "@ice/app": "^3.0.0", + "@ice/app": "^3.1.2", "webpack": "^5.73.0" }, "repository": { diff --git a/packages/plugin-request/CHANGELOG.md b/packages/plugin-request/CHANGELOG.md index fbc07028ec..281d222b44 100644 --- a/packages/plugin-request/CHANGELOG.md +++ b/packages/plugin-request/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGELOG +## 1.0.1 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder +- dae91e21: fix: request and useRequest type + fix: useRequest usage + ## 1.0.0 - The initial version of the plugin. diff --git a/packages/plugin-request/package.json b/packages/plugin-request/package.json index 9d4356c972..ba414e2483 100644 --- a/packages/plugin-request/package.json +++ b/packages/plugin-request/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-request", - "version": "1.0.0", + "version": "1.0.1", "description": "Request plugin for ice.", "license": "MIT", "type": "module", @@ -53,8 +53,8 @@ "axios": "^0.27.2" }, "devDependencies": { - "@ice/app": "^3.1.1-beta.9", - "@ice/runtime": "^1.1.2-beta.0", + "@ice/app": "^3.1.2", + "@ice/runtime": "^1.1.3", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "regenerator-runtime": "^0.13.9" diff --git a/packages/plugin-store/CHANGELOG.md b/packages/plugin-store/CHANGELOG.md index 0853996944..6080c5c591 100644 --- a/packages/plugin-store/CHANGELOG.md +++ b/packages/plugin-store/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 1.0.3 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder + ## 1.0.2 - fix: improve code compatibility diff --git a/packages/plugin-store/package.json b/packages/plugin-store/package.json index 605aeb3e65..b5e047ed08 100644 --- a/packages/plugin-store/package.json +++ b/packages/plugin-store/package.json @@ -1,6 +1,6 @@ { "name": "@ice/plugin-store", - "version": "1.0.2", + "version": "1.0.3", "description": "", "license": "MIT", "type": "module", @@ -44,8 +44,8 @@ "micromatch": "^4.0.5" }, "devDependencies": { - "@ice/app": "^3.1.1-beta.9", - "@ice/runtime": "^1.1.2-beta.0", + "@ice/app": "^3.1.2", + "@ice/runtime": "^1.1.3", "react": "^18.2.0", "react-dom": "^18.2.0", "@types/react": "^18.0.0", diff --git a/packages/rax-compat/CHANGELOG.md b/packages/rax-compat/CHANGELOG.md index 3dc1281c34..3a7bbdc8bb 100644 --- a/packages/rax-compat/CHANGELOG.md +++ b/packages/rax-compat/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.1.8 + +### Patch Changes + +- 03acb898: fix: Only the dom needs to be transformed, not the components + ## 0.1.7 - [refactor] jsx-runtime using react backend implementation. diff --git a/packages/rax-compat/package.json b/packages/rax-compat/package.json index 213e006b1f..f86a40d347 100644 --- a/packages/rax-compat/package.json +++ b/packages/rax-compat/package.json @@ -1,6 +1,6 @@ { "name": "rax-compat", - "version": "0.1.7", + "version": "0.1.8", "description": "Rax compatible mode, running rax project on the react runtime.", "files": [ "esm", diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index cece757dd1..fb96d9be99 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -1,16 +1,24 @@ # @ice/runtime -## 1.1.2 +## 1.1.3 ### Patch Changes -- 8eee4f0d: feat: export types +- c6b70bce: fix: should not build html when distType has not html +- 56fb406e: fix: support types definition without specify esm folder +- 7d729697: fix: SSR Suspense + - feat: support pass server data + - feat: support change public path runtime + - feat: support get request ctx in suspense + - fix: suspense error handle + - fix: duplicate data request in suspense csr + - fix: support await render to response -## 1.1.2-beta.0 +## 1.1.2 ### Patch Changes -- 7e38619b: feat: export types +- 8eee4f0d: feat: export types ## v1.1.1 diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 5ca2e6993d..4136c0f848 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@ice/runtime", - "version": "1.1.2", + "version": "1.1.3", "description": "Runtime module for ice.js", "type": "module", "types": "./esm/index.d.ts", diff --git a/packages/webpack-config/CHANGELOG.md b/packages/webpack-config/CHANGELOG.md index 18f8099445..13eab01d8e 100644 --- a/packages/webpack-config/CHANGELOG.md +++ b/packages/webpack-config/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.0.8 + +### Patch Changes + +- 56fb406e: fix: support types definition without specify esm folder +- 071a627d: feat: support code spliting strategy +- Updated dependencies [1e992472] + - @ice/bundles@0.1.5 + ## 1.0.7 ### Patch Changes diff --git a/packages/webpack-config/package.json b/packages/webpack-config/package.json index 9bc8f4fcb5..5e26634387 100644 --- a/packages/webpack-config/package.json +++ b/packages/webpack-config/package.json @@ -1,6 +1,6 @@ { "name": "@ice/webpack-config", - "version": "1.0.7", + "version": "1.0.8", "repository": "alibaba/ice", "bugs": "https://github.com/alibaba/ice/issues", "homepage": "https://v3.ice.work", @@ -16,7 +16,7 @@ "*.d.ts" ], "dependencies": { - "@ice/bundles": "0.1.4", + "@ice/bundles": "0.1.5", "@rollup/pluginutils": "^4.2.0", "browserslist": "^4.19.3", "consola": "^2.15.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7327963e4e..ec8f12a8ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -982,10 +982,10 @@ importers: '@babel/parser': 7.18.10 '@babel/traverse': 7.18.10 '@babel/types': 7.18.10 - '@ice/bundles': 0.1.4 + '@ice/bundles': 0.1.5 '@ice/route-manifest': 1.0.0 - '@ice/runtime': ^1.1.2 - '@ice/webpack-config': 1.0.7 + '@ice/runtime': ^1.1.3 + '@ice/webpack-config': 1.0.8 '@swc/helpers': 0.4.14 '@types/babel__generator': ^7.6.4 '@types/babel__traverse': ^7.17.1 @@ -1150,7 +1150,7 @@ importers: packages/plugin-antd: specifiers: - '@ice/app': ^3.0.0 + '@ice/app': ^3.1.2 '@ice/style-import': ^1.0.0 dependencies: '@ice/style-import': link:../style-import @@ -1159,8 +1159,8 @@ importers: packages/plugin-auth: specifiers: - '@ice/app': ^3.1.1-beta.9 - '@ice/runtime': ^1.1.2-beta.0 + '@ice/app': ^3.1.2 + '@ice/runtime': ^1.1.3 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 regenerator-runtime: ^0.13.9 @@ -1173,7 +1173,7 @@ importers: packages/plugin-css-assets-local: specifiers: - '@ice/app': ^3.0.0 + '@ice/app': ^3.1.2 consola: ^2.15.3 extract-css-assets-webpack-plugin: ^0.2.10 dependencies: @@ -1184,7 +1184,7 @@ importers: packages/plugin-fusion: specifiers: - '@ice/app': ^3.0.0 + '@ice/app': ^3.1.2 '@ice/style-import': ^1.0.0 dependencies: '@ice/style-import': link:../style-import @@ -1193,8 +1193,8 @@ importers: packages/plugin-icestark: specifiers: - '@ice/app': ^3.1.1-beta.9 - '@ice/runtime': ^1.1.2-beta.0 + '@ice/app': ^3.1.2 + '@ice/runtime': ^1.1.3 '@ice/stark': ^2.7.4 '@ice/stark-app': ^1.2.0 '@types/react': ^18.0.0 @@ -1211,7 +1211,7 @@ importers: packages/plugin-jsx-plus: specifiers: '@babel/core': ^7.19.1 - '@ice/app': ^3.0.0 + '@ice/app': ^3.1.2 '@types/react': ^18.0.20 '@types/react-dom': ^18.0.6 babel-plugin-transform-jsx-class: ^0.1.3 @@ -1270,13 +1270,13 @@ importers: packages/plugin-moment-locales: specifiers: - '@ice/app': ^3.0.0 + '@ice/app': ^3.1.2 devDependencies: '@ice/app': link:../ice packages/plugin-pha: specifiers: - '@ice/app': ^3.1.1 + '@ice/app': ^3.1.2 '@remix-run/router': ^1.0.3 build-scripts: ^2.1.0 chalk: ^4.0.0 @@ -1305,13 +1305,13 @@ importers: specifiers: '@babel/core': ^7.0.0 '@babel/plugin-proposal-export-default-from': ^7.18.9 - '@ice/app': ^3.0.0 - '@ice/bundles': ^0.1.0 + '@ice/app': ^3.1.2 + '@ice/bundles': ^0.1.5 babel-plugin-transform-jsx-stylesheet: 1.0.6 consola: ^2.15.3 css: ^2.2.1 lodash.merge: ^4.6.2 - rax-compat: ^0.1.0 + rax-compat: ^0.1.8 style-unit: ^3.0.5 stylesheet-loader: ^0.9.1 webpack: ^5.73.0 @@ -1332,8 +1332,8 @@ importers: packages/plugin-request: specifiers: - '@ice/app': ^3.1.1-beta.9 - '@ice/runtime': ^1.1.2-beta.0 + '@ice/app': ^3.1.2 + '@ice/runtime': ^1.1.3 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 ahooks: ^3.0.0 @@ -1351,8 +1351,8 @@ importers: packages/plugin-store: specifiers: - '@ice/app': ^3.1.1-beta.9 - '@ice/runtime': ^1.1.2-beta.0 + '@ice/app': ^3.1.2 + '@ice/runtime': ^1.1.3 '@ice/store': ^2.0.3 '@types/micromatch': ^4.0.2 '@types/react': ^18.0.0 @@ -1450,7 +1450,7 @@ importers: packages/webpack-config: specifiers: - '@ice/bundles': 0.1.4 + '@ice/bundles': 0.1.5 '@rollup/pluginutils': ^4.2.0 browserslist: ^4.19.3 consola: ^2.15.3 @@ -6560,7 +6560,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@swc/core-darwin-arm64/1.3.3: @@ -6578,7 +6577,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@swc/core-darwin-x64/1.3.3: @@ -6607,7 +6605,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm-gnueabihf/1.3.3: @@ -6627,7 +6624,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm64-gnu/1.3.3: @@ -6645,7 +6641,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-arm64-musl/1.3.3: @@ -6663,7 +6658,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-x64-gnu/1.3.3: @@ -6681,7 +6675,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@swc/core-linux-x64-musl/1.3.3: @@ -6699,7 +6692,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-arm64-msvc/1.3.3: @@ -6719,7 +6711,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-ia32-msvc/1.3.3: @@ -6739,7 +6730,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@swc/core-win32-x64-msvc/1.3.3: @@ -6767,7 +6757,6 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.19 '@swc/core-win32-ia32-msvc': 1.3.19 '@swc/core-win32-x64-msvc': 1.3.19 - dev: false /@swc/core/1.3.3: resolution: {integrity: sha512-OGx3Qpw+czNSaea1ojP2X2wxrGtYicQxH1QnzX4F3rXGEcSUFIllmrae6iJHW91zS4SNcOocnQoRz1IYnrILYw==} @@ -9453,8 +9442,8 @@ packages: engines: {node: '>=10'} hasBin: true dependencies: - is-text-path: 1.0.1 JSONStream: 1.3.5 + is-text-path: 1.0.1 lodash: 4.17.21 meow: 8.1.2 split2: 3.2.2 @@ -9480,7 +9469,6 @@ packages: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} dependencies: is-what: 3.14.1 - dev: false /copy-text-to-clipboard/3.0.1: resolution: {integrity: sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==} @@ -10649,7 +10637,6 @@ packages: requiresBuild: true dependencies: prr: 1.0.1 - dev: false optional: true /error-ex/1.3.2: @@ -13008,7 +12995,6 @@ packages: engines: {node: '>=0.10.0'} hasBin: true requiresBuild: true - dev: false optional: true /image-size/1.0.2: @@ -13031,7 +13017,6 @@ packages: /immutable/4.1.0: resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} - dev: false /import-cwd/3.0.0: resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} @@ -13541,7 +13526,6 @@ packages: /is-what/3.14.1: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} - dev: false /is-whitespace-character/1.0.4: resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} @@ -14843,7 +14827,6 @@ packages: source-map: 0.6.1 transitivePeerDependencies: - supports-color - dev: false /leven/3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} @@ -15164,7 +15147,6 @@ packages: dependencies: pify: 4.0.1 semver: 5.7.1 - dev: false optional: true /make-dir/3.1.0: @@ -15543,7 +15525,6 @@ packages: sax: 1.2.4 transitivePeerDependencies: - supports-color - dev: false optional: true /negotiator/0.6.3: @@ -16020,7 +16001,6 @@ packages: /parse-node-version/1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} - dev: false /parse-numeric-range/1.3.0: resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} @@ -17867,7 +17847,6 @@ packages: /prr/1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} - dev: false optional: true /pseudomap/1.0.2: @@ -18632,6 +18611,12 @@ packages: /react-dev-utils/12.0.1_hhrrucqyg4eysmfpujvov2ym5u: resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} engines: {node: '>=14'} + peerDependencies: + typescript: '>=2.7' + webpack: '>=4' + peerDependenciesMeta: + typescript: + optional: true dependencies: '@babel/code-frame': 7.18.6 address: 1.2.2 @@ -18662,9 +18647,7 @@ packages: transitivePeerDependencies: - eslint - supports-color - - typescript - vue-template-compiler - - webpack /react-dom/17.0.2_react@17.0.2: resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} @@ -18675,7 +18658,6 @@ packages: object-assign: 4.1.1 react: 17.0.2 scheduler: 0.20.2 - dev: false /react-dom/18.2.0_react@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} @@ -18789,7 +18771,6 @@ packages: /react-refresh/0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} - dev: false /react-router-config/5.1.1_2dl5roaqnyqqppnjni7uetnb3a: resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} @@ -18887,7 +18868,6 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - dev: false /react/18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} @@ -19473,7 +19453,6 @@ packages: chokidar: 3.5.3 immutable: 4.1.0 source-map-js: 1.0.2 - dev: false /sax/1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} @@ -19490,7 +19469,6 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - dev: false /scheduler/0.21.0: resolution: {integrity: sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==} @@ -20541,7 +20519,6 @@ packages: serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_esbuild@0.16.10 - dev: true /terser-webpack-plugin/5.3.6_peqg53aznxdu6ibj7wrnfxrfiq: resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} @@ -20567,7 +20544,6 @@ packages: serialize-javascript: 6.0.0 terser: 5.16.2 webpack: 5.75.0_ncbsfugu56ddhgadp34k4kpsue - dev: true /terser-webpack-plugin/5.3.6_webpack@5.75.0: resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} @@ -21982,7 +21958,6 @@ packages: - '@swc/core' - esbuild - uglify-js - dev: true /webpack/5.75.0_ncbsfugu56ddhgadp34k4kpsue: resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==} @@ -22022,7 +21997,6 @@ packages: - '@swc/core' - esbuild - uglify-js - dev: true /webpackbar/5.0.2_webpack@5.75.0: resolution: {integrity: sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==}