mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: lazyload api
This commit is contained in:
3 files changed
+45
-38
No files matched your search
@@ -16,38 +16,10 @@ export { default as React } from 'react';
|
|||||||
export { default as ReactDOM } from 'react-dom/client';
|
export { default as ReactDOM } from 'react-dom/client';
|
||||||
export * from './misc/Page';
|
export * from './misc/Page';
|
||||||
export { initPageLoader } from './hydro';
|
export { initPageLoader } from './hydro';
|
||||||
|
export * from './lazyload';
|
||||||
|
import { load } from './lazyload';
|
||||||
|
|
||||||
const lazyModules = {};
|
export default load;
|
||||||
const features = {};
|
|
||||||
export default async function load(name: string) {
|
|
||||||
if (window.node_modules[name]) return window.node_modules[name];
|
|
||||||
if (name === 'echarts') return import('echarts');
|
|
||||||
if (name === 'moment') return import('moment');
|
|
||||||
if (!window.lazyloadMetadata?.[`${name}.lazy.js`]) throw new Error(`Module ${name} not found`);
|
|
||||||
if (lazyModules[name]) return lazyModules[name];
|
|
||||||
const tag = document.createElement('script');
|
|
||||||
tag.src = `/lazy/${window.lazyloadMetadata[`${name}.lazy.js`]}/${name}.lazy.js`;
|
|
||||||
lazyModules[name] = new Promise((resolve, reject) => {
|
|
||||||
tag.onerror = reject;
|
|
||||||
const timeout = setTimeout(reject, 30000);
|
|
||||||
window.lazyModuleResolver[name] = (item) => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
resolve(item);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
document.body.appendChild(tag);
|
|
||||||
return lazyModules[name];
|
|
||||||
}
|
|
||||||
export async function getFeatures(name: string) {
|
|
||||||
const legacy = Object.keys(window.externalModules).filter((i) => i === name || i.startsWith(`${name}@`));
|
|
||||||
const c = Object.keys(features).filter((i) => i === name || i.startsWith(`${name}@`));
|
|
||||||
return legacy.concat(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function provideFeature(name: string, content: string) {
|
|
||||||
features[name] = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventMap { }
|
export interface EventMap { }
|
||||||
|
|
||||||
import AutoComplete from './components/autocomplete';
|
import AutoComplete from './components/autocomplete';
|
||||||
@@ -57,7 +29,7 @@ import ProblemSelectAutoComplete from './components/autocomplete/ProblemSelectAu
|
|||||||
import UserSelectAutoComplete from './components/autocomplete/UserSelectAutoComplete';
|
import UserSelectAutoComplete from './components/autocomplete/UserSelectAutoComplete';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
load, AutoComplete, UserSelectAutoComplete, ProblemSelectAutoComplete, DomainSelectAutoComplete, CustomSelectAutoComplete,
|
AutoComplete, UserSelectAutoComplete, ProblemSelectAutoComplete, DomainSelectAutoComplete, CustomSelectAutoComplete,
|
||||||
};
|
};
|
||||||
export function addPage(page: import('./misc/Page').Page | (() => Promise<void> | void)) {
|
export function addPage(page: import('./misc/Page').Page | (() => Promise<void> | void)) {
|
||||||
window.Hydro.extraPages.push(page);
|
window.Hydro.extraPages.push(page);
|
||||||
@@ -82,7 +54,7 @@ import ReactDOM from 'react-dom/client';
|
|||||||
import * as redux from 'react-redux';
|
import * as redux from 'react-redux';
|
||||||
|
|
||||||
const modules = {
|
const modules = {
|
||||||
_, $, React, redux, ReactDOM, load,
|
_, $, React, redux, ReactDOM,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { load as loadModule } from '@hydrooj/ui-default';
|
import { getFeatures, load as loadModule } from '../../lazyload';
|
||||||
|
|
||||||
let loaded;
|
let loaded;
|
||||||
|
|
||||||
@@ -35,9 +35,10 @@ const loaders = {
|
|||||||
typescript: () => import('./languages/typescript'),
|
typescript: () => import('./languages/typescript'),
|
||||||
yaml: () => import('./languages/yaml'),
|
yaml: () => import('./languages/yaml'),
|
||||||
external: async (monaco, feat) => {
|
external: async (monaco, feat) => {
|
||||||
const items = Object.keys(window.externalModules).filter((i) => i === `monaco-${feat}` || i.startsWith(`monaco-${feat}@`));
|
for (const item of await getFeatures(`monaco-${feat}`)) {
|
||||||
for (const item of items) {
|
let apply = typeof item === 'function'
|
||||||
let apply = (item.startsWith('http') || item.startsWith('/'))
|
? item
|
||||||
|
: (item.startsWith('http') || item.startsWith('/'))
|
||||||
? await legacyLoadExternalModule(window.externalModules[item])
|
? await legacyLoadExternalModule(window.externalModules[item])
|
||||||
: (await loadModule(item)).apply;
|
: (await loadModule(item)).apply;
|
||||||
if (typeof apply !== 'function') apply = apply.default || apply.apply;
|
if (typeof apply !== 'function') apply = apply.default || apply.apply;
|
||||||
@@ -65,7 +66,7 @@ export async function load(features = ['markdown']) {
|
|||||||
for (const feat of features) {
|
for (const feat of features) {
|
||||||
if (loaded.includes(feat)) continue;
|
if (loaded.includes(feat)) continue;
|
||||||
if (!loaders[feat]) {
|
if (!loaders[feat]) {
|
||||||
const items = Object.keys(window.externalModules).filter((i) => i === `monaco-${feat}` || i.startsWith(`monaco-${feat}@`));
|
const items = await getFeatures(`monaco-${feat}`);
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
console.warn('Unknown monaco feature:', feat);
|
console.warn('Unknown monaco feature:', feat);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const lazyModules = {};
|
||||||
|
const features: Record<string, string | (() => Promise<any>)> = {};
|
||||||
|
export default async function load(name: string) {
|
||||||
|
if (window.node_modules[name]) return window.node_modules[name];
|
||||||
|
if (name === 'echarts') return import('echarts');
|
||||||
|
if (name === 'moment') return import('moment');
|
||||||
|
if (!window.lazyloadMetadata?.[`${name}.lazy.js`]) throw new Error(`Module ${name} not found`);
|
||||||
|
if (lazyModules[name]) return lazyModules[name];
|
||||||
|
const tag = document.createElement('script');
|
||||||
|
tag.src = `/lazy/${window.lazyloadMetadata[`${name}.lazy.js`]}/${name}.lazy.js`;
|
||||||
|
lazyModules[name] = new Promise((resolve, reject) => {
|
||||||
|
tag.onerror = reject;
|
||||||
|
const timeout = setTimeout(reject, 30000);
|
||||||
|
window.lazyModuleResolver[name] = (item) => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
resolve(item);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
document.body.appendChild(tag);
|
||||||
|
return lazyModules[name];
|
||||||
|
}
|
||||||
|
export { load };
|
||||||
|
export async function getFeatures(name: string) {
|
||||||
|
const legacy = Object.keys(window.externalModules).filter((i) => i === name || i.startsWith(`${name}@`))
|
||||||
|
.map((i) => window.externalModules[i]);
|
||||||
|
const c = Object.keys(features).filter((i) => i === name || i.startsWith(`${name}@`))
|
||||||
|
.map((i) => features[i]);
|
||||||
|
console.log(legacy, c, features);
|
||||||
|
return c.concat(legacy);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function provideFeature(name: string, content: string | (() => Promise<any>)) {
|
||||||
|
features[name] = content;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user