# Conflicts:
#	package.json
#	pnpm-lock.yaml
#	src/auto-imports.d.ts
#	tsconfig.json
#	vite.config.ts
main
NoahLan 1 year ago
commit a4b1c68eec

@ -0,0 +1,4 @@
> 1%
last 2 versions
not dead
not ie 11

39
.env

@ -1,17 +1,30 @@
# Whether to open mock # 项目基本地址
VITE_USE_MOCK=false VITE_BASE_URL=/
# 项目名称
# public path VITE_APP_NAME=N-Admin
VITE_PUBLIC_PATH=/ # 项目标题
VITE_APP_TITLE=N-Admin
# 项目描述
VITE_APP_DESC=N-Admin-UI
VITE_TITLE=N-Admin # API访问地址
VITE_DESCRIPTION=N-Admin-UI template
# Basic interface address SPA
VITE_API_URL=/api VITE_API_URL=/api
# 上传地址optional
# File upload address optional
VITE_UPLOAD_URL=/api/upload VITE_UPLOAD_URL=/api/upload
# API接口前缀
# Interface prefix
VITE_API_URL_PREFIX= VITE_API_URL_PREFIX=
# 是否开启请求代理
VITE_HTTP_PROXY=false
# 是否开启打包文件大小结果分析
VITE_VISUALIZER=true
# 是否开启打包压缩
VITE_COMPRESS=false
# 压缩算法类型
VITE_COMPRESS_TYPE=gzip
# 是否应用pwa
VITE_PWA=false
# 是否启用Markdown插件
VITE_MARKDOWN=true
# 是否开启Mock
VITE_USE_MOCK=false

11
.gitattributes vendored

@ -0,0 +1,11 @@
# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
# Automatically normalize line endings (to LF) for all text-based files.
* text=auto eol=lf
# Declare files that will always have CRLF line endings on checkout.
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary

38
.gitignore vendored

@ -1,10 +1,38 @@
.DS_Store
.vite-ssg-dist .vite-ssg-dist
.vite-ssg-temp .vite-ssg-temp
*.local cypress/downloads
node_modules
.DS_Store
dist dist
dist-ssr dist-ssr
node_modules .cache
.idea/ .turbo
# local files
*.local
# local env files
.env.local
.env.*.local
.eslintcache
# Log files
*.log *.log
cypress/downloads npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
package-lock.json
pnpm-lock.yaml
.history

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020-PRESENT Anthony Fu Copyright (c) 2020-PRESENT NorthLan
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

@ -0,0 +1,35 @@
import AutoImport from 'unplugin-auto-import/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
export default () => {
// https://github.com/antfu/unplugin-auto-import
return AutoImport({
imports: [
'vue',
'vue-router',
'vue-i18n',
'vue/macros',
'@vueuse/head',
'@vueuse/core',
{
'naive-ui': [
'useDialog',
'useMessage',
'useNotification',
'useLoadingBar',
],
},
],
dts: 'src/auto-imports.d.ts',
dirs: [
'src/composables',
'src/stores',
'src/types',
'src/api/**',
],
vueTemplate: true,
resolvers: [
NaiveUiResolver(),
],
})
}

@ -0,0 +1,6 @@
import ViteCompression from 'vite-plugin-compression'
export default (viteEnv: ImportMetaEnv) => {
const { VITE_COMPRESS_TYPE = 'gzip' } = viteEnv
return ViteCompression({ algorithm: VITE_COMPRESS_TYPE })
}

@ -0,0 +1,60 @@
import type { PluginOption } from 'vite'
import Layouts from 'vite-plugin-vue-layouts'
import Pages from 'vite-plugin-pages'
import WebfontDownload from 'vite-plugin-webfont-dl'
import VueDevTools from 'vite-plugin-vue-devtools'
import Unocss from 'unocss/vite'
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
// must
import { getRootPath } from 'build/utils'
import vueMacros from './vuemacros'
import autoImport from './autoimport'
import unplugins from './unplugins'
// select
import visualizer from './visualizer'
import compress from './compress'
import pwa from './pwa'
import markdown from './markdown'
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
const plugins = [
vueMacros(),
autoImport(),
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
Layouts(),
// https://github.com/hannoeru/vite-plugin-pages
Pages({
extensions: ['vue', 'md'],
}),
// https://github.com/feat-agency/vite-plugin-webfont-dl
WebfontDownload(),
// https://github.com/webfansplz/vite-plugin-vue-devtools
VueDevTools(),
// https://github.com/antfu/unocss
// see uno.config.ts for config
Unocss(),
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n
VueI18n({
runtimeOnly: true,
compositionOnly: true,
fullInstall: true,
include: [`${getRootPath()}/locales/**`],
}),
...unplugins(viteEnv),
]
if (viteEnv.VITE_VISUALIZER)
plugins.push(visualizer as PluginOption)
if (viteEnv.VITE_COMPRESS)
plugins.push(compress(viteEnv))
if (viteEnv.VITE_PWA)
plugins.push(pwa())
if (viteEnv.VITE_MARKDOWN)
plugins.push(markdown(viteEnv))
return plugins
}

@ -0,0 +1,28 @@
import Markdown from 'vite-plugin-vue-markdown'
import LinkAttributes from 'markdown-it-link-attributes'
import Shiki from 'markdown-it-shiki'
export default (viteEnv: ImportMetaEnv) => {
// https://github.com/antfu/vite-plugin-vue-markdown
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
return Markdown({
wrapperClasses: 'prose prose-sm m-auto text-left',
headEnabled: true,
markdownItSetup(md) {
// https://prismjs.com/
md.use(Shiki, {
theme: {
light: 'vitesse-light',
dark: 'vitesse-dark',
},
})
md.use(LinkAttributes, {
matcher: (link: string) => /^https?:\/\//.test(link),
attrs: {
target: '_blank',
rel: 'noopener',
},
})
},
})
}

@ -0,0 +1,32 @@
import { VitePWA } from 'vite-plugin-pwa'
export default function setupVitePwa() {
// https://github.com/antfu/vite-plugin-pwa
return VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
manifest: {
name: 'N-Admin',
short_name: 'N-Admin',
theme_color: '#ffffff',
icons: [
{
src: '/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
})
}

@ -0,0 +1,18 @@
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
export default (viteEnv: ImportMetaEnv) => {
return [
// https://github.com/antfu/unplugin-vue-components
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
dts: 'src/components.d.ts',
resolvers: [
NaiveUiResolver(),
],
}),
]
}

@ -0,0 +1,7 @@
import { visualizer } from 'rollup-plugin-visualizer'
export default visualizer({
gzipSize: true,
brotliSize: true,
open: true,
})

@ -0,0 +1,23 @@
import { transformShortVmodel } from '@vue-macros/short-vmodel'
import Vue from '@vitejs/plugin-vue'
// @ts-expect-error failed to resolve types
import VueMacros from 'unplugin-vue-macros/vite'
export default () => {
return VueMacros({
plugins: {
vue: Vue({
include: [/\.vue$/, /\.md$/],
reactivityTransform: true,
template: {
compilerOptions: {
nodeTransforms: [
transformShortVmodel({ prefix: '::' }),
],
},
},
}),
},
})
}

@ -0,0 +1,16 @@
import path from 'node:path'
import process from 'node:process'
/**
*
*/
export function getRootPath() {
return path.resolve(process.cwd())
}
/**
* src
*/
export function getSrcPath(srcName = 'src') {
return `${getRootPath()}/${srcName}`
}

@ -1,11 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="/pwa-192x192.png"> <link rel="apple-touch-icon" href="/pwa-192x192.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
<meta name="msapplication-TileColor" content="#00aba9"> <meta name="msapplication-TileColor" content="#00aba9">
<title>%VITE_APP_NAME%</title>
<script> <script>
(function () { (function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
@ -15,9 +19,13 @@
})() })()
</script> </script>
</head> </head>
<body class="font-sans"> <body class="font-sans">
<div id="app"></div> <div id="app">
<div id="appLoading"></div>
</div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
<noscript>This website requires JavaScript to function properly. Please enable JavaScript to continue.</noscript> <noscript>This website requires JavaScript to function properly. Please enable JavaScript to continue.</noscript>
</body> </body>
</html> </html>

@ -1,7 +1,13 @@
{ {
"name": "n-admin-ui",
"type": "module", "type": "module",
"version": "1.0.0",
"private": true, "private": true,
"packageManager": "pnpm@8.5.1", "packageManager": "pnpm@8.5.1",
"engines": {
"node": ">=16.15.1",
"pnpm": ">=8.1.0"
},
"scripts": { "scripts": {
"build": "vite build", "build": "vite build",
"build:ssg": "vite-ssg build", "build:ssg": "vite-ssg build",
@ -14,7 +20,7 @@
"test:unit": "vitest", "test:unit": "vitest",
"typecheck": "vue-tsc --noEmit", "typecheck": "vue-tsc --noEmit",
"up": "taze major -I", "up": "taze major -I",
"postinstall": "npx simple-git-hooks", "postinstall": "npx simple-git-hooks && turbo run stub",
"sizecheck": "npx vite-bundle-visualizer" "sizecheck": "npx vite-bundle-visualizer"
}, },
"dependencies": { "dependencies": {

File diff suppressed because it is too large Load Diff

@ -53,6 +53,7 @@ declare global {
const isRef: typeof import('vue')['isRef'] const isRef: typeof import('vue')['isRef']
const login: typeof import('./api/auth/auth')['login'] const login: typeof import('./api/auth/auth')['login']
const loginByCode: typeof import('./api/auth/auth')['loginByCode'] const loginByCode: typeof import('./api/auth/auth')['loginByCode']
const login: typeof import('./api/auth/auth')['login']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const markRaw: typeof import('vue')['markRaw'] const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick'] const nextTick: typeof import('vue')['nextTick']
@ -367,6 +368,7 @@ declare module 'vue' {
readonly isRef: UnwrapRef<typeof import('vue')['isRef']> readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']> readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']>
readonly loginByCode: UnwrapRef<typeof import('./api/auth/auth')['loginByCode']> readonly loginByCode: UnwrapRef<typeof import('./api/auth/auth')['loginByCode']>
readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']> readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']> readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']> readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
@ -675,6 +677,7 @@ declare module '@vue/runtime-core' {
readonly isRef: UnwrapRef<typeof import('vue')['isRef']> readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']> readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']>
readonly loginByCode: UnwrapRef<typeof import('./api/auth/auth')['loginByCode']> readonly loginByCode: UnwrapRef<typeof import('./api/auth/auth')['loginByCode']>
readonly login: UnwrapRef<typeof import('./api/auth/auth')['login']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']> readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']> readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']> readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>

44
src/types/env.d.ts vendored

@ -1,20 +1,36 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {
// 是否开启Mock /** 项目基本地址 */
readonly VITE_USE_MOCK:boolean readonly VITE_BASE_URL: string
// public path /** 项目名称 */
readonly VITE_PUBLIC_PATH:string readonly VITE_APP_NAME: string
// 全局项目标题 /** 项目标题 */
readonly VITE_TITLE:string readonly VITE_APP_TITLE: string
// API访问地址 /** 项目描述 */
readonly VITE_API_URL:string readonly VITE_APP_DESC: string
// 上传地址
readonly VITE_UPLOAD_URL:string /** API访问地址 */
// API前缀 readonly VITE_API_URL: string
readonly VITE_API_URL_PREFIX:string /** 上传地址 */
// 项目描述 readonly VITE_UPLOAD_URL: string
readonly VITE_DESCRIPTION:string /** API前缀 */
readonly VITE_API_URL_PREFIX: string
/** 开启请求代理 */
readonly VITE_HTTP_PROXY: boolean
/** 是否开启打包文件大小结果分析 */
readonly VITE_VISUALIZER: boolean
/** 是否开启打包压缩 */
readonly VITE_COMPRESS: boolean
/** 压缩算法类型 */
readonly VITE_COMPRESS_TYPE: 'gzip' | 'brotliCompress' | 'deflate' | 'deflateRaw'
/** 是否应用pwa */
readonly VITE_PWA: boolean
/** 是否启用Markdown插件,markdown生成html */
readonly VITE_MARKDOWN: boolean
// 是否开启Mock
readonly VITE_OPEN_MOCK: boolean
} }
interface ImportMeta {readonly env: ImportMetaEnv} interface ImportMeta {readonly env: ImportMetaEnv}

@ -1,12 +1,55 @@
declare type Recordable<T = any> = Record<string, T>; /**
declare type ReadonlyRecordable<T = any> = { *
readonly [key: string]: T; */
}; declare type Recordable<T = any> = Record<string, T>
declare type Nullable<T> = T | null; /**
declare type NonNullable<T> = T extends null | undefined ? never : T; *
declare type Indexable<T = any> = { */
[key: string]: T; declare interface ReadonlyRecordable<T = any> {
}; readonly [key: string]: T
}
/**
* T | null
*/
declare type Nullable<T> = T | null
/**
* T | Not null
*/
declare type NonNullable<T> = T extends null | undefined ? never : T
declare interface Indexable<T = any> {
[key: string]: T
}
declare type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>;
}
/**
*
*/
declare type AnyPromiseFunction = (...arg: any[]) => PromiseLike<any>
/**
*
*/
declare type AnyNormalFunction = (...arg: any[]) => any
/**
*
*/
declare type AnyFunction = AnyNormalFunction | AnyPromiseFunction
/**
* setTimeout
*/
type TimeoutHandle = ReturnType<typeof setTimeout>
/**
* setInterval
*/
type IntervalHandle = ReturnType<typeof setInterval>
declare type FormType = 'create' | 'update' declare type FormType = 'create' | 'update'

@ -1,20 +1,22 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": ".",
"module": "ESNext",
"target": "ESNext", "target": "ESNext",
"lib": ["DOM", "ESNext"], "lib": [
"strict": true, "DOM",
"esModuleInterop": true, "ESNext"
],
"jsx": "preserve", "jsx": "preserve",
"skipLibCheck": true, "module": "ESNext",
"isolatedModules": true,
"moduleResolution": "node", "moduleResolution": "node",
"resolveJsonModule": true, "baseUrl": ".",
"noUnusedLocals": true, "paths": {
"strictNullChecks": true, "~/*": [
"allowJs": true, "src/*"
"forceConsistentCasingInFileNames": true, ],
"#/*": [
"src/types/*"
]
},
"types": [ "types": [
"vitest", "vitest",
"vite/client", "vite/client",
@ -25,11 +27,18 @@
"vite-plugin-pwa/client", "vite-plugin-pwa/client",
"unplugin-vue-macros/macros-global", "unplugin-vue-macros/macros-global",
"naive-ui", "naive-ui",
"naive-ui/volar"
], ],
"paths": { "resolveJsonModule": true,
"~/*": ["src/*"], "allowJs": true,
"#/*": ["src/types/*"] "isolatedModules": true,
} "allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"skipLibCheck": true
}, },
"vueCompilerOptions": { "vueCompilerOptions": {
"plugins": [ "plugins": [
@ -38,10 +47,22 @@
"@vue-macros/volar/short-vmodel" "@vue-macros/volar/short-vmodel"
] ]
}, },
"exclude": ["dist", "node_modules", "cypress"], "include": [
// "include": [ "tests/**/*.ts",
// // "src/**/*", "src/**/*.ts",
// // "src/types/**/*.d.ts", "src/**/*.d.ts",
// // "src/**/types/**/*.d.ts" "src/**/*.tsx",
// ] "src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"mock/**/*.ts",
"vite.config.ts"
],
"exclude": [
"dist",
"node_modules",
"cypress"
]
} }

@ -0,0 +1,18 @@
{
"$schema": "https://turborepo.org/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"stub": {},
"lint": {},
"clean": {
"cache": false
},
"dev": {
"cache": false,
"persistent": true
}
}
}

@ -1,196 +1,65 @@
import path from 'node:path' import path from 'node:path'
import { defineConfig } from 'vite' import process from 'node:process'
import Vue from '@vitejs/plugin-vue' import { setupVitePlugins } from 'build/plugins'
import Pages from 'vite-plugin-pages' import type { ConfigEnv } from 'vite'
import generateSitemap from 'vite-ssg-sitemap' import { defineConfig, loadEnv } from 'vite'
import Layouts from 'vite-plugin-vue-layouts'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Markdown from 'unplugin-vue-markdown/vite'
import VueMacros from 'unplugin-vue-macros/vite'
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
import { VitePWA } from 'vite-plugin-pwa'
import VueDevTools from 'vite-plugin-vue-devtools'
import LinkAttributes from 'markdown-it-link-attributes'
import Unocss from 'unocss/vite'
import Shiki from 'markdown-it-shiki'
import WebfontDownload from 'vite-plugin-webfont-dl'
// custom
import { transformShortVmodel } from '@vue-macros/short-vmodel'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({ import generateSitemap from 'vite-ssg-sitemap'
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
'#/': `${path.resolve(__dirname, 'src/types')}/`,
},
},
plugins: [ export default defineConfig(({ command, mode }: ConfigEnv) => {
VueMacros({ const viteEnv = loadEnv(mode, process.cwd()) as unknown as ImportMetaEnv
plugins: { return {
vue: Vue({ base: viteEnv.VITE_BASE_URL,
include: [/\.vue$/, /\.md$/], resolve: {
reactivityTransform: true, alias: {
template: { '~/': `${path.resolve(__dirname, 'src')}/`,
compilerOptions: { '#/': `${path.resolve(__dirname, 'src/types')}/`,
nodeTransforms: [
transformShortVmodel({ prefix: '::' }),
],
},
},
}),
}, },
}), },
// https://github.com/hannoeru/vite-plugin-pages
Pages({
extensions: ['vue', 'md'],
}),
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
Layouts(),
// https://github.com/antfu/unplugin-auto-import plugins: setupVitePlugins(viteEnv),
AutoImport({
imports: [
'vue',
'vue-router',
'vue-i18n',
'vue/macros',
'@vueuse/head',
'@vueuse/core',
{
'naive-ui': [
'useDialog',
'useMessage',
'useNotification',
'useLoadingBar',
],
},
],
dts: 'src/auto-imports.d.ts',
dirs: [
'src/composables',
'src/stores',
'src/types',
'src/api',
'src/api/**',
],
vueTemplate: true,
resolvers: [
NaiveUiResolver(),
],
}),
// https://github.com/antfu/unplugin-vue-components server: {
Components({ host: '0.0.0.0',
// allow auto load markdown components under `./src/components/` port: 3200,
extensions: ['vue', 'md'], },
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
dts: 'src/components.d.ts',
resolvers: [
NaiveUiResolver(),
],
}),
// https://github.com/antfu/unocss optimizeDeps: {
// see uno.config.ts for config include: [],
Unocss(), },
// https://github.com/antfu/vite-plugin-vue-markdown // https://github.com/vitest-dev/vitest
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite test: {
Markdown({ include: ['test/**/*.test.ts'],
wrapperClasses: 'prose prose-sm m-auto text-left', environment: 'jsdom',
headEnabled: true, deps: {
markdownItSetup(md) { inline: ['@vue', '@vueuse', 'vue-demi'],
// https://prismjs.com/
md.use(Shiki, {
theme: {
light: 'vitesse-light',
dark: 'vitesse-dark',
},
})
md.use(LinkAttributes, {
matcher: (link: string) => /^https?:\/\//.test(link),
attrs: {
target: '_blank',
rel: 'noopener',
},
})
}, },
}), },
// https://github.com/antfu/vite-plugin-pwa // https://github.com/antfu/vite-ssg
VitePWA({ ssgOptions: {
registerType: 'autoUpdate', script: 'async',
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'], formatting: 'minify',
manifest: { crittersOptions: {
name: 'Vitesse', reduceInlineStyles: false,
short_name: 'Vitesse', },
theme_color: '#ffffff', onFinished() {
icons: [ generateSitemap()
{
src: '/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
}, },
}),
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n
VueI18n({
runtimeOnly: true,
compositionOnly: true,
fullInstall: true,
include: [path.resolve(__dirname, 'locales/**')],
}),
// https://github.com/feat-agency/vite-plugin-webfont-dl
WebfontDownload(),
// https://github.com/webfansplz/vite-plugin-vue-devtools
VueDevTools(),
],
// https://github.com/vitest-dev/vitest
test: {
include: ['test/**/*.test.ts'],
environment: 'jsdom',
deps: {
inline: ['@vue', '@vueuse', 'vue-demi'],
}, },
},
// https://github.com/antfu/vite-ssg ssr: {
ssgOptions: { // TODO: workaround until they support native ESM
script: 'async', noExternal: ['workbox-window', /vue-i18n/],
formatting: 'minify',
crittersOptions: {
reduceInlineStyles: false,
},
onFinished() {
generateSitemap()
}, },
},
ssr: { build: {
// TODO: workaround until they support native ESM reportCompressedSize: false,
noExternal: ['workbox-window', /vue-i18n/], sourcemap: false,
}, commonjsOptions: {
ignoreTryCatch: false,
},
},
}
}) })

Loading…
Cancel
Save