Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat:add online solution links for qiankun #2754

Open
wants to merge 7 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chilled-radios-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@qiankunjs/shared": patch
---

feat: add online solution links for qiankun
16 changes: 16 additions & 0 deletions .dumi/pages/error/CodeSnippet.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="__dumi-default-code-block">
<pre className="prism-code language-tsx">
{formattedLines}
</pre>
</div>

)
}
54 changes: 54 additions & 0 deletions .dumi/pages/error/codes/1.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#1: Application died in status NOT_MOUNTED: Target container with #container not existed after {props.getErrorCodeArg(0)} mounted!</h1>
<p>
This error thrown as the container DOM does not exist after the micro app is loaded. The possible reasons are:
</p>
<h4>
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.
</h4>
<div>
<h4>vue micro app:</h4>
<CodeSnippet>
{`
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);
}
`}
</CodeSnippet>
<h4>react micro app:</h4>
<CodeSnippet>
{ `
function render(props) {
const { container } = props;
ReactDOM.render(<App />, 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'));
}
`}
</CodeSnippet>
</div>
<h2>Explanation:</h2>
<p>
<a href="/qiankun/faq#application-died-in-status-not_mounted-target-container-with-container-not-existed-after-xxx-mounted">FAQ</a>
</p>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#2: You should not set multiply entry script in one entry html, but {props.getErrorCodeArg(0)} has at least 2 entry scripts</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/3.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#3: entry {props.getErrorCodeArg(0)} load failed as entry script {props.getErrorCodeArg(1)} load failed</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/4.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#4: entry {props.getErrorCodeArg(0)} response body is empty!</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/5.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#5: {props.getErrorCodeArg(0)} entry {props.getErrorCodeArg(1)} load failed as it not export lifecycles</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/6.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#6: You need to export lifecycle functions in {props.getErrorCodeArg(0)} entry</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/7.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#7: {props.getErrorCodeArg(0)} head element not existed while accessing document.head!</h1>
</>
)
}
10 changes: 10 additions & 0 deletions .dumi/pages/error/codes/8.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import CodeSnippet from '../CodeSnippet'

export default function ErrorCode1(props) {
return (
<>
<h1>#8: {props.getErrorCodeArg(0)} container {props.getErrorCodeArg(1)} element not ready while rebuilding!</h1>
</>
)
}
29 changes: 29 additions & 0 deletions .dumi/pages/error/index.tsx
Original file line number Diff line number Diff line change
@@ -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 ? (
<div>
<Comp errorCodeArgs={errorCodeArgs}
getErrorCodeArg={getErrorCodeArg}
errorCode={code} />
</div>
) : (<div>Please enter the error code</div>)

function getErrorCodeArg(index, argName) {
const missingArg = argName ? `(${argName})` : `(unknown)`;
return errorCodeArgs.length > index ? errorCodeArgs[index] : missingArg;
}
}
1 change: 1 addition & 0 deletions .dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ export default defineConfig({
theme: {
'@c-primary': '#6451AB',
},
styles: [`li a[href="/qiankun/error"],li a[href="/qiankun/error"] ~ * { display: none}]`],
});
11 changes: 9 additions & 2 deletions packages/loader/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ export async function loadEntry<T>(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,
);
}

Expand All @@ -139,7 +141,12 @@ export async function loadEntry<T>(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,
),
);
}
}
Expand Down Expand Up @@ -171,5 +178,5 @@ export async function loadEntry<T>(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);
}
7 changes: 4 additions & 3 deletions packages/qiankun/src/core/loadApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -94,7 +94,8 @@ export default async function loadApp<T extends ObjectType>(
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,
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 10 additions & 2 deletions packages/qiankun/src/error.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions packages/shared/src/error/QiankunError.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
12 changes: 10 additions & 2 deletions packages/shared/src/reporter/QiankunError.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}