mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 00:26:20 +08:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ccaa32125a | ||
![]() |
0619faf61e | ||
![]() |
b6415fad2d | ||
![]() |
d3ed6757ac | ||
![]() |
27ffc9e71b | ||
![]() |
bf8a5ffb5d | ||
![]() |
8ed2adb916 | ||
![]() |
43224a4643 | ||
![]() |
f13fda408b | ||
![]() |
530159140c | ||
![]() |
e544119aa3 | ||
![]() |
8313be8e08 | ||
![]() |
d5f355120a |
15
.github/CODEOWNERS
vendored
15
.github/CODEOWNERS
vendored
@@ -1,7 +1,14 @@
|
||||
# default onwer
|
||||
* anncwb@126.com
|
||||
* anncwb@126.com vince292007@gmail.com
|
||||
|
||||
# vben core onwer
|
||||
/packages/@core/ anncwb@126.com
|
||||
/internal/ anncwb@126.com
|
||||
/scripts/ anncwb@126.com
|
||||
/.github/ anncwb@126.com vince292007@gmail.com
|
||||
/.vscode/ anncwb@126.com vince292007@gmail.com
|
||||
/packages/ anncwb@126.com vince292007@gmail.com
|
||||
/packages/@core/ anncwb@126.com vince292007@gmail.com
|
||||
/internal/ anncwb@126.com vince292007@gmail.com
|
||||
/scripts/ anncwb@126.com vince292007@gmail.com
|
||||
|
||||
# vben team onwer
|
||||
apps/ anncwb@126.com vince292007@gmail.com @vbenjs/team-v5
|
||||
docs/ anncwb@126.com vince292007@gmail.com @vbenjs/team-v5
|
||||
|
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -14,8 +14,8 @@ body:
|
||||
label: Version
|
||||
description: What version of our software are you running?
|
||||
options:
|
||||
- Vben Admin Pro
|
||||
- Vben Admin
|
||||
- Vben Admin V5
|
||||
- Vben Admin V2
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
|
@@ -1,4 +1,5 @@
|
||||
name: Dependabot post-update
|
||||
# name: Dependabot post-update
|
||||
name: Build detection
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
@@ -14,7 +15,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
post-update:
|
||||
if: ${{ github.actor == 'dependabot[bot]' }}
|
||||
# if: ${{ github.actor == 'dependabot[bot]' }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -43,7 +44,6 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Test and Build
|
||||
- name: Build
|
||||
run: |
|
||||
pnpm run test:unit
|
||||
pnpm run build
|
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- "releases/*"
|
||||
|
||||
permissions:
|
||||
@@ -25,8 +24,8 @@ jobs:
|
||||
node-version: [20]
|
||||
os:
|
||||
- ubuntu-latest
|
||||
# - macos-latest
|
||||
# - windows-latest
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
7
.github/workflows/deploy.yml
vendored
7
.github/workflows/deploy.yml
vendored
@@ -24,7 +24,14 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-antd/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-antd/.env.production
|
||||
cat ./apps/web-antd/.env.production
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-ele/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-ele/.env.production
|
||||
cat ./apps/web-ele/.env.production
|
||||
sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-naive/.env.production
|
||||
sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-naive/.env.production
|
||||
cat ./apps/web-naive/.env.production
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
3
.github/workflows/semantic-pull-request.yml
vendored
3
.github/workflows/semantic-pull-request.yml
vendored
@@ -9,17 +9,18 @@ on:
|
||||
|
||||
jobs:
|
||||
main:
|
||||
if: github.repository == 'vitejs/vite'
|
||||
runs-on: ubuntu-latest
|
||||
name: Semantic Pull Request
|
||||
steps:
|
||||
- name: Validate PR title
|
||||
uses: amannn/action-semantic-pull-request@v5
|
||||
with:
|
||||
wip: true
|
||||
subjectPattern: ^(?![A-Z]).+$
|
||||
subjectPatternError: |
|
||||
The subject "{subject}" found in the pull request title "{title}"
|
||||
didn't match the configured pattern. Please ensure that the subject
|
||||
doesn't start with an uppercase character.
|
||||
requireScope: false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
@@ -1 +1,20 @@
|
||||
export { default } from '@vben/lint-staged-config';
|
||||
export default {
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'eslint --cache --fix',
|
||||
],
|
||||
'*.{scss,less,styl,html,vue,css}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'*.md': ['prettier --cache --ignore-unknown --write'],
|
||||
'*.vue': [
|
||||
'prettier --write',
|
||||
'eslint --cache --fix',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
|
||||
'prettier --cache --write--parser json',
|
||||
],
|
||||
'package.json': ['prettier --cache --write'],
|
||||
};
|
||||
|
1
.npmrc
1
.npmrc
@@ -3,7 +3,6 @@ public-hoist-pattern[]=husky
|
||||
public-hoist-pattern[]=eslint
|
||||
public-hoist-pattern[]=prettier
|
||||
public-hoist-pattern[]=prettier-plugin-tailwindcss
|
||||
public-hoist-pattern[]=lint-staged
|
||||
public-hoist-pattern[]=stylelint
|
||||
public-hoist-pattern[]=*postcss*
|
||||
public-hoist-pattern[]=@commitlint/*
|
||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -139,8 +139,6 @@
|
||||
"typescript.preferences.preferTypeOnlyAutoImports": true,
|
||||
"typescript.preferences.includePackageJsonAutoImports": "on",
|
||||
|
||||
// Enable the ESlint flat config support
|
||||
"eslint.experimental.useFlatConfig": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"typescript",
|
||||
|
@@ -21,7 +21,7 @@ RUN echo "Builder Success 🎉"
|
||||
FROM nginx:stable-alpine as production
|
||||
|
||||
RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf
|
||||
COPY --from=builder /app/apps/antd-view/dist /usr/share/nginx/html
|
||||
COPY --from=builder /app/apps/web-antd/dist /usr/share/nginx/html
|
||||
|
||||
COPY ./deploy/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
|
@@ -25,7 +25,7 @@ function warning() {
|
||||
}
|
||||
function success() {
|
||||
ElMessage.success(
|
||||
"'Cause you walked hand in hand With another man in my place",
|
||||
'Cause you walked hand in hand With another man in my place',
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||
LOG_FILE=${SCRIPT_DIR}/build-local-docker-image.log
|
||||
ERROR=""
|
||||
IMAGE_NAME="vben-admin-pro-local"
|
||||
IMAGE_NAME="vben-admin-local"
|
||||
|
||||
function stop_and_remove_container() {
|
||||
# Stop and remove the existing container
|
||||
|
@@ -40,6 +40,7 @@
|
||||
"nocheck",
|
||||
"prefixs",
|
||||
"vitepress",
|
||||
"antdv",
|
||||
"ependencies",
|
||||
"vite",
|
||||
"echarts",
|
||||
|
@@ -72,7 +72,7 @@ const { b, e, is } = useNamespace('menu');
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
// 如果你在应用内使用,这行代码可以省略,已经在所有的应用内全局引入了
|
||||
@import (reference) '@vben/styles/global';
|
||||
@import '@vben/styles/global';
|
||||
@include b('menu') {
|
||||
color: black;
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
## 原理
|
||||
|
||||
由 `vite-plugin-inject-app-loading` 插件实现,插件会在每个页面的注入一个全局的 loading html。
|
||||
由 `vite-plugin-inject-app-loading` 插件实现,插件会在每个应用的注入一个全局的 `loading html`。
|
||||
|
||||
## 关闭
|
||||
|
||||
|
@@ -14,3 +14,4 @@
|
||||
6. 自行适配组件库的主题,与 `Vben Admin` 契合。
|
||||
7. 调整 `.env` 内的应用名
|
||||
8. 在大仓根目录增加 `dev:xxx` 脚本
|
||||
9. 执行 `pnpm install` 安装依赖
|
||||
|
@@ -25,36 +25,52 @@ features:
|
||||
- icon: 🚀
|
||||
title: 最新技术栈
|
||||
details: 基于 Vue3、Pinia、Vue Router、TypeScript、等最新技术栈。
|
||||
link: /guide/introduction/quick-start
|
||||
linkText: 快速开始
|
||||
- icon: 🦄
|
||||
title: 丰富的配置
|
||||
details: 企业级中后台前端解决方案,提供丰富的组件和模板以及 N 种偏好设置组合方案。
|
||||
# link: /
|
||||
# linkText: x
|
||||
link: /guide/essentials/settings
|
||||
linkText: 配置文档
|
||||
- icon: 🎨
|
||||
title: 主题定制
|
||||
details: 通过简单的配置,即可实现各种主题切换,满足个性化需求。
|
||||
link: /guide/in-depth/theme
|
||||
linkText: 主题文档
|
||||
- icon: 🌐
|
||||
title: 国际化
|
||||
details: 内置国际化方案,支持多语言切换,满足国际化需求。
|
||||
link: /guide/in-depth/locale
|
||||
linkText: 国际化文档
|
||||
- icon: 🔐
|
||||
title: 权限管理
|
||||
details: 内置权限管理方案,支持多种权限控制方式,满足各种权限需求。
|
||||
link: /guide/in-depth/access
|
||||
linkText: 权限文档
|
||||
- title: Vite
|
||||
icon:
|
||||
src: /logos/vite.svg
|
||||
details: 现代化的前端构建工具,快速冷启动,瞬间热更新。
|
||||
link: https://vitejs.dev/
|
||||
linkText: 官方站点
|
||||
- title: Shadcn UI
|
||||
icon:
|
||||
src: /logos/shadcn-ui.svg
|
||||
details: 核心基于 Shadcn UI + Tailwindcss,业务可支持任意的 UI 框架。
|
||||
link: https://www.shadcn-vue.com/
|
||||
linkText: 官方站点
|
||||
- title: Turbo Repo
|
||||
icon:
|
||||
src: /logos/turborepo.svg
|
||||
details: 规范且标准的大仓架构,使用 pnpm + monorepo + turbo 工程管理模式,提供企业级开发规范。
|
||||
link: https://turbo.build/
|
||||
linkText: 官方站点
|
||||
- title: Nitro Mock Server
|
||||
icon:
|
||||
src: /logos/nitro.svg
|
||||
details: 内置 Nitro Mock 服务,让你的 mock 服务更加强大。
|
||||
link: https://nitro.unjs.io/
|
||||
linkText: 官方站点
|
||||
---
|
||||
|
||||
<!-- <script setup>
|
||||
|
@@ -1,7 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['src/index'],
|
||||
});
|
@@ -1,5 +1,3 @@
|
||||
import type { UserConfig } from 'cz-git';
|
||||
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
import { getPackagesSync } from '@vben/node-utils';
|
||||
@@ -27,7 +25,10 @@ const scopeComplete = execSync('git status --porcelain || true')
|
||||
?.match(/src%%((\w|-)*)/)?.[1]
|
||||
?.replace(/s$/, '');
|
||||
|
||||
const userConfig: UserConfig = {
|
||||
/**
|
||||
* @type {import('cz-git').UserConfig}
|
||||
*/
|
||||
const userConfig = {
|
||||
extends: ['@commitlint/config-conventional'],
|
||||
plugins: ['commitlint-plugin-function-rules'],
|
||||
prompt: {
|
||||
@@ -46,7 +47,6 @@ const userConfig: UserConfig = {
|
||||
defaultScope: scopeComplete,
|
||||
// English
|
||||
typesAppend: [
|
||||
{ name: 'wip: work in process', value: 'wip' },
|
||||
{ name: 'workflow: workflow improvements', value: 'workflow' },
|
||||
{ name: 'types: type definition file changes', value: 'types' },
|
||||
],
|
||||
@@ -106,7 +106,7 @@ const userConfig: UserConfig = {
|
||||
'function-rules/scope-enum': [
|
||||
2, // level: error
|
||||
'always',
|
||||
(parsed: { scope: string }) => {
|
||||
(parsed) => {
|
||||
if (!parsed.scope || allowedScopes.includes(parsed.scope)) {
|
||||
return [true];
|
||||
}
|
@@ -11,20 +11,15 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./index.mjs",
|
||||
"module": "./index.mjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
"import": "./index.mjs",
|
||||
"default": "./index.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/node.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@@ -43,7 +43,7 @@
|
||||
"eslint-plugin-jsonc": "^2.16.0",
|
||||
"eslint-plugin-n": "^17.10.1",
|
||||
"eslint-plugin-no-only-tests": "^3.1.0",
|
||||
"eslint-plugin-perfectionist": "^3.0.0",
|
||||
"eslint-plugin-perfectionist": "^3.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-regexp": "^2.6.0",
|
||||
"eslint-plugin-unicorn": "^55.0.0",
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function comments(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function comments(): Promise<Linter.Config[]> {
|
||||
const [pluginComments] = await Promise.all([
|
||||
// @ts-expect-error - no types
|
||||
import('eslint-plugin-eslint-comments'),
|
||||
interopDefault(import('eslint-plugin-eslint-comments')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function disableds(): Promise<Linter.FlatConfig[]> {
|
||||
export async function disableds(): Promise<Linter.Config[]> {
|
||||
return [
|
||||
{
|
||||
files: ['**/__tests__/**/*.?([cm])[jt]s?(x)'],
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function ignores(): Promise<Linter.FlatConfig[]> {
|
||||
export async function ignores(): Promise<Linter.Config[]> {
|
||||
return [
|
||||
{
|
||||
ignores: [
|
||||
|
@@ -6,7 +6,7 @@ import js from '@eslint/js';
|
||||
import pluginUnusedImports from 'eslint-plugin-unused-imports';
|
||||
import globals from 'globals';
|
||||
|
||||
export async function javascript(): Promise<Linter.FlatConfig[]> {
|
||||
export async function javascript(): Promise<Linter.Config[]> {
|
||||
return [
|
||||
{
|
||||
languageOptions: {
|
||||
|
@@ -1,14 +1,15 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function jsdoc(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function jsdoc(): Promise<Linter.Config[]> {
|
||||
const [pluginJsdoc] = await Promise.all([
|
||||
import('eslint-plugin-jsdoc'),
|
||||
interopDefault(import('eslint-plugin-jsdoc')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
{
|
||||
plugins: {
|
||||
// @ts-expect-error - no types
|
||||
jsdoc: pluginJsdoc,
|
||||
},
|
||||
rules: {
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function jsonc(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function jsonc(): Promise<Linter.Config[]> {
|
||||
const [pluginJsonc, parserJsonc] = await Promise.all([
|
||||
import('eslint-plugin-jsonc'),
|
||||
import('jsonc-eslint-parser'),
|
||||
interopDefault(import('eslint-plugin-jsonc')),
|
||||
interopDefault(import('jsonc-eslint-parser')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function node(): Promise<Linter.FlatConfig[]> {
|
||||
const [pluginNode] = await Promise.all([import('eslint-plugin-n')] as const);
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function node(): Promise<Linter.Config[]> {
|
||||
const pluginNode = await interopDefault(import('eslint-plugin-n'));
|
||||
|
||||
return [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@ import type { Linter } from 'eslint';
|
||||
|
||||
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
||||
|
||||
export async function perfectionist(): Promise<Linter.FlatConfig[]> {
|
||||
export async function perfectionist(): Promise<Linter.Config[]> {
|
||||
return [
|
||||
perfectionistPlugin.configs['recommended-natural'],
|
||||
{
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function prettier(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function prettier(): Promise<Linter.Config[]> {
|
||||
const [pluginPrettier] = await Promise.all([
|
||||
import('eslint-plugin-prettier'),
|
||||
interopDefault(import('eslint-plugin-prettier')),
|
||||
] as const);
|
||||
return [
|
||||
{
|
||||
|
@@ -1,8 +1,10 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function regexp(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function regexp(): Promise<Linter.Config[]> {
|
||||
const [pluginRegexp] = await Promise.all([
|
||||
import('eslint-plugin-regexp'),
|
||||
interopDefault(import('eslint-plugin-regexp')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,10 +1,12 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function test(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function test(): Promise<Linter.Config[]> {
|
||||
const [pluginTest, pluginNoOnlyTests] = await Promise.all([
|
||||
import('eslint-plugin-vitest'),
|
||||
interopDefault(import('eslint-plugin-vitest')),
|
||||
// @ts-expect-error - no types
|
||||
import('eslint-plugin-no-only-tests'),
|
||||
interopDefault(import('eslint-plugin-no-only-tests')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function turbo(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function turbo(): Promise<Linter.Config[]> {
|
||||
const [pluginTurbo] = await Promise.all([
|
||||
// @ts-expect-error - no types
|
||||
import('eslint-config-turbo'),
|
||||
interopDefault(import('eslint-config-turbo')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,10 +1,12 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function typescript(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function typescript(): Promise<Linter.Config[]> {
|
||||
const [pluginTs, parserTs] = await Promise.all([
|
||||
import('@typescript-eslint/eslint-plugin'),
|
||||
interopDefault(import('@typescript-eslint/eslint-plugin')),
|
||||
// @ts-expect-error missing types
|
||||
import('@typescript-eslint/parser'),
|
||||
interopDefault(import('@typescript-eslint/parser')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function unicorn(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function unicorn(): Promise<Linter.Config[]> {
|
||||
const [pluginUnicorn] = await Promise.all([
|
||||
// @ts-expect-error - missing types
|
||||
import('eslint-plugin-unicorn'),
|
||||
interopDefault(import('eslint-plugin-unicorn')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
@@ -1,12 +1,14 @@
|
||||
import type { Linter } from 'eslint';
|
||||
|
||||
export async function vue(): Promise<Linter.FlatConfig[]> {
|
||||
import { interopDefault } from '../util';
|
||||
|
||||
export async function vue(): Promise<Linter.Config[]> {
|
||||
const [pluginVue, parserVue, parserTs] = await Promise.all([
|
||||
// @ts-expect-error missing types
|
||||
import('eslint-plugin-vue'),
|
||||
import('vue-eslint-parser'),
|
||||
interopDefault(import('eslint-plugin-vue')),
|
||||
interopDefault(import('vue-eslint-parser')),
|
||||
// @ts-expect-error missing types
|
||||
import('@typescript-eslint/parser'),
|
||||
interopDefault(import('@typescript-eslint/parser')),
|
||||
] as const);
|
||||
|
||||
return [
|
||||
|
8
internal/lint-configs/eslint-config/src/util.ts
Normal file
8
internal/lint-configs/eslint-config/src/util.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type Awaitable<T> = Promise<T> | T;
|
||||
|
||||
export async function interopDefault<T>(
|
||||
m: Awaitable<T>,
|
||||
): Promise<T extends { default: infer U } ? U : T> {
|
||||
const resolved = await m;
|
||||
return (resolved as any).default || resolved;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['src/index'],
|
||||
});
|
@@ -1,33 +0,0 @@
|
||||
{
|
||||
"name": "@vben/lint-staged-config",
|
||||
"version": "5.0.0",
|
||||
"private": true,
|
||||
"homepage": "https://github.com/vbenjs/vue-vben-admin",
|
||||
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
|
||||
"directory": "internal/lint-configs/lint-staged-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"lint-staged": "^15.2.7"
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
export default {
|
||||
'*.{js,jsx,ts,tsx}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'eslint --cache --fix',
|
||||
],
|
||||
'*.{scss,less,styl,html,vue,css}': [
|
||||
'prettier --cache --ignore-unknown --write',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'*.md': ['prettier --cache --ignore-unknown --write'],
|
||||
'*.vue': [
|
||||
'prettier --write',
|
||||
'eslint --cache --fix',
|
||||
'stylelint --fix --allow-empty-input',
|
||||
],
|
||||
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
|
||||
'prettier --cache --write--parser json',
|
||||
],
|
||||
'package.json': ['prettier --cache --write'],
|
||||
};
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/node.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['src/index'],
|
||||
});
|
@@ -11,20 +11,14 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./index.mjs",
|
||||
"module": "./index.mjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
"default": "./index.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/node.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['src/index'],
|
||||
});
|
@@ -11,20 +11,15 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild --stub"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"main": "./index.mjs",
|
||||
"module": "./index.mjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.mjs"
|
||||
"import": "./index.mjs",
|
||||
"default": "./index.mjs"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/node.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@@ -35,7 +35,6 @@
|
||||
"dayjs": "^1.11.12",
|
||||
"execa": "^9.3.0",
|
||||
"find-up": "^7.0.0",
|
||||
"fs-extra": "^11.2.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"ora": "^8.0.1",
|
||||
"pkg-types": "^1.1.3",
|
||||
@@ -43,7 +42,6 @@
|
||||
"rimraf": "^6.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chalk": "^2.2.0",
|
||||
"@types/fs-extra": "^11.0.4"
|
||||
"@types/chalk": "^2.2.0"
|
||||
}
|
||||
}
|
||||
|
39
internal/node-utils/src/fs.ts
Normal file
39
internal/node-utils/src/fs.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
export async function outputJSON(
|
||||
filePath: string,
|
||||
data: any,
|
||||
spaces: number = 2,
|
||||
) {
|
||||
try {
|
||||
const dir = dirname(filePath);
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
const jsonData = JSON.stringify(data, null, spaces);
|
||||
await fs.writeFile(filePath, jsonData, 'utf8');
|
||||
} catch (error) {
|
||||
console.error('Error writing JSON file:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureFile(filePath: string) {
|
||||
try {
|
||||
const dir = dirname(filePath);
|
||||
await fs.mkdir(dir, { recursive: true });
|
||||
await fs.writeFile(filePath, '', { flag: 'a' });
|
||||
} catch (error) {
|
||||
console.error('Error ensuring file:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function readJSON(filePath: string) {
|
||||
try {
|
||||
const data = await fs.readFile(filePath, 'utf8');
|
||||
return JSON.parse(data);
|
||||
} catch (error) {
|
||||
console.error('Error reading JSON file:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
export * from './constants';
|
||||
export * from './date';
|
||||
export * from './fs';
|
||||
export * from './git';
|
||||
export { add as gitAdd, getStagedFiles } from './git';
|
||||
export { generatorContentHash } from './hash';
|
||||
@@ -11,7 +12,10 @@ export type { Package } from '@manypkg/get-packages';
|
||||
export { default as colors } from 'chalk';
|
||||
export { consola } from 'consola';
|
||||
export * from 'execa';
|
||||
export { default as fs } from 'fs-extra';
|
||||
|
||||
export { nanoid } from 'nanoid';
|
||||
|
||||
export { default as fs } from 'node:fs/promises';
|
||||
|
||||
export { type PackageJson, readPackageJSON } from 'pkg-types';
|
||||
export { rimraf } from 'rimraf';
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import fs from 'fs-extra';
|
||||
import fs from 'node:fs/promises';
|
||||
|
||||
import { format, getFileInfo, resolveConfig } from 'prettier';
|
||||
|
||||
async function prettierFormat(filepath: string) {
|
||||
@@ -12,7 +13,7 @@ async function prettierFormat(filepath: string) {
|
||||
parser: fileInfo.inferredParser as any,
|
||||
});
|
||||
if (output !== input) {
|
||||
fs.writeFileSync(filepath, output, 'utf8');
|
||||
await fs.writeFile(filepath, output, 'utf8');
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import type { Config } from 'tailwindcss';
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import { fs, getPackagesSync } from '@vben/node-utils';
|
||||
import { getPackagesSync } from '@vben/node-utils';
|
||||
|
||||
import { addDynamicIconSelectors } from '@iconify/tailwind';
|
||||
import typographyPlugin from '@tailwindcss/typography';
|
||||
|
@@ -15,8 +15,8 @@ import { getCommonConfig } from './common';
|
||||
|
||||
function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
|
||||
return defineConfig(async (config) => {
|
||||
const { appTitle, base, port, ...envConfig } = await loadAndConvertEnv();
|
||||
const options = await userConfigPromise?.(config);
|
||||
const { appTitle, base, port, ...envConfig } = await loadAndConvertEnv();
|
||||
const { command, mode } = config;
|
||||
const { application = {}, vite = {} } = options || {};
|
||||
const root = process.cwd();
|
||||
@@ -78,16 +78,16 @@ function defineApplicationConfig(userConfigPromise?: DefineApplicationOptions) {
|
||||
port,
|
||||
warmup: {
|
||||
// 预热文件
|
||||
clientFiles: ['./index.html', './src/{views,layouts}/*'],
|
||||
clientFiles: ['./index.html', './src/{views,layouts,router,store}/*'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mergedConfig = mergeConfig(
|
||||
const mergedCommonConfig = mergeConfig(
|
||||
await getCommonConfig(),
|
||||
applicationConfig,
|
||||
);
|
||||
return mergeConfig(mergedConfig, vite);
|
||||
return mergeConfig(mergedCommonConfig, vite);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ function createCssOptions(injectGlobalScss = true) {
|
||||
const relativePath = relative(root, filepath);
|
||||
// apps下的包注入全局样式
|
||||
if (relativePath.startsWith('apps/')) {
|
||||
return `@import (reference) "@vben/styles/global";\n${content}`;
|
||||
return `@import "@vben/styles/global";\n${content}`;
|
||||
}
|
||||
return content;
|
||||
},
|
||||
|
@@ -13,8 +13,8 @@ function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) {
|
||||
return defineConfig(async (config: ConfigEnv) => {
|
||||
const options = await userConfigPromise?.(config);
|
||||
const { command, mode } = config;
|
||||
const root = process.cwd();
|
||||
const { library = {}, vite = {} } = options || {};
|
||||
const root = process.cwd();
|
||||
const isBuild = command === 'build';
|
||||
|
||||
const plugins = await loadLibraryPlugins({
|
||||
@@ -52,8 +52,8 @@ function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) {
|
||||
plugins,
|
||||
};
|
||||
const commonConfig = await getCommonConfig();
|
||||
const mergedConfig = mergeConfig(commonConfig, packageConfig);
|
||||
return mergeConfig(mergedConfig, vite);
|
||||
const mergedConmonConfig = mergeConfig(commonConfig, packageConfig);
|
||||
return mergeConfig(mergedConmonConfig, vite);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -28,12 +28,12 @@ const getDefaultPwaOptions = (name: string): Partial<PwaPluginOptions> => ({
|
||||
const defaultImportmapOptions: ImportmapPluginOptions = {
|
||||
// 通过 Importmap CDN 方式引入,
|
||||
// 目前只有esm.sh源兼容性好一点,jspm.io对于 esm 入口要求高
|
||||
defaultProvider: 'jspm.io',
|
||||
defaultProvider: 'esm.sh',
|
||||
importmap: [
|
||||
{ name: 'vue' },
|
||||
{ name: 'pinia' },
|
||||
{ name: 'vue-router' },
|
||||
{ name: 'vue-i18n' },
|
||||
// { name: 'vue-i18n' },
|
||||
{ name: 'dayjs' },
|
||||
{ name: 'vue-demi' },
|
||||
],
|
||||
|
@@ -1,3 +1,3 @@
|
||||
# inject-app-loading
|
||||
|
||||
用于在应用加载时显示加载动画的插件。可自行选择加载动画的样式。
|
||||
用于在应用加载时显示加载动画的插件,可自行选择加载动画的样式。
|
||||
|
@@ -25,7 +25,7 @@
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.6s ease-out;
|
||||
transition: all 1s ease-out;
|
||||
}
|
||||
|
||||
.dark .loading {
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import fs from 'node:fs';
|
||||
import fsp from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
import { fs, readPackageJSON } from '@vben/node-utils';
|
||||
import { readPackageJSON } from '@vben/node-utils';
|
||||
|
||||
import { type PluginOption } from 'vite';
|
||||
|
||||
@@ -50,19 +52,15 @@ async function viteInjectAppLoadingPlugin(
|
||||
* 用于获取loading的html模板
|
||||
*/
|
||||
async function getLoadingRawByHtmlTemplate(loadingTemplate: string) {
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
const defaultLoadingPath = join(__dirname, './default-loading.html');
|
||||
// 支持在app内自定义loading模板,模版参考default-loading.html即可
|
||||
const appLoadingPath = join(process.cwd(), loadingTemplate);
|
||||
let loadingPath = defaultLoadingPath;
|
||||
let appLoadingPath = join(process.cwd(), loadingTemplate);
|
||||
|
||||
if (fs.existsSync(appLoadingPath)) {
|
||||
loadingPath = appLoadingPath;
|
||||
return;
|
||||
if (!fs.existsSync(appLoadingPath)) {
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url));
|
||||
appLoadingPath = join(__dirname, './default-loading.html');
|
||||
}
|
||||
|
||||
const htmlRaw = await fs.readFile(loadingPath, 'utf8');
|
||||
return htmlRaw;
|
||||
return await fsp.readFile(appLoadingPath, 'utf8');
|
||||
}
|
||||
|
||||
export { viteInjectAppLoadingPlugin };
|
||||
|
@@ -74,13 +74,13 @@ interface CommonPluginOptions {
|
||||
}
|
||||
|
||||
interface ApplicationPluginOptions extends CommonPluginOptions {
|
||||
/** 开启 gzip 压缩 */
|
||||
/** 开启 gzip|brotli 压缩 */
|
||||
compress?: boolean;
|
||||
/** 压缩类型 */
|
||||
compressTypes?: ('brotli' | 'gzip')[];
|
||||
/** 在构建的时候抽离配置文件 */
|
||||
extraAppConfig?: boolean;
|
||||
/** html 插件配置 */
|
||||
/** 是否开启html插件 */
|
||||
html?: boolean;
|
||||
/** 是否开启i18n */
|
||||
i18n?: boolean;
|
||||
@@ -98,7 +98,7 @@ interface ApplicationPluginOptions extends CommonPluginOptions {
|
||||
nitroMock?: boolean;
|
||||
/** nitro mock 插件配置 */
|
||||
nitroMockOptions?: NitroMockPluginOptions;
|
||||
/** dev是否开启mock服务 */
|
||||
/** 开启控制台自定义打印 */
|
||||
print?: boolean;
|
||||
/** 打印插件配置 */
|
||||
printInfoMap?: PrintPluginOptions['infoMap'];
|
||||
|
@@ -59,10 +59,9 @@
|
||||
"@changesets/cli": "^2.27.7",
|
||||
"@ls-lint/ls-lint": "^2.2.3",
|
||||
"@types/jsdom": "^21.1.7",
|
||||
"@types/node": "^22.0.2",
|
||||
"@types/node": "^22.1.0",
|
||||
"@vben/commitlint-config": "workspace:*",
|
||||
"@vben/eslint-config": "workspace:*",
|
||||
"@vben/lint-staged-config": "workspace:*",
|
||||
"@vben/prettier-config": "workspace:*",
|
||||
"@vben/stylelint-config": "workspace:*",
|
||||
"@vben/tailwind-config": "workspace:*",
|
||||
@@ -77,6 +76,7 @@
|
||||
"husky": "^9.1.4",
|
||||
"is-ci": "^3.0.1",
|
||||
"jsdom": "^24.1.1",
|
||||
"lint-staged": "^15.2.7",
|
||||
"rimraf": "^6.0.1",
|
||||
"tailwindcss": "^3.4.7",
|
||||
"turbo": "^2.0.11",
|
||||
|
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"lucide-vue-next": "^0.419.0",
|
||||
"lucide-vue-next": "^0.424.0",
|
||||
"vue": "^3.4.35"
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { defaultPreferences } from './config';
|
||||
import { isDarkTheme, PreferenceManager } from './preferences';
|
||||
import { PreferenceManager } from './preferences';
|
||||
import { isDarkTheme } from './update-css-variables';
|
||||
|
||||
describe('preferences', () => {
|
||||
let preferenceManager: PreferenceManager;
|
||||
|
@@ -19,14 +19,6 @@ const STORAGE_KEY = 'preferences';
|
||||
const STORAGE_KEY_LOCALE = `${STORAGE_KEY}-locale`;
|
||||
const STORAGE_KEY_THEME = `${STORAGE_KEY}-theme`;
|
||||
|
||||
function isDarkTheme(theme: string) {
|
||||
let dark = theme === 'dark';
|
||||
if (theme === 'auto') {
|
||||
dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
return dark;
|
||||
}
|
||||
|
||||
class PreferenceManager {
|
||||
private cache: null | StorageManager = null;
|
||||
// private flattenedState: Flatten<Preferences>;
|
||||
@@ -39,6 +31,7 @@ class PreferenceManager {
|
||||
constructor() {
|
||||
this.cache = new StorageManager();
|
||||
|
||||
// 避免频繁的操作缓存
|
||||
this.savePreferences = useDebounceFn(
|
||||
(preference: Preferences) => this._savePreferences(preference),
|
||||
150,
|
||||
@@ -58,7 +51,6 @@ class PreferenceManager {
|
||||
/**
|
||||
* 处理更新的键值
|
||||
* 根据更新的键值执行相应的操作。
|
||||
*
|
||||
* @param {DeepPartial<Preferences>} updates - 部分更新的偏好设置
|
||||
*/
|
||||
private handleUpdates(updates: DeepPartial<Preferences>) {
|
||||
@@ -124,7 +116,7 @@ class PreferenceManager {
|
||||
this.updatePreferences({
|
||||
theme: { mode: isDark ? 'dark' : 'light' },
|
||||
});
|
||||
updateCSSVariables(this.state);
|
||||
// updateCSSVariables(this.state);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -232,4 +224,4 @@ class PreferenceManager {
|
||||
}
|
||||
|
||||
const preferencesManager = new PreferenceManager();
|
||||
export { isDarkTheme, PreferenceManager, preferencesManager };
|
||||
export { PreferenceManager, preferencesManager };
|
||||
|
@@ -115,4 +115,4 @@ function isDarkTheme(theme: string) {
|
||||
return dark;
|
||||
}
|
||||
|
||||
export { updateCSSVariables };
|
||||
export { isDarkTheme, updateCSSVariables };
|
||||
|
@@ -2,7 +2,8 @@ import { computed } from 'vue';
|
||||
|
||||
import { diff } from '@vben-core/shared';
|
||||
|
||||
import { isDarkTheme, preferencesManager } from './preferences';
|
||||
import { preferencesManager } from './preferences';
|
||||
import { isDarkTheme } from './update-css-variables';
|
||||
|
||||
function usePreferences() {
|
||||
const preferences = preferencesManager.getPreferences();
|
||||
|
@@ -445,8 +445,8 @@ $namespace: vben;
|
||||
--menu-item-color: hsl(var(--foreground) / 80%);
|
||||
--menu-item-hover-color: hsl(var(--accent-foreground));
|
||||
--menu-item-hover-background-color: hsl(var(--accent));
|
||||
--menu-item-active-color: hsl(var(--primary-foreground));
|
||||
--menu-item-active-background-color: hsl(var(--primary));
|
||||
--menu-item-active-color: hsl(var(--accent-foreground));
|
||||
--menu-item-active-background-color: hsl(var(--accent));
|
||||
--menu-submenu-hover-color: hsl(var(--foreground));
|
||||
--menu-submenu-hover-background-color: hsl(var(--accent));
|
||||
--menu-submenu-active-color: hsl(var(--foreground));
|
||||
|
@@ -48,7 +48,7 @@
|
||||
"@vben-core/typings": "workspace:*",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"lucide-vue-next": "^0.419.0",
|
||||
"lucide-vue-next": "^0.424.0",
|
||||
"radix-vue": "^1.9.2",
|
||||
"vue": "^3.4.35"
|
||||
}
|
||||
|
@@ -209,7 +209,7 @@ export function useElementPlusDesignTokens() {
|
||||
'--el-text-color-primary': getCssVariableValue('--foreground'),
|
||||
'--el-text-color-regular': getCssVariableValue('--foreground'),
|
||||
};
|
||||
updateCSSVariables(variables, `__vben_ele_styles__`);
|
||||
updateCSSVariables(variables, `__vben_design_styles__`);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { MenuRecordRaw } from '@vben/types';
|
||||
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
import {
|
||||
ArrowDown,
|
||||
@@ -40,6 +40,7 @@ const props = withDefaults(
|
||||
|
||||
const [open, toggleOpen] = useToggle();
|
||||
const keyword = ref('');
|
||||
const searchInputRef = ref<HTMLInputElement>();
|
||||
|
||||
function handleClose() {
|
||||
open.value = false;
|
||||
@@ -54,6 +55,12 @@ whenever(cmd, () => {
|
||||
}
|
||||
});
|
||||
|
||||
whenever(open, () => {
|
||||
nextTick(() => {
|
||||
searchInputRef.value?.focus();
|
||||
});
|
||||
});
|
||||
|
||||
const preventDefaultBrowserSearchHotKey = (event: KeyboardEvent) => {
|
||||
if (event.key.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) {
|
||||
event.preventDefault();
|
||||
@@ -115,6 +122,7 @@ onMounted(() => {
|
||||
>
|
||||
<Search class="text-muted-foreground size-4" />
|
||||
<input
|
||||
ref="searchInputRef"
|
||||
v-model="keyword"
|
||||
:placeholder="$t('widgets.search.searchNavigate')"
|
||||
class="ring-none placeholder:text-muted-foreground w-[80%] rounded-md border border-none bg-transparent p-2 pl-0 text-sm outline-none ring-0 ring-offset-transparent focus-visible:ring-transparent"
|
||||
|
@@ -59,10 +59,10 @@ const styleItems = computed((): SelectOption[] => [
|
||||
<SwitchItem v-model="tabbarShowIcon" :disabled="!tabbarEnable">
|
||||
{{ $t('preferences.tabbar.icon') }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="tabbarShowRefresh" :disabled="!tabbarEnable">
|
||||
<SwitchItem v-model="tabbarShowMore" :disabled="!tabbarEnable">
|
||||
{{ $t('preferences.tabbar.showMore') }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="tabbarShowMore" :disabled="!tabbarEnable">
|
||||
<SwitchItem v-model="tabbarShowRefresh" :disabled="!tabbarEnable">
|
||||
{{ $t('preferences.tabbar.showRefresh') }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="tabbarShowMaximize" :disabled="!tabbarEnable">
|
||||
|
@@ -206,6 +206,7 @@ if (enableShortcutKey.value) {
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
v-if="preferences.app.enablePreferences"
|
||||
class="mx-1 flex cursor-pointer items-center rounded-sm py-1 leading-8"
|
||||
@click="handleOpenPreference"
|
||||
>
|
||||
|
@@ -3,6 +3,7 @@
|
||||
* 放在这里是而不是放在 index.html 的app标签内,是因为这样比较不会生硬,渲染过快可能会有闪烁
|
||||
* 通过先添加css动画隐藏,在动画结束后在移除loading节点来改善体验
|
||||
* 不好的地方是会增加一些代码量
|
||||
* 自定义loading可以见:https://doc.vben.pro/guide/in-depth/loading.html
|
||||
*/
|
||||
export function unmountGlobalLoading() {
|
||||
// 查找全局 loading 元素
|
||||
|
487
pnpm-lock.yaml
generated
487
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ export async function run(options: RunOptions) {
|
||||
|
||||
// 只显示有对应命令的包
|
||||
const selectPkgs = packages.filter((pkg) => {
|
||||
return (pkg?.packageJson as Record<string, any>).scripts?.[command];
|
||||
return (pkg?.packageJson as Record<string, any>)?.scripts?.[command];
|
||||
});
|
||||
|
||||
const selectPkg = await select<any, string>({
|
||||
|
@@ -6,9 +6,9 @@ import {
|
||||
colors,
|
||||
consola,
|
||||
findMonorepoRoot,
|
||||
fs,
|
||||
getPackages,
|
||||
gitAdd,
|
||||
outputJSON,
|
||||
prettierFormat,
|
||||
toPosixPath,
|
||||
} from '@vben/node-utils';
|
||||
@@ -38,7 +38,7 @@ async function createCodeWorkspace({
|
||||
|
||||
const monorepoRoot = findMonorepoRoot();
|
||||
const outputPath = join(monorepoRoot, CODE_WORKSPACE_FILE);
|
||||
await fs.outputJSON(outputPath, { folders }, { encoding: 'utf8', spaces });
|
||||
await outputJSON(outputPath, { folders }, spaces);
|
||||
|
||||
await prettierFormat(outputPath);
|
||||
if (autoCommit) {
|
||||
|
@@ -6,10 +6,12 @@ import { basename, dirname, join } from 'node:path';
|
||||
import {
|
||||
colors,
|
||||
consola,
|
||||
ensureFile,
|
||||
findMonorepoRoot,
|
||||
fs,
|
||||
generatorContentHash,
|
||||
getPackages,
|
||||
outputJSON,
|
||||
readJSON,
|
||||
UNICODE,
|
||||
} from '@vben/node-utils';
|
||||
|
||||
@@ -56,8 +58,8 @@ function getCacheFile() {
|
||||
|
||||
async function readCache(cacheFile: string) {
|
||||
try {
|
||||
await fs.ensureFile(cacheFile);
|
||||
return await fs.readJSON(cacheFile, { encoding: 'utf8' });
|
||||
await ensureFile(cacheFile);
|
||||
return await readJSON(cacheFile);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
@@ -73,7 +75,7 @@ async function runPublint(files: string[], { check }: PubLintCommandOptions) {
|
||||
const results = await Promise.all(
|
||||
lintFiles.map(async (file) => {
|
||||
try {
|
||||
const pkgJson = await fs.readJSON(file);
|
||||
const pkgJson = await readJSON(file);
|
||||
|
||||
if (pkgJson.private) {
|
||||
return null;
|
||||
@@ -106,7 +108,7 @@ async function runPublint(files: string[], { check }: PubLintCommandOptions) {
|
||||
}),
|
||||
);
|
||||
|
||||
await fs.outputJSON(cacheFile, cache);
|
||||
await outputJSON(cacheFile, cache);
|
||||
printResult(results, check);
|
||||
}
|
||||
|
||||
|
@@ -37,11 +37,6 @@
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
},
|
||||
"@vben/backend#dev": {
|
||||
"outputs": [],
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
},
|
||||
"typecheck": {
|
||||
"outputs": []
|
||||
}
|
||||
|
@@ -28,10 +28,6 @@
|
||||
"name": "@vben/eslint-config",
|
||||
"path": "internal/lint-configs/eslint-config",
|
||||
},
|
||||
{
|
||||
"name": "@vben/lint-staged-config",
|
||||
"path": "internal/lint-configs/lint-staged-config",
|
||||
},
|
||||
{
|
||||
"name": "@vben/prettier-config",
|
||||
"path": "internal/lint-configs/prettier-config",
|
||||
|
Reference in New Issue
Block a user