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!')
- {{ msg }}
-
+ {{ msg }}
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'],
+ },
+ },
+ })
+}