main
commit
435f6a734f
@ -0,0 +1,10 @@
|
|||||||
|
# Glob API URL
|
||||||
|
VITE_GLOB_API_URL=/api
|
||||||
|
|
||||||
|
VITE_APP_API_BASE_URL=http://114.218.158.24:9020
|
||||||
|
|
||||||
|
# Whether long replies are supported, which may result in higher API fees
|
||||||
|
VITE_GLOB_OPEN_LONG_REPLY=false
|
||||||
|
|
||||||
|
# When you want to use PWA
|
||||||
|
VITE_GLOB_APP_PWA=false
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"name": "chatgpt-web",
|
||||||
|
"version": "2.11.1",
|
||||||
|
"private": false,
|
||||||
|
"description": "ChatGPT Web",
|
||||||
|
"author": "ChenZhaoYu <chenzhaoyu1994@gmail.com>",
|
||||||
|
"keywords": [
|
||||||
|
"chatgpt-web",
|
||||||
|
"chatgpt",
|
||||||
|
"chatbot",
|
||||||
|
"vue"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "run-p type-check build-only",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --noEmit",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"lint:fix": "eslint . --fix",
|
||||||
|
"bootstrap": "pnpm install && pnpm run common:prepare",
|
||||||
|
"common:cleanup": "rimraf node_modules && rimraf pnpm-lock.yaml",
|
||||||
|
"common:prepare": "husky install"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@traptitech/markdown-it-katex": "^3.6.0",
|
||||||
|
"@vueuse/core": "^9.13.0",
|
||||||
|
"highlight.js": "^11.7.0",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
|
"katex": "^0.16.4",
|
||||||
|
"markdown-it": "^13.0.1",
|
||||||
|
"naive-ui": "^2.34.3",
|
||||||
|
"pinia": "^2.0.33",
|
||||||
|
"vite-plugin-qiankun": "^1.0.15",
|
||||||
|
"vue": "^3.2.47",
|
||||||
|
"vue-i18n": "^9.2.2",
|
||||||
|
"vue-router": "^4.1.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@antfu/eslint-config": "^0.35.3",
|
||||||
|
"@commitlint/cli": "^17.4.4",
|
||||||
|
"@commitlint/config-conventional": "^17.4.4",
|
||||||
|
"@iconify/vue": "^4.1.0",
|
||||||
|
"@types/crypto-js": "^4.1.1",
|
||||||
|
"@types/katex": "^0.16.0",
|
||||||
|
"@types/markdown-it": "^12.2.3",
|
||||||
|
"@types/markdown-it-link-attributes": "^3.0.1",
|
||||||
|
"@types/node": "^18.14.6",
|
||||||
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
|
"autoprefixer": "^10.4.13",
|
||||||
|
"axios": "^1.3.4",
|
||||||
|
"crypto-js": "^4.1.1",
|
||||||
|
"eslint": "^8.35.0",
|
||||||
|
"husky": "^8.0.3",
|
||||||
|
"less": "^4.1.3",
|
||||||
|
"lint-staged": "^13.1.2",
|
||||||
|
"markdown-it-link-attributes": "^4.0.1",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"postcss": "^8.4.21",
|
||||||
|
"rimraf": "^4.3.0",
|
||||||
|
"tailwindcss": "^3.2.7",
|
||||||
|
"typescript": "~4.9.5",
|
||||||
|
"vite": "^5.0.12",
|
||||||
|
"vite-plugin-pwa": "^0.14.4",
|
||||||
|
"vue-tsc": "^1.2.0"
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{ts,tsx,vue}": [
|
||||||
|
"pnpm lint:fix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import request from "@/utils/request/request";
|
||||||
|
|
||||||
|
export const getSessionList = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/chat/list',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export const sessionDetail = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/chat/detail',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
import type { AxiosProgressEvent, GenericAbortSignal } from 'axios'
|
||||||
|
import { post } from '@/utils/request'
|
||||||
|
import { useAuthStore, useSettingStore } from '@/store'
|
||||||
|
|
||||||
|
export function fetchChatAPI<T = any>(
|
||||||
|
prompt: string,
|
||||||
|
options?: { conversationId?: string; parentMessageId?: string },
|
||||||
|
signal?: GenericAbortSignal,
|
||||||
|
) {
|
||||||
|
return post<T>({
|
||||||
|
url: '/chat',
|
||||||
|
data: { prompt, options },
|
||||||
|
signal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchChatConfig<T = any>() {
|
||||||
|
return post<T>({
|
||||||
|
url: '/config',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchChatAPIProcess<T = any>(
|
||||||
|
params: {
|
||||||
|
prompt: string
|
||||||
|
options?: { conversationId?: string; parentMessageId?: string }
|
||||||
|
signal?: GenericAbortSignal
|
||||||
|
onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void },
|
||||||
|
) {
|
||||||
|
const settingStore = useSettingStore()
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
|
let data: Record<string, any> = {
|
||||||
|
prompt: params.prompt,
|
||||||
|
options: params.options,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authStore.isChatGPTAPI) {
|
||||||
|
data = {
|
||||||
|
...data,
|
||||||
|
systemMessage: settingStore.systemMessage,
|
||||||
|
temperature: settingStore.temperature,
|
||||||
|
top_p: settingStore.top_p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return post<T>({
|
||||||
|
url: '/chat-process',
|
||||||
|
data,
|
||||||
|
signal: params.signal,
|
||||||
|
onDownloadProgress: params.onDownloadProgress,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function fetchSession<T>() {
|
||||||
|
return post<T>({
|
||||||
|
url: '/session',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function fetchVerify<T>(token: string) {
|
||||||
|
return post<T>({
|
||||||
|
url: '/verify',
|
||||||
|
data: { token },
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import type { Router } from 'vue-router'
|
||||||
|
|
||||||
|
export function setupPageGuard(router: Router) {
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import axios, { type AxiosResponse } from 'axios'
|
||||||
|
import { useAuthStore } from '@/store'
|
||||||
|
|
||||||
|
const service = axios.create({
|
||||||
|
baseURL: 'http://114.218.158.24:9020',
|
||||||
|
})
|
||||||
|
|
||||||
|
service.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// const token = useAuthStore().token
|
||||||
|
const token = "46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644e756eda7154e1af9e70d1c9d2f100823a26885ea6df3249fe619995cb79dc5dbd5ead32d43b955d6b3ce83129097bb21bb8169898f48692de4f966db140c71b85a2065acfc948561c465279fc05194a79a1115f3b00170944b6c4bd6c52ada909a075c55d18d76c2ed2175602421b34b27362a05c350733ed73382471df0a08950f7f1e812a610c17bdac82d82d54be38969f6b41201af79b8d36ef177c5b94b77a297c94f40d4036d2bd3a7ceac5cb29b191ba490d59fc77c794d533c2d078304c7642e8ae7d697ff83e4cc5dd96f685b7c30f18877f2c1672219ba649e17fdfee148c51f63f1875beb019586995f51fd1a51c55e3e62f09727a44181fa46ff"
|
||||||
|
if (token)
|
||||||
|
config.headers.Authorization =token
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
service.interceptors.response.use(
|
||||||
|
(response: AxiosResponse): AxiosResponse => {
|
||||||
|
console.log(response,'response')
|
||||||
|
return response.data
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default service
|
@ -0,0 +1,16 @@
|
|||||||
|
//对axios进行二次封装,将刚才下载好的axios导入进来
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
const request = axios.create({
|
||||||
|
baseURL:'http://114.218.158.24:9020',
|
||||||
|
timeout:5000
|
||||||
|
});
|
||||||
|
|
||||||
|
request.interceptors.request.use((config)=>{
|
||||||
|
config.headers.Authorization = "46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644e756eda7154e1af9e70d1c9d2f100823a26885ea6df3249fe619995cb79dc5dbd5ead32d43b955d6b3ce83129097bb21bb8169898f48692de4f966db140c71b85a2065acfc948561c465279fc05194a79a1115f3b00170944b6c4bd6c52ada909a075c55d18d76c2ed2175602421b34b27362a05c350733ed73382471df0a08950f7f1e812a610c17bdac82d82d54be38969f6b41201af79b8d36ef177c5b94b77a297c94f40d4036d2bd3a7ceac5cb29b191ba490d59fc77c794d533c2d078304c7642e8ae7d697ff83e4cc5dd96f685b7c30f18877f2c1672219ba649e17fdfee148c51f63f1875beb019586995f51fd1a51c55e3e62f09727a44181fa46ff"
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
request.interceptors.response.use((res)=>{
|
||||||
|
return res.data;
|
||||||
|
});
|
||||||
|
export default request;
|
@ -0,0 +1,127 @@
|
|||||||
|
<script setup >
|
||||||
|
import {computed, ref} from 'vue'
|
||||||
|
import { NInput, NPopconfirm, NScrollbar } from 'naive-ui'
|
||||||
|
import {getSessionList, sessionDetail} from '@/api/api'
|
||||||
|
import { SvgIcon } from '@/components/common'
|
||||||
|
import { useAppStore, useChatStore } from '@/store'
|
||||||
|
import { useBasicLayout } from '@/hooks/useBasicLayout'
|
||||||
|
import { debounce } from '@/utils/functions/debounce'
|
||||||
|
const { isMobile } = useBasicLayout()
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const chatStore = useChatStore()
|
||||||
|
const dataSources = computed(() => chatStore.history)
|
||||||
|
async function handleSelect({ listUuid }) {
|
||||||
|
currentListUuid.value=listUuid
|
||||||
|
getSessionDetail()
|
||||||
|
if (isActive(listUuid)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatStore.active)
|
||||||
|
chatStore.updateHistory(chatStore.active, { isEdit: false })
|
||||||
|
await chatStore.setActive(listUuid)
|
||||||
|
|
||||||
|
if (isMobile.value)
|
||||||
|
appStore.setSiderCollapsed(true)
|
||||||
|
}
|
||||||
|
const dataList=ref([])
|
||||||
|
const currentListUuid=ref('')
|
||||||
|
const detailData=ref([])
|
||||||
|
const getSessionDetail =async () => {
|
||||||
|
const res= await sessionDetail({listUuid:currentListUuid.value})
|
||||||
|
if (res.code===0){
|
||||||
|
detailData.value=res.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const getDataList = async () => {
|
||||||
|
const data = {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 9999,
|
||||||
|
}
|
||||||
|
const res=await getSessionList(data).then((res)=>{
|
||||||
|
if (res.code===0){
|
||||||
|
dataList.value=res.data.data
|
||||||
|
console.log(dataList.value,'dataList.value')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
getDataList()
|
||||||
|
function handleEdit({ listUuid }, isEdit, event) {
|
||||||
|
event?.stopPropagation()
|
||||||
|
chatStore.updateHistory(listUuid, { isEdit })
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(index, event) {
|
||||||
|
event?.stopPropagation()
|
||||||
|
chatStore.deleteHistory(index)
|
||||||
|
if (isMobile.value)
|
||||||
|
appStore.setSiderCollapsed(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeleteDebounce = debounce(handleDelete, 600)
|
||||||
|
|
||||||
|
function handleEnter({ listUuid }, isEdit, event) {
|
||||||
|
event?.stopPropagation()
|
||||||
|
if (event.key === 'Enter')
|
||||||
|
chatStore.updateHistory(listUuid, { isEdit })
|
||||||
|
}
|
||||||
|
|
||||||
|
function isActive(listUuid) {
|
||||||
|
return chatStore.active === listUuid
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NScrollbar class="px-4">
|
||||||
|
<div class="flex flex-col gap-2 text-sm">
|
||||||
|
<template v-if="!dataList.length">
|
||||||
|
<div class="flex flex-col items-center mt-4 text-center text-neutral-300">
|
||||||
|
<SvgIcon icon="ri:inbox-line" class="mb-2 text-3xl" />
|
||||||
|
<span>{{ $t('common.noData') }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<div v-for="(item, index) of dataList" :key="item.listUuid">
|
||||||
|
<a
|
||||||
|
class="relative flex items-center gap-3 px-3 py-3 break-all border rounded-md cursor-pointer hover:bg-neutral-100 group dark:border-neutral-800 dark:hover:bg-[#24272e]"
|
||||||
|
:class="isActive(item.listUuid) && ['border-[#4b9e5f]', 'bg-neutral-100', 'text-[#4b9e5f]', 'dark:bg-[#24272e]', 'dark:border-[#4b9e5f]', 'pr-14']"
|
||||||
|
@click="handleSelect(item)"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<SvgIcon icon="ri:message-3-line" />
|
||||||
|
</span>
|
||||||
|
<div class="relative flex-1 overflow-hidden break-all text-ellipsis whitespace-nowrap">
|
||||||
|
<NInput
|
||||||
|
v-if="item.isEdit"
|
||||||
|
v-model:value="item.title" size="tiny"
|
||||||
|
@keypress="handleEnter(item, false, $event)"
|
||||||
|
/>
|
||||||
|
<span v-else>{{ item.title }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="isActive(item.listUuid)" class="absolute z-10 flex visible right-1">
|
||||||
|
<template v-if="item.isEdit">
|
||||||
|
<button class="p-1" @click="handleEdit(item, false, $event)">
|
||||||
|
<SvgIcon icon="ri:save-line" />
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<button class="p-1">
|
||||||
|
<SvgIcon icon="ri:edit-line" @click="handleEdit(item, true, $event)" />
|
||||||
|
</button>
|
||||||
|
<NPopconfirm placement="bottom" @positive-click="handleDeleteDebounce(index, $event)">
|
||||||
|
<template #trigger>
|
||||||
|
<button class="p-1">
|
||||||
|
<SvgIcon icon="ri:delete-bin-line" />
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
{{ $t('chat.deleteHistoryConfirm') }}
|
||||||
|
</NPopconfirm>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</NScrollbar>
|
||||||
|
</template>
|
@ -0,0 +1,117 @@
|
|||||||
|
<script setup lang='ts'>
|
||||||
|
import type { CSSProperties } from 'vue'
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { NButton, NLayoutSider, useDialog } from 'naive-ui'
|
||||||
|
import List from './List.vue'
|
||||||
|
import Footer from './Footer.vue'
|
||||||
|
import { useAppStore, useChatStore } from '@/store'
|
||||||
|
import { useBasicLayout } from '@/hooks/useBasicLayout'
|
||||||
|
import { PromptStore, SvgIcon } from '@/components/common'
|
||||||
|
import { t } from '@/locales'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const chatStore = useChatStore()
|
||||||
|
|
||||||
|
const dialog = useDialog()
|
||||||
|
|
||||||
|
const { isMobile } = useBasicLayout()
|
||||||
|
const show = ref(false)
|
||||||
|
|
||||||
|
const collapsed = computed(() => appStore.siderCollapsed)
|
||||||
|
|
||||||
|
function handleAdd() {
|
||||||
|
chatStore.addHistory({ title: t('chat.newChatTitle'), uuid: Date.now(), isEdit: false })
|
||||||
|
if (isMobile.value)
|
||||||
|
appStore.setSiderCollapsed(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleUpdateCollapsed() {
|
||||||
|
appStore.setSiderCollapsed(!collapsed.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClearAll() {
|
||||||
|
dialog.warning({
|
||||||
|
title: t('chat.deleteMessage'),
|
||||||
|
content: t('chat.clearHistoryConfirm'),
|
||||||
|
positiveText: t('common.yes'),
|
||||||
|
negativeText: t('common.no'),
|
||||||
|
onPositiveClick: () => {
|
||||||
|
chatStore.clearHistory()
|
||||||
|
if (isMobile.value)
|
||||||
|
appStore.setSiderCollapsed(true)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMobileClass = computed<CSSProperties>(() => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
return {
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 50,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const mobileSafeArea = computed(() => {
|
||||||
|
if (isMobile.value) {
|
||||||
|
return {
|
||||||
|
paddingBottom: 'env(safe-area-inset-bottom)',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
isMobile,
|
||||||
|
(val) => {
|
||||||
|
appStore.setSiderCollapsed(val)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
flush: 'post',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NLayoutSider
|
||||||
|
:collapsed="collapsed"
|
||||||
|
:collapsed-width="0"
|
||||||
|
:width="260"
|
||||||
|
:show-trigger="isMobile ? false : 'arrow-circle'"
|
||||||
|
collapse-mode="transform"
|
||||||
|
position="absolute"
|
||||||
|
bordered
|
||||||
|
:style="getMobileClass"
|
||||||
|
@update-collapsed="handleUpdateCollapsed"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col h-full" :style="mobileSafeArea">
|
||||||
|
<main class="flex flex-col flex-1 min-h-0">
|
||||||
|
<div class="p-4">
|
||||||
|
<NButton dashed block @click="handleAdd">
|
||||||
|
{{ $t('chat.newChatButton') }}
|
||||||
|
</NButton>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 min-h-0 pb-4 overflow-hidden">
|
||||||
|
<List />
|
||||||
|
</div>
|
||||||
|
<!-- <div class="flex items-center p-4 space-x-4">
|
||||||
|
<div class="flex-1">
|
||||||
|
<NButton block @click="show = true">
|
||||||
|
{{ $t('store.siderButton') }}
|
||||||
|
</NButton>
|
||||||
|
</div>
|
||||||
|
<NButton @click="handleClearAll">
|
||||||
|
<SvgIcon icon="ri:close-circle-line" />
|
||||||
|
</NButton>
|
||||||
|
</div>-->
|
||||||
|
</main>
|
||||||
|
<!-- <Footer />-->
|
||||||
|
</div>
|
||||||
|
</NLayoutSider>
|
||||||
|
<template v-if="isMobile">
|
||||||
|
<div v-show="!collapsed" class="fixed inset-0 z-40 w-full h-full bg-black/40" @click="handleUpdateCollapsed" />
|
||||||
|
</template>
|
||||||
|
<PromptStore v-model:visible="show" />
|
||||||
|
</template>
|
@ -0,0 +1,62 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import type { PluginOption } from 'vite'
|
||||||
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
|
import qiankun from 'vite-plugin-qiankun'
|
||||||
|
function setupPlugins(env: ImportMetaEnv): PluginOption[] {
|
||||||
|
return [
|
||||||
|
vue(),
|
||||||
|
env.VITE_GLOB_APP_PWA === 'true' && VitePWA({
|
||||||
|
injectRegister: 'auto',
|
||||||
|
manifest: {
|
||||||
|
name: 'chatGPT',
|
||||||
|
short_name: 'chatGPT',
|
||||||
|
icons: [
|
||||||
|
{ src: 'pwa-192x192.png', sizes: '192x192', type: 'image/png' },
|
||||||
|
{ src: 'pwa-512x512.png', sizes: '512x512', type: 'image/png' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineConfig((env) => {
|
||||||
|
const viteEnv = loadEnv(env.mode, process.cwd()) as unknown as ImportMetaEnv
|
||||||
|
|
||||||
|
return {
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(process.cwd(), 'src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [setupPlugins(viteEnv), qiankun('testapp', {
|
||||||
|
useDevMode: true,
|
||||||
|
})],
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 1002,
|
||||||
|
open: false,
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: viteEnv.VITE_APP_API_BASE_URL,
|
||||||
|
changeOrigin: true, // 允许跨域
|
||||||
|
rewrite: path => path.replace('/api/', '/'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
reportCompressedSize: false,
|
||||||
|
sourcemap: false,
|
||||||
|
commonjsOptions: {
|
||||||
|
ignoreTryCatch: false,
|
||||||
|
},
|
||||||
|
target: 'esnext',
|
||||||
|
lib: {
|
||||||
|
name: 'testapp',
|
||||||
|
entry: 'src/main.ts',
|
||||||
|
formats: ['umd'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue