From 7429bc90e777b2f39c3af97d4f5629c20e6b8feb Mon Sep 17 00:00:00 2001 From: guanjiameng Date: Tue, 24 Oct 2023 01:24:28 +0800 Subject: [PATCH 1/6] feat:add online solution links for qiankun --- .dumi/pages/error/CodeSnippet.tsx | 16 +++++++ .dumi/pages/error/codes/1.tsx | 54 +++++++++++++++++++++++ .dumi/pages/error/index.tsx | 29 ++++++++++++ .dumirc.ts | 1 + packages/shared/src/error/QiankunError.ts | 7 +++ 5 files changed, 107 insertions(+) create mode 100644 .dumi/pages/error/CodeSnippet.tsx create mode 100644 .dumi/pages/error/codes/1.tsx create mode 100644 .dumi/pages/error/index.tsx diff --git a/.dumi/pages/error/CodeSnippet.tsx b/.dumi/pages/error/CodeSnippet.tsx new file mode 100644 index 000000000..15d3639e5 --- /dev/null +++ b/.dumi/pages/error/CodeSnippet.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +export default function CodeSnippet(props) { + const lines = props.children.split('\n') + const firstTextualLine = lines.find(l => l.trim() !== l) + const numLeadingSpaces = firstTextualLine ? /([^\s])/.exec(firstTextualLine).index : 0 + const formattedLines = lines.map(line => line.slice(numLeadingSpaces)).filter((line, i) => line.length > 0 || i > 0).join('\n') + return ( +
+
+      {formattedLines}
+    
+
+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/1.tsx b/.dumi/pages/error/codes/1.tsx new file mode 100644 index 000000000..c2fc5ab05 --- /dev/null +++ b/.dumi/pages/error/codes/1.tsx @@ -0,0 +1,54 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#1: Application died in status NOT_MOUNTED: Target container with #container not existed after {props.getErrorCodeArg(0)} mounted!

+

+ This error thrown as the container DOM does not exist after the micro app is loaded. The possible reasons are: +

+

+ 1.The root id of the micro app conflicts with other DOM, and the solution is to modify the search range of the root id. +

+
+

vue micro app:

+ + {` + function render(props = {}) { + const { container } = props; + instance = new Vue({ + router, + store, + render: (h) => h(App), + }).$mount(container ? container.querySelector('#app') : '#app'); + } + export async function mount(props) { + render(props); + } + `} + +

react micro app:

+ + { ` + function render(props) { + const { container } = props; + ReactDOM.render(, container ? container.querySelector('#root') : document.querySelector('#root')); + } + export async function mount(props) { + render(props); + } + export async function unmount(props) { + const { container } = props; + ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root')); + } + `} + +
+

Explanation:

+

+ FAQ +

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/index.tsx b/.dumi/pages/error/index.tsx new file mode 100644 index 000000000..9f613219f --- /dev/null +++ b/.dumi/pages/error/index.tsx @@ -0,0 +1,29 @@ +/** + * sidebar: false + */ + +import React from 'react' +import { useLocation, useParams } from 'react-router-dom'; +import Error1 from './codes/1' +import { useSearchParams } from 'dumi'; +const r = require.context('./codes/', false, /\.tsx$/); + +export default function CodeSnippet() { + let [searchParams, setSearchParams] = useSearchParams(); + const code = searchParams.get('code'); + const Comp = code && r(`./${code}.tsx`).default; + const errorCodeArgs = searchParams.getAll('arg'); + + return code ? ( +
+ +
+ ) : (
请输入错误码code
) + + function getErrorCodeArg(index, argName) { + const missingArg = argName ? `(${argName})` : `(unknown)`; + return errorCodeArgs.length > index ? errorCodeArgs[index] : missingArg; + } +} \ No newline at end of file diff --git a/.dumirc.ts b/.dumirc.ts index 8d65d61bb..abd2534f7 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -58,4 +58,5 @@ export default defineConfig({ theme: { '@c-primary': '#6451AB', }, + styles: [`li a[href="/qiankun/error"],li a[href="/qiankun/error"] ~ * { display: none}]`], }); diff --git a/packages/shared/src/error/QiankunError.ts b/packages/shared/src/error/QiankunError.ts index a05d3a612..eacadc767 100644 --- a/packages/shared/src/error/QiankunError.ts +++ b/packages/shared/src/error/QiankunError.ts @@ -3,3 +3,10 @@ export class QiankunError extends Error { super(`[qiankun]: ${message}`); } } + +export class QiankunError2 extends Error { + constructor(code: number, message: string, ...args: string[]) { + super(`[qiankun #${code}]: ${message ? message + " " : ""}See https://qiankun.umijs.org/error/?code=${code}${args.length ? `&arg=${args.join("&arg=")}` : "" + }`); + } +} From 207308e64c8d4f7cd7b9f706a7d12518f52635eb Mon Sep 17 00:00:00 2001 From: guanjiameng Date: Mon, 30 Oct 2023 23:55:00 +0800 Subject: [PATCH 2/6] chore:update QiankunError --- packages/shared/src/error/QiankunError.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/shared/src/error/QiankunError.ts b/packages/shared/src/error/QiankunError.ts index eacadc767..e31b5c024 100644 --- a/packages/shared/src/error/QiankunError.ts +++ b/packages/shared/src/error/QiankunError.ts @@ -1,12 +1,13 @@ export class QiankunError extends Error { - constructor(message: string) { - super(`[qiankun]: ${message}`); - } -} - -export class QiankunError2 extends Error { constructor(code: number, message: string, ...args: string[]) { - super(`[qiankun #${code}]: ${message ? message + " " : ""}See https://qiankun.umijs.org/error/?code=${code}${args.length ? `&arg=${args.join("&arg=")}` : "" - }`); + let errorMessage = `[qiankun #${code}]: ${message ? message + ' ' : ''}`; + if (process.env.NODE_ENV === 'production') { + errorMessage += `See https://qiankun.umijs.org/error/?code=${code}${ + args.length ? `&arg=${args.join('&arg=')}` : '' + }`; + } else { + console.warn('args', ...args) + } + super(errorMessage); } } From 74bc9c8dea45ca3d231abf288c700de7eb52f765 Mon Sep 17 00:00:00 2001 From: Kuitos Date: Wed, 1 Nov 2023 12:05:18 +0800 Subject: [PATCH 3/6] Create chilled-radios-retire.md --- .changeset/chilled-radios-retire.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilled-radios-retire.md diff --git a/.changeset/chilled-radios-retire.md b/.changeset/chilled-radios-retire.md new file mode 100644 index 000000000..2c4f91db6 --- /dev/null +++ b/.changeset/chilled-radios-retire.md @@ -0,0 +1,5 @@ +--- +"@qiankunjs/shared": patch +--- + +feat: add online solution links for qiankun From 8ea88e305a6f11a819bf295efae68e2cf35ca080 Mon Sep 17 00:00:00 2001 From: gjmhandsome <40262743+gjmhandsome@users.noreply.github.com> Date: Mon, 6 Nov 2023 20:53:48 +0800 Subject: [PATCH 4/6] chore:format QiankunError --- packages/shared/src/error/QiankunError.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/error/QiankunError.ts b/packages/shared/src/error/QiankunError.ts index e31b5c024..9c4777461 100644 --- a/packages/shared/src/error/QiankunError.ts +++ b/packages/shared/src/error/QiankunError.ts @@ -6,7 +6,7 @@ export class QiankunError extends Error { args.length ? `&arg=${args.join('&arg=')}` : '' }`; } else { - console.warn('args', ...args) + console.warn('args', ...args); } super(errorMessage); } From 706c0a165149c1a38ffd0b90990358ec6c5cfd8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=8C=E7=A5=9E=E4=B8=80=E4=B8=8D=E5=B0=8F=E5=BF=83?= <40262743+gjmhandsome@users.noreply.github.com> Date: Wed, 8 Nov 2023 23:09:28 +0800 Subject: [PATCH 5/6] chore:adapt to old QiankunError usage --- packages/shared/src/error/QiankunError.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/error/QiankunError.ts b/packages/shared/src/error/QiankunError.ts index 9c4777461..322e2e571 100644 --- a/packages/shared/src/error/QiankunError.ts +++ b/packages/shared/src/error/QiankunError.ts @@ -1,7 +1,7 @@ export class QiankunError extends Error { - constructor(code: number, message: string, ...args: string[]) { + constructor(message: string, code?: number, ...args: string[]) { let errorMessage = `[qiankun #${code}]: ${message ? message + ' ' : ''}`; - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === 'production' && typeof(code) !== 'undefined') { errorMessage += `See https://qiankun.umijs.org/error/?code=${code}${ args.length ? `&arg=${args.join('&arg=')}` : '' }`; From 43a31d3b441d6f750d1439ad4f1e5c87b46a141e Mon Sep 17 00:00:00 2001 From: guanjiameng Date: Wed, 22 Nov 2023 21:58:40 +0800 Subject: [PATCH 6/6] chore:update all QiankunError usage --- .dumi/pages/error/codes/2.tsx | 10 ++++++++++ .dumi/pages/error/codes/3.tsx | 10 ++++++++++ .dumi/pages/error/codes/4.tsx | 10 ++++++++++ .dumi/pages/error/codes/5.tsx | 10 ++++++++++ .dumi/pages/error/codes/6.tsx | 10 ++++++++++ .dumi/pages/error/codes/7.tsx | 10 ++++++++++ .dumi/pages/error/codes/8.tsx | 10 ++++++++++ .dumi/pages/error/index.tsx | 2 +- packages/loader/src/index.ts | 11 +++++++++-- packages/qiankun/src/core/loadApp.ts | 7 ++++--- packages/qiankun/src/error.ts | 12 ++++++++++-- .../patchers/dynamicAppend/forStandardSandbox.ts | 9 ++++++++- packages/shared/src/error/QiankunError.ts | 13 +++++++++++++ packages/shared/src/reporter/QiankunError.ts | 4 ++-- 14 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 .dumi/pages/error/codes/2.tsx create mode 100644 .dumi/pages/error/codes/3.tsx create mode 100644 .dumi/pages/error/codes/4.tsx create mode 100644 .dumi/pages/error/codes/5.tsx create mode 100644 .dumi/pages/error/codes/6.tsx create mode 100644 .dumi/pages/error/codes/7.tsx create mode 100644 .dumi/pages/error/codes/8.tsx create mode 100644 packages/shared/src/error/QiankunError.ts diff --git a/.dumi/pages/error/codes/2.tsx b/.dumi/pages/error/codes/2.tsx new file mode 100644 index 000000000..8bc3bc787 --- /dev/null +++ b/.dumi/pages/error/codes/2.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#2: You should not set multiply entry script in one entry html, but {props.getErrorCodeArg(0)} has at least 2 entry scripts

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/3.tsx b/.dumi/pages/error/codes/3.tsx new file mode 100644 index 000000000..859b9b2ba --- /dev/null +++ b/.dumi/pages/error/codes/3.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#3: entry {props.getErrorCodeArg(0)} load failed as entry script {props.getErrorCodeArg(1)} load failed

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/4.tsx b/.dumi/pages/error/codes/4.tsx new file mode 100644 index 000000000..524fbe3a2 --- /dev/null +++ b/.dumi/pages/error/codes/4.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#4: entry {props.getErrorCodeArg(0)} response body is empty!

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/5.tsx b/.dumi/pages/error/codes/5.tsx new file mode 100644 index 000000000..b394824eb --- /dev/null +++ b/.dumi/pages/error/codes/5.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#5: {props.getErrorCodeArg(0)} entry {props.getErrorCodeArg(1)} load failed as it not export lifecycles

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/6.tsx b/.dumi/pages/error/codes/6.tsx new file mode 100644 index 000000000..da0e4f98d --- /dev/null +++ b/.dumi/pages/error/codes/6.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#6: You need to export lifecycle functions in {props.getErrorCodeArg(0)} entry

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/7.tsx b/.dumi/pages/error/codes/7.tsx new file mode 100644 index 000000000..2b849ec56 --- /dev/null +++ b/.dumi/pages/error/codes/7.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#7: {props.getErrorCodeArg(0)} head element not existed while accessing document.head!

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/codes/8.tsx b/.dumi/pages/error/codes/8.tsx new file mode 100644 index 000000000..faa4f2ba2 --- /dev/null +++ b/.dumi/pages/error/codes/8.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import CodeSnippet from '../CodeSnippet' + +export default function ErrorCode1(props) { + return ( + <> +

#8: {props.getErrorCodeArg(0)} container {props.getErrorCodeArg(1)} element not ready while rebuilding!

+ + ) +} \ No newline at end of file diff --git a/.dumi/pages/error/index.tsx b/.dumi/pages/error/index.tsx index 9f613219f..2cb925ed4 100644 --- a/.dumi/pages/error/index.tsx +++ b/.dumi/pages/error/index.tsx @@ -20,7 +20,7 @@ export default function CodeSnippet() { getErrorCodeArg={getErrorCodeArg} errorCode={code} /> - ) : (
请输入错误码code
) + ) : (
Please enter the error code
) function getErrorCodeArg(index, argName) { const missingArg = argName ? `(${argName})` : `(unknown)`; diff --git a/packages/loader/src/index.ts b/packages/loader/src/index.ts index 6f09dad70..de0de1c60 100644 --- a/packages/loader/src/index.ts +++ b/packages/loader/src/index.ts @@ -121,7 +121,9 @@ export async function loadEntry(entry: Entry, container: HTMLElement, opts: L if (isEntryScript(script)) { if (foundEntryScript) { throw new QiankunError( + 2, `You should not set multiply entry script in one entry html, but ${entry} has at least 2 entry scripts`, + entry, ); } @@ -139,7 +141,12 @@ export async function loadEntry(entry: Entry, container: HTMLElement, opts: L onEntryLoaded(); } else { entryScriptLoadedDeferred.reject( - new QiankunError(`entry ${entry} load failed as entry script ${script.src} load failed}`), + new QiankunError( + 3, + `entry ${entry} load failed as entry script ${script.src} load failed`, + entry, + script.src, + ), ); } } @@ -171,5 +178,5 @@ export async function loadEntry(entry: Entry, container: HTMLElement, opts: L return entryScriptLoadedDeferred.promise; } - throw new QiankunError(`entry ${entry} response body is empty!`); + throw new QiankunError(4, `entry ${entry} response body is empty!`, entry); } diff --git a/packages/qiankun/src/core/loadApp.ts b/packages/qiankun/src/core/loadApp.ts index 85b528b2e..16c1d276e 100644 --- a/packages/qiankun/src/core/loadApp.ts +++ b/packages/qiankun/src/core/loadApp.ts @@ -10,7 +10,7 @@ import { moduleResolver as defaultModuleResolver, transpileAssets, wrapFetchWith import { concat, isFunction, mergeWith } from 'lodash'; import type { ParcelConfigObject } from 'single-spa'; import getAddOns from '../addons'; -import { QiankunError } from '../error'; +import { QiankunError } from '@qiankunjs/shared'; import type { AppConfiguration, LifeCycleFn, LifeCycles, LoadableApp, MicroAppLifeCycles, ObjectType } from '../types'; import { getPureHTMLStringWithoutScripts, @@ -94,7 +94,8 @@ export default async function loadApp( await execHooksChain(toArray(beforeLoad), app, global); const lifecycles = await lifecyclesPromise; - if (!lifecycles) throw new QiankunError(`${appName} entry ${entry} load failed as it not export lifecycles`); + if (!lifecycles) + throw new QiankunError(5, `${appName} entry ${entry} load failed as it not export lifecycles`, appName, entry); const { bootstrap, mount, unmount, update } = getLifecyclesFromExports( lifecycles, appName, @@ -235,7 +236,7 @@ function getLifecyclesFromExports( return globalVariableExports; } - throw new QiankunError(`You need to export lifecycle functions in ${appName} entry`); + throw new QiankunError(6, `You need to export lifecycle functions in ${appName} entry`, appName); } function calcPublicPath(entry: string): string { diff --git a/packages/qiankun/src/error.ts b/packages/qiankun/src/error.ts index a05d3a612..9c4777461 100644 --- a/packages/qiankun/src/error.ts +++ b/packages/qiankun/src/error.ts @@ -1,5 +1,13 @@ export class QiankunError extends Error { - constructor(message: string) { - super(`[qiankun]: ${message}`); + constructor(code: number, message: string, ...args: string[]) { + let errorMessage = `[qiankun #${code}]: ${message ? message + ' ' : ''}`; + if (process.env.NODE_ENV === 'production') { + errorMessage += `See https://qiankun.umijs.org/error/?code=${code}${ + args.length ? `&arg=${args.join('&arg=')}` : '' + }`; + } else { + console.warn('args', ...args); + } + super(errorMessage); } } diff --git a/packages/sandbox/src/patchers/dynamicAppend/forStandardSandbox.ts b/packages/sandbox/src/patchers/dynamicAppend/forStandardSandbox.ts index d03bf0933..1fffc516f 100644 --- a/packages/sandbox/src/patchers/dynamicAppend/forStandardSandbox.ts +++ b/packages/sandbox/src/patchers/dynamicAppend/forStandardSandbox.ts @@ -78,7 +78,11 @@ function patchDocument(sandbox: Sandbox, getContainer: () => HTMLElement): Calla const container = getContainer(); const containerHeadElement = getContainerHeadElement(container); if (!containerHeadElement) { - throw new QiankunError(`${sandbox.name} head element not existed while accessing document.head!`); + throw new QiankunError( + 7, + `${sandbox.name} head element not existed while accessing document.head!`, + sandbox.name, + ); } return containerHeadElement; }; @@ -374,7 +378,10 @@ export function patchStandardSandbox( const containerHeadElement = getContainerHeadElement(container); if (!containerHeadElement) { throw new QiankunError( + 8, `${appName} container ${qiankunHeadTagName} element not ready while rebuilding!`, + appName, + qiankunHeadTagName, ); } return containerHeadElement; diff --git a/packages/shared/src/error/QiankunError.ts b/packages/shared/src/error/QiankunError.ts new file mode 100644 index 000000000..9c4777461 --- /dev/null +++ b/packages/shared/src/error/QiankunError.ts @@ -0,0 +1,13 @@ +export class QiankunError extends Error { + constructor(code: number, message: string, ...args: string[]) { + let errorMessage = `[qiankun #${code}]: ${message ? message + ' ' : ''}`; + if (process.env.NODE_ENV === 'production') { + errorMessage += `See https://qiankun.umijs.org/error/?code=${code}${ + args.length ? `&arg=${args.join('&arg=')}` : '' + }`; + } else { + console.warn('args', ...args); + } + super(errorMessage); + } +} diff --git a/packages/shared/src/reporter/QiankunError.ts b/packages/shared/src/reporter/QiankunError.ts index 322e2e571..9c4777461 100644 --- a/packages/shared/src/reporter/QiankunError.ts +++ b/packages/shared/src/reporter/QiankunError.ts @@ -1,7 +1,7 @@ export class QiankunError extends Error { - constructor(message: string, code?: number, ...args: string[]) { + constructor(code: number, message: string, ...args: string[]) { let errorMessage = `[qiankun #${code}]: ${message ? message + ' ' : ''}`; - if (process.env.NODE_ENV === 'production' && typeof(code) !== 'undefined') { + if (process.env.NODE_ENV === 'production') { errorMessage += `See https://qiankun.umijs.org/error/?code=${code}${ args.length ? `&arg=${args.join('&arg=')}` : '' }`;