From 86ead663dfc773a571d288ad3ef3ecd331b78c4f Mon Sep 17 00:00:00 2001 From: undefined Date: Sun, 9 Jan 2022 05:03:21 +0800 Subject: [PATCH] ui: external module support --- packages/ui-default/.eslintrc.js | 1 + packages/ui-default/components/monaco/loader.ts | 14 +++++++++++--- .../components/navigation/navigation.page.js | 4 ---- .../scratchpad/ScratchpadEditorContainer.jsx | 7 ++++--- packages/ui-default/entry.js | 1 + packages/ui-default/hydro.ts | 1 + packages/ui-default/package.json | 2 +- packages/ui-default/utils/loadModule.ts | 10 ++++++++++ 8 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 packages/ui-default/utils/loadModule.ts diff --git a/packages/ui-default/.eslintrc.js b/packages/ui-default/.eslintrc.js index 06327cdaf..78e8468d0 100644 --- a/packages/ui-default/.eslintrc.js +++ b/packages/ui-default/.eslintrc.js @@ -42,6 +42,7 @@ module.exports = { __webpack_require__: true, UiContext: true, UserContext: true, + externalModules: true, LOCALES: true, window: true, JQuery: true, diff --git a/packages/ui-default/components/monaco/loader.ts b/packages/ui-default/components/monaco/loader.ts index 7332c3d64..383842160 100644 --- a/packages/ui-default/components/monaco/loader.ts +++ b/packages/ui-default/components/monaco/loader.ts @@ -1,3 +1,5 @@ +import loadExternalModule from 'vj/utils/loadModule'; + let loaded; const loaders = { i18n: async () => { @@ -16,6 +18,11 @@ const loaders = { markdown: () => import('./languages/markdown'), typescript: () => import('./languages/typescript'), yaml: () => import('./languages/yaml'), + external: async (monaco, feat) => { + let apply = await loadExternalModule(window.externalModules[`monaco-${feat}`]); + if (typeof apply !== 'function') apply = apply.default || apply.apply; + if (typeof apply === 'function') await apply(monaco); + }, }; export async function load(features = ['markdown']) { @@ -26,18 +33,19 @@ export async function load(features = ['markdown']) { } const res = await import('./index'); if (!loaded) { - console.log('Loaded monaco editor in ', Date.now() - s, 'ms'); + console.log('Loaded monaco editor in', Date.now() - s, 'ms'); loaded = []; } for (const feat of features) { if (loaded.includes(feat)) continue; - if (!loaders[feat]) { + if (!loaders[feat] && !window.externalModules[`monaco-${feat}`]) { console.error('Unknown monaco feature:', feat); continue; } s = Date.now(); console.log('Loading monaco feature:', feat); - await loaders[feat](); + if (loaders[feat]) await loaders[feat](); + else await loaders.external(res.default, feat); console.log('Loaded monaco feature:', feat, 'in', Date.now() - s, 'ms'); loaded.push(feat); } diff --git a/packages/ui-default/components/navigation/navigation.page.js b/packages/ui-default/components/navigation/navigation.page.js index 348c29e8c..a036cd2c4 100644 --- a/packages/ui-default/components/navigation/navigation.page.js +++ b/packages/ui-default/components/navigation/navigation.page.js @@ -79,7 +79,6 @@ function handleNavbar() { if (!$(navItems[navItem]).children('a').hasClass('nav--active')) { $(navItems[navItem]).removeClass('nav__list-item').addClass('menu__item'); $(navItems[navItem]).children('a').removeClass('nav__item').addClass('menu__link'); - console.log('hide', navItems[navItem]); $(menu).prepend($(navItems[navItem])); } navItem--; @@ -91,7 +90,6 @@ function handleNavbar() { const ele = menu.children(0); $(ele).addClass('nav__list-item').removeClass('menu__item'); $(ele).children('a').addClass('nav__item').removeClass('menu__link'); - console.log('show', ele); ele.insertBefore(trigger); } } @@ -103,7 +101,6 @@ function handleNavbar() { if (!$(navItems[navItem]).children('a').hasClass('nav--active')) { $(navItems[navItem]).removeClass('nav__list-item').addClass('menu__item'); $(navItems[navItem]).children('a').removeClass('nav__item').addClass('menu__link'); - console.log('hide', navItems[navItem]); $(menu).prepend($(navItems[navItem])); break; } @@ -111,7 +108,6 @@ function handleNavbar() { } } - console.log('children', menu.children()); if (!menu.children().length) trigger.hide(); } diff --git a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx index 6d0784cd2..d95e95190 100644 --- a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx +++ b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx @@ -25,9 +25,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e const value = this.props.value || ''; const { language, theme } = this.props; const { load } = await import('vj/components/monaco/loader'); - console.log(load); const { monaco, registerAction } = await load([language]); - this.model = monaco.editor.createModel(value, language, monaco.Uri.parse('file://model')); + this.model = monaco.editor.createModel(value, language, monaco.Uri.parse(`file:///${UiContext.pdoc.pid || UiContext.pdoc.docId}.${language}`)); if (this.containerElement) { /** @type {monaco.editor.IStandaloneEditorConstructionOptions} */ const config = { @@ -108,7 +107,9 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e width: '100%', }} className="ScratchpadMonacoEditor" - /> + > +
+ ); } }); diff --git a/packages/ui-default/entry.js b/packages/ui-default/entry.js index c64c2e984..8d0eb979d 100644 --- a/packages/ui-default/entry.js +++ b/packages/ui-default/entry.js @@ -5,6 +5,7 @@ window.Hydro = { utils: {}, node_modules: {}, }; +window.externalModules = {}; console.log( '%c%s%c%s', diff --git a/packages/ui-default/hydro.ts b/packages/ui-default/hydro.ts index 7cd151aae..cff9ef155 100644 --- a/packages/ui-default/hydro.ts +++ b/packages/ui-default/hydro.ts @@ -12,6 +12,7 @@ declare global { Hydro: any; // eslint-disable-next-line camelcase node_modules: any; + externalModules: Record; } } diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index e66180180..9067d19b8 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.29.0", + "version": "4.29.1", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/utils/loadModule.ts b/packages/ui-default/utils/loadModule.ts new file mode 100644 index 000000000..ad36c6acf --- /dev/null +++ b/packages/ui-default/utils/loadModule.ts @@ -0,0 +1,10 @@ +export default async function loadExternalModule(target: string) { + const ele = document.createElement('script'); + ele.src = target; + await new Promise((resolve, reject) => { + ele.onload = resolve; + ele.onerror = reject; + document.head.appendChild(ele); + }); + return window.exports; +}