From 3e7c9e329fefb7077e970ade38fbe0dfcb99dc7a Mon Sep 17 00:00:00 2001 From: sunlei Date: Wed, 13 May 2026 18:17:07 +0800 Subject: [PATCH] feat: add playground component save workflow --- .env.development | 2 + index.html | 12 +- package.json | 7 +- pnpm-lock.yaml | 88 +++++++++ src/PlaygroundHeader.vue | 407 +++++++++++++++++++++++++++++++++++++++ src/api/component.ts | 18 ++ src/api/dict.ts | 18 ++ src/api/minio.ts | 9 + src/api/request.ts | 47 +++++ src/import-map.ts | 17 ++ src/output/Sandbox.vue | 30 ++- src/store.ts | 9 +- src/template/welcome.vue | 3 +- test/main.ts | 56 +++--- vite.config.ts | 90 +++++---- 15 files changed, 743 insertions(+), 70 deletions(-) create mode 100644 .env.development create mode 100644 src/PlaygroundHeader.vue create mode 100644 src/api/component.ts create mode 100644 src/api/dict.ts create mode 100644 src/api/minio.ts create mode 100644 src/api/request.ts diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..27a819d --- /dev/null +++ b/.env.development @@ -0,0 +1,2 @@ +VITE_APP_API_BASE = "/api" +VITE_APP_PROXY = "http://192.168.0.49:48085/" diff --git a/index.html b/index.html index 50eeaa8..0151ff9 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Vue SFC Playground + KT-Template - Playground diff --git a/package.json b/package.json index 4d38ce0..93bc02d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "tag": "latest" }, "scripts": { - "dev": "vite", + "dev": "vite --host", "build": "vite build", "build-preview": "vite build -c vite.preview.config.ts", "format": "prettier --write .", @@ -115,9 +115,12 @@ "typescript-eslint": "^8.39.0", "vite": "^8.0.8", "vite-plugin-dts": "^4.5.4", - "vscode-uri": "^3.1.0", "volar-service-typescript": "0.0.65", + "vscode-uri": "^3.1.0", "vue": "^3.5.18", "vue-tsc": "3.0.8" + }, + "dependencies": { + "axios": "^1.16.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2fccfd2..a6c342f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,10 @@ settings: importers: .: + dependencies: + axios: + specifier: ^1.16.0 + version: 1.16.0 devDependencies: '@babel/standalone': specifier: ^7.28.2 @@ -988,10 +992,16 @@ packages: assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axios@1.16.0: + resolution: {integrity: sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1082,6 +1092,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -1217,6 +1231,10 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -1278,6 +1296,10 @@ packages: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1407,6 +1429,15 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1414,6 +1445,10 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + fs-extra@11.3.0: resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} engines: {node: '>=14.14'} @@ -1822,6 +1857,14 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} @@ -2016,6 +2059,10 @@ packages: property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + pug-error@2.1.0: resolution: {integrity: sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==} @@ -3534,10 +3581,20 @@ snapshots: object.assign: 4.1.7 util: 0.12.5 + asynckit@0.4.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 + axios@1.16.0: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + balanced-match@1.0.2: {} boolbase@1.0.0: {} @@ -3633,6 +3690,10 @@ snapshots: colorette@2.0.20: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} commander@14.0.0: {} @@ -3766,6 +3827,8 @@ snapshots: defu@6.1.4: {} + delayed-stream@1.0.0: {} + dequal@2.0.3: {} detect-libc@2.1.2: {} @@ -3813,6 +3876,13 @@ snapshots: dependencies: es-errors: 1.3.0 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.2.6 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -3962,6 +4032,8 @@ snapshots: flatted@3.3.2: {} + follow-redirects@1.16.0: {} + for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -3971,6 +4043,14 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + fs-extra@11.3.0: dependencies: graceful-fs: 4.2.11 @@ -4370,6 +4450,12 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-function@5.0.1: {} minimatch@10.0.3: @@ -4554,6 +4640,8 @@ snapshots: property-information@7.1.0: {} + proxy-from-env@2.1.0: {} + pug-error@2.1.0: {} pug-lexer@5.0.1: diff --git a/src/PlaygroundHeader.vue b/src/PlaygroundHeader.vue new file mode 100644 index 0000000..cd57512 --- /dev/null +++ b/src/PlaygroundHeader.vue @@ -0,0 +1,407 @@ + + + + + diff --git a/src/api/component.ts b/src/api/component.ts new file mode 100644 index 0000000..7b37e7b --- /dev/null +++ b/src/api/component.ts @@ -0,0 +1,18 @@ +import { post } from './request' + +export type ComponentPayload = { + id?: string + name: string + type: number + componentType: number + image: string + template: string +} + +export const saveComponent = (data: ComponentPayload) => { + return post('/component/save', data) +} + +export const updateComponent = (data: ComponentPayload) => { + return post('/component/update', data) +} diff --git a/src/api/dict.ts b/src/api/dict.ts new file mode 100644 index 0000000..e7a1295 --- /dev/null +++ b/src/api/dict.ts @@ -0,0 +1,18 @@ +import { get } from './request' + +export type DictItem = { + label: string + value: number +} + +export const getDictByKey = (dictKey: string) => { + return get('/dict/getDictByKey', { + params: { dictKey }, + }) +} + +export const getComponentDictByType = (type: string | number) => { + return get('/dict/getComponentDictByType', { + params: { type }, + }) +} diff --git a/src/api/minio.ts b/src/api/minio.ts new file mode 100644 index 0000000..e4f8636 --- /dev/null +++ b/src/api/minio.ts @@ -0,0 +1,9 @@ +import { post } from './request' + +export type MinioUploadResult = { + url: string +} + +export const uploadFile = (data: FormData) => { + return post('/minio/upload', data) +} diff --git a/src/api/request.ts b/src/api/request.ts new file mode 100644 index 0000000..9d69b2a --- /dev/null +++ b/src/api/request.ts @@ -0,0 +1,47 @@ +import axios, { type AxiosRequestConfig } from 'axios' + +export type ApiResponse = { + code: number + msg: string + data: T +} + +const request = axios.create({ + baseURL: import.meta.env.VITE_APP_API_BASE || '/api', + timeout: 1000 * 30, +}) + +request.interceptors.response.use( + (response) => { + const data = response.data as ApiResponse + + if (data.code !== 200) { + return Promise.reject(new Error(data.msg || '请求失败')) + } + + return data.data as any + }, + (error) => { + if (axios.isAxiosError(error)) { + return Promise.reject( + new Error(error.response?.data?.msg || error.message || '请求失败'), + ) + } + + return Promise.reject(error) + }, +) + +export const get = (url: string, config?: AxiosRequestConfig) => { + return request.get(url, config) +} + +export const post = ( + url: string, + data?: unknown, + config?: AxiosRequestConfig, +) => { + return request.post(url, data, config) +} + +export default request diff --git a/src/import-map.ts b/src/import-map.ts index 328cb40..5a14db6 100644 --- a/src/import-map.ts +++ b/src/import-map.ts @@ -10,6 +10,22 @@ export function isVaporSupported(version: string): boolean{ return major > 3 || (major === 3 && minor >= 6) } +export const builtinLibraryImports: Record = { + echarts: 'https://esm.sh/echarts@latest', + 'echarts/': 'https://esm.sh/echarts@latest/', + 'ant-design-vue': 'https://esm.sh/ant-design-vue@latest?external=vue', + 'ant-design-vue/': 'https://esm.sh/ant-design-vue@latest/', + '@ant-design/icons-vue': + 'https://esm.sh/@ant-design/icons-vue@latest?external=vue', + '@ant-design/icons-vue/': 'https://esm.sh/@ant-design/icons-vue@latest/', + 'element-plus': 'https://esm.sh/element-plus@latest?external=vue', + 'element-plus/': 'https://esm.sh/element-plus@latest/', + '@element-plus/icons-vue': + 'https://esm.sh/@element-plus/icons-vue@latest?external=vue', + '@element-plus/icons-vue/': + 'https://esm.sh/@element-plus/icons-vue@latest/', +} + export function useVueImportMap( defaults: { runtimeDev?: string | (() => string) @@ -50,6 +66,7 @@ export function useVueImportMap( imports: { vue, 'vue/server-renderer': serverRenderer, + ...builtinLibraryImports, }, } }) diff --git a/src/output/Sandbox.vue b/src/output/Sandbox.vue index a5bafa2..7374e4a 100644 --- a/src/output/Sandbox.vue +++ b/src/output/Sandbox.vue @@ -62,6 +62,23 @@ let sandbox: HTMLIFrameElement let proxy: PreviewProxy let stopUpdateWatcher: WatchStopHandle | undefined +const builtinLibraryHeadHTML = ` + + +` + +const antDesignVueModule = 'ant-design' + '-vue' +const elementPlusModule = 'element' + '-plus' +const builtinLibraryImportCode = [ + `import __AntDesignVue from '${antDesignVueModule}'`, + `import __ElementPlus from '${elementPlusModule}'`, +].join('\n') + +const builtinLibraryUseCode = ` +app.use(__AntDesignVue) +app.use(__ElementPlus) +` + // create sandbox on mount onMounted(createSandbox) @@ -118,13 +135,12 @@ function createSandbox() { ) const importMap = store.value.getImportMap() + const headHTML = + builtinLibraryHeadHTML + (previewOptions.value?.headHTML || '') const sandboxSrc = srcdoc .replace(//, ``) .replace(//, JSON.stringify(importMap)) - .replace( - //, - previewOptions.value?.headHTML || '', - ) + .replace(//, headHTML) .replace( //, previewOptions.value?.placeholderHTML || '', @@ -237,6 +253,8 @@ async function updatePreview() { ...ssrModules, `import { renderToString as _renderToString } from 'vue/server-renderer' import { createSSRApp as _createApp ${vaporSupported ? ', createVaporSSRApp as _createVaporApp' : ''} } from 'vue' + ${builtinLibraryImportCode} + ${previewOptions.value?.customCode?.importCode || ''} const AppComponent = __modules__["${mainFile}"].default AppComponent.name = 'Repl' const vaporSupported = ${vaporSupported} @@ -245,6 +263,8 @@ async function updatePreview() { app.config.unwrapInjectedRef = true } app.config.warnHandler = () => {} + ${builtinLibraryUseCode} + ${previewOptions.value?.customCode?.useCode || ''} const rawContext = {} window.__ssr_promise__ = _renderToString(app, rawContext).then(html => { document.body.innerHTML = '
' + html + '
' + \`${ @@ -313,6 +333,7 @@ async function updatePreview() { } as _createVaporApp` : '' } } from "vue" + ${builtinLibraryImportCode} ${previewOptions.value?.customCode?.importCode || ''} const _mount = () => { const AppComponent = __modules__["${mainFile}"].default @@ -323,6 +344,7 @@ async function updatePreview() { app.config.unwrapInjectedRef = true } app.config.errorHandler = e => console.error(e) + ${builtinLibraryUseCode} ${previewOptions.value?.customCode?.useCode || ''} app.mount('#app') } diff --git a/src/store.ts b/src/store.ts index 1989dd9..4f98f57 100644 --- a/src/store.ts +++ b/src/store.ts @@ -25,6 +25,13 @@ import newSFCCode from './template/new-sfc.vue?raw' export const importMapFile = 'import-map.json' export const tsconfigFile = 'tsconfig.json' +export const builtinDependencyVersions: Record = { + echarts: 'latest', + 'ant-design-vue': 'latest', + '@ant-design/icons-vue': 'latest', + 'element-plus': 'latest', + '@element-plus/icons-vue': 'latest', +} export function useStore( { @@ -46,7 +53,7 @@ export function useStore( locale = ref(), typescriptVersion = ref('latest'), - dependencyVersion = ref(Object.create(null)), + dependencyVersion = ref({ ...builtinDependencyVersions }), reloadLanguageTools = ref(), resourceLinks = undefined, }: Partial = {}, diff --git a/src/template/welcome.vue b/src/template/welcome.vue index 5b15d82..427bfd8 100644 --- a/src/template/welcome.vue +++ b/src/template/welcome.vue @@ -5,6 +5,5 @@ const msg = ref('Hello World!') diff --git a/test/main.ts b/test/main.ts index 43a674c..beaf428 100644 --- a/test/main.ts +++ b/test/main.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/prefer-ts-expect-error */ import { createApp, h, ref, watchEffect } from 'vue' import { type OutputModes, Repl, useStore, useVueImportMap } from '../src' +import PlaygroundHeader from '../src/PlaygroundHeader.vue' // @ts-ignore import MonacoEditor from '../src/editor/MonacoEditor.vue' // @ts-ignore @@ -31,7 +32,13 @@ const App = { )) console.info(store) - watchEffect(() => history.replaceState({}, '', store.serialize())) + watchEffect(() => { + history.replaceState( + {}, + '', + `${location.pathname}${location.search}${store.serialize()}`, + ) + }) // setTimeout(() => { // store.setFiles( @@ -53,30 +60,33 @@ const App = { window.previewTheme = previewTheme return () => - h(Repl, { - store, - theme: theme.value, - previewTheme: previewTheme.value, - editor: MonacoEditor, - showOpenSourceMap: true, - // layout: 'vertical', - ssr: true, - showSsrOutput: true, - sfcOptions: { - script: { - // inlineTemplate: false + h('div', { class: ['playground-shell', theme.value] }, [ + h(PlaygroundHeader, { store }), + h(Repl, { + store, + theme: theme.value, + previewTheme: previewTheme.value, + editor: MonacoEditor, + showOpenSourceMap: true, + // layout: 'vertical', + ssr: true, + showSsrOutput: true, + sfcOptions: { + script: { + // inlineTemplate: false + }, }, - }, - // showCompileOutput: false, - // showImportMap: false - editorOptions: { - autoSaveText: '💾', - monacoOptions: { - // wordWrap: 'on', + // showCompileOutput: false, + // showImportMap: false + editorOptions: { + autoSaveText: '💾', + monacoOptions: { + // wordWrap: 'on', + }, }, - }, - // autoSave: false, - }) + // autoSave: false, + }), + ]) }, } diff --git a/vite.config.ts b/vite.config.ts index 1b007b8..25dabfc 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,4 +1,4 @@ -import { type Plugin, mergeConfig } from 'vite' +import { type Plugin, loadEnv, mergeConfig } from 'vite' import dts from 'vite-plugin-dts' import base from './vite.preview.config' import fs from 'node:fs' @@ -34,42 +34,58 @@ const patchCssFiles: Plugin = { }, } -export default mergeConfig(base, { - plugins: [ - dts({ - rollupTypes: true, - }), - genStub, - patchCssFiles, - ], - optimizeDeps: { - // avoid late discovered deps - include: [ - 'typescript', - 'monaco-editor-core/esm/vs/editor/editor.worker', - 'vue/server-renderer', +export default ({ mode }: { mode: string }) => { + const env = loadEnv(mode, process.cwd()) + + return mergeConfig(base, { + plugins: [ + dts({ + rollupTypes: true, + }), + genStub, + patchCssFiles, ], - }, - base: './', - build: { - target: 'esnext', - minify: false, - lib: { - entry: { - 'vue-repl': './src/index.ts', - core: './src/core.ts', - 'monaco-editor': './src/editor/MonacoEditor.vue', - 'codemirror-editor': './src/editor/CodeMirrorEditor.vue', - }, - formats: ['es'], - fileName: () => '[name].js', + server: { + proxy: env.VITE_APP_PROXY + ? { + '/api': { + target: env.VITE_APP_PROXY, + changeOrigin: true, + rewrite: (requestPath: string) => + requestPath.replace(/^\/api/, ''), + }, + } + : undefined, }, - cssCodeSplit: true, - rollupOptions: { - output: { - chunkFileNames: 'chunks/[name]-[hash].js', - }, - external: ['vue', 'vue/compiler-sfc'], + optimizeDeps: { + // avoid late discovered deps + include: [ + 'typescript', + 'monaco-editor-core/esm/vs/editor/editor.worker', + 'vue/server-renderer', + ], }, - }, -}) + base: './', + build: { + target: 'esnext', + minify: false, + lib: { + entry: { + 'vue-repl': './src/index.ts', + core: './src/core.ts', + 'monaco-editor': './src/editor/MonacoEditor.vue', + 'codemirror-editor': './src/editor/CodeMirrorEditor.vue', + }, + formats: ['es'], + fileName: () => '[name].js', + }, + cssCodeSplit: true, + rollupOptions: { + output: { + chunkFileNames: 'chunks/[name]-[hash].js', + }, + external: ['vue', 'vue/compiler-sfc'], + }, + }, + }) +}