| | |
| | | .history |
| | | .vscode/extensions.json |
| | | .vscode/settings.json |
| | | internal/ |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | *.sh |
| | | node_modules |
| | | *.md |
| | | *.woff |
| | | *.ttf |
| | | .turbo |
| | | dist |
| | | package.json |
¶Ô±ÈÐÂÎļþ |
| | |
| | | module.exports = { |
| | | root: true, |
| | | extends: ['@vben/eslint-config/strict'], |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineBuildConfig } from 'unbuild'; |
| | | |
| | | export default defineBuildConfig({ |
| | | clean: true, |
| | | entries: ['src/index', 'src/strict'], |
| | | declaration: true, |
| | | rollup: { |
| | | emitCJS: true, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "@vben/eslint-config", |
| | | "version": "1.0.0", |
| | | "private": true, |
| | | "homepage": "https://github.com/vbenjs/vue-vben-admin", |
| | | "bugs": { |
| | | "url": "https://github.com/vbenjs/vue-vben-admin/issues" |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "git+https://github.com/vbenjs/vue-vben-admin.git", |
| | | "directory": "internal/eslint-config" |
| | | }, |
| | | "license": "MIT", |
| | | "type": "module", |
| | | "exports": { |
| | | ".": { |
| | | "types": "./dist/index.d.ts", |
| | | "import": "./dist/index.mjs", |
| | | "require": "./dist/index.cjs" |
| | | }, |
| | | "./strict": { |
| | | "types": "./dist/strict.d.ts", |
| | | "import": "./dist/strict.mjs", |
| | | "require": "./dist/strict.cjs" |
| | | } |
| | | }, |
| | | "main": "./dist/index.cjs", |
| | | "module": "./dist/index.mjs", |
| | | "types": "./dist/index.d.ts", |
| | | "files": [ |
| | | "dist" |
| | | ], |
| | | "scripts": { |
| | | "clean": "pnpm rimraf .turbo node_modules dist", |
| | | "lint": "pnpm eslint .", |
| | | "stub": "pnpm unbuild --stub" |
| | | }, |
| | | "devDependencies": { |
| | | "@typescript-eslint/eslint-plugin": "^7.0.1", |
| | | "@typescript-eslint/parser": "^7.0.1", |
| | | "eslint": "^8.56.0", |
| | | "eslint-config-prettier": "^9.1.0", |
| | | "eslint-plugin-import": "^2.29.1", |
| | | "eslint-plugin-prettier": "^5.1.3", |
| | | "eslint-plugin-simple-import-sort": "^12.0.0", |
| | | "eslint-plugin-vue": "^9.21.1", |
| | | "vue-eslint-parser": "^9.4.2" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | env: { |
| | | browser: true, |
| | | node: true, |
| | | es6: true, |
| | | }, |
| | | parser: 'vue-eslint-parser', |
| | | parserOptions: { |
| | | parser: '@typescript-eslint/parser', |
| | | ecmaVersion: 2020, |
| | | sourceType: 'module', |
| | | jsxPragma: 'React', |
| | | ecmaFeatures: { |
| | | jsx: true, |
| | | }, |
| | | project: './tsconfig.*?.json', |
| | | createDefaultProgram: false, |
| | | extraFileExtensions: ['.vue'], |
| | | }, |
| | | plugins: ['vue', '@typescript-eslint', 'import'], |
| | | extends: [ |
| | | 'eslint:recommended', |
| | | 'plugin:vue/vue3-recommended', |
| | | 'plugin:@typescript-eslint/recommended', |
| | | 'plugin:prettier/recommended', |
| | | ], |
| | | rules: { |
| | | 'no-unused-vars': 'off', |
| | | 'no-case-declarations': 'off', |
| | | 'no-use-before-define': 'off', |
| | | 'space-before-function-paren': 'off', |
| | | |
| | | 'import/first': 'error', |
| | | 'import/newline-after-import': 'error', |
| | | 'import/no-duplicates': 'error', |
| | | |
| | | '@typescript-eslint/no-unused-vars': [ |
| | | 'error', |
| | | { |
| | | argsIgnorePattern: '^_', |
| | | varsIgnorePattern: '^_', |
| | | }, |
| | | ], |
| | | '@typescript-eslint/ban-ts-ignore': 'off', |
| | | '@typescript-eslint/ban-ts-comment': 'off', |
| | | '@typescript-eslint/ban-types': 'off', |
| | | '@typescript-eslint/explicit-function-return-type': 'off', |
| | | '@typescript-eslint/no-explicit-any': 'off', |
| | | '@typescript-eslint/no-var-requires': 'off', |
| | | '@typescript-eslint/no-empty-function': 'off', |
| | | '@typescript-eslint/no-use-before-define': 'off', |
| | | '@typescript-eslint/no-non-null-assertion': 'off', |
| | | '@typescript-eslint/explicit-module-boundary-types': 'off', |
| | | 'vue/script-setup-uses-vars': 'error', |
| | | 'vue/no-reserved-component-names': 'off', |
| | | 'vue/custom-event-name-casing': 'off', |
| | | 'vue/attributes-order': 'off', |
| | | 'vue/one-component-per-file': 'off', |
| | | 'vue/html-closing-bracket-newline': 'off', |
| | | 'vue/max-attributes-per-line': 'off', |
| | | 'vue/multiline-html-element-content-newline': 'off', |
| | | 'vue/singleline-html-element-content-newline': 'off', |
| | | 'vue/attribute-hyphenation': 'off', |
| | | 'vue/require-default-prop': 'off', |
| | | 'vue/require-explicit-emits': 'off', |
| | | 'vue/html-self-closing': [ |
| | | 'error', |
| | | { |
| | | html: { |
| | | void: 'always', |
| | | normal: 'never', |
| | | component: 'always', |
| | | }, |
| | | svg: 'always', |
| | | math: 'always', |
| | | }, |
| | | ], |
| | | 'vue/multi-word-component-names': 'off', |
| | | // 'sort-imports': [ |
| | | // 'error', |
| | | // { |
| | | // ignoreCase: true, |
| | | // ignoreDeclarationSort: false, |
| | | // ignoreMemberSort: false, |
| | | // memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], |
| | | // allowSeparatedGroups: false, |
| | | // }, |
| | | // ], |
| | | }, |
| | | globals: { defineOptions: 'readonly' }, |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | extends: ['@vben'], |
| | | plugins: ['simple-import-sort'], |
| | | rules: { |
| | | 'simple-import-sort/imports': 'error', |
| | | 'simple-import-sort/exports': 'error', |
| | | |
| | | '@typescript-eslint/ban-ts-comment': [ |
| | | 'error', |
| | | { |
| | | 'ts-expect-error': 'allow-with-description', |
| | | 'ts-ignore': 'allow-with-description', |
| | | 'ts-nocheck': 'allow-with-description', |
| | | 'ts-check': false, |
| | | }, |
| | | ], |
| | | |
| | | /** |
| | | * ã强å¶ãå
³é®åååæä¸ä¸ªç©ºæ ¼ |
| | | * @link https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/keyword-spacing.md |
| | | */ |
| | | 'keyword-spacing': 'off', |
| | | '@typescript-eslint/keyword-spacing': [ |
| | | 'error', |
| | | { |
| | | before: true, |
| | | after: true, |
| | | overrides: { |
| | | return: { after: true }, |
| | | throw: { after: true }, |
| | | case: { after: true }, |
| | | }, |
| | | }, |
| | | ], |
| | | |
| | | /** |
| | | * ç¦æ¢åºç°ç©ºå½æ°ï¼æ®é彿°ï¼é async/await/generatorï¼ãç®å¤´å½æ°ãç±»ä¸çæ¹æ³é¤å¤ |
| | | * @link https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-empty-function.md |
| | | */ |
| | | 'no-empty-function': 'off', |
| | | '@typescript-eslint/no-empty-function': [ |
| | | 'error', |
| | | { |
| | | allow: ['arrowFunctions', 'functions', 'methods'], |
| | | }, |
| | | ], |
| | | |
| | | /** |
| | | * ä¼å
ä½¿ç¨ interface è䏿¯ type å®ä¹å¯¹è±¡ç±»å |
| | | * @link https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/consistent-type-definitions.md |
| | | */ |
| | | '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], |
| | | |
| | | 'vue/attributes-order': 'error', |
| | | 'vue/require-default-prop': 'error', |
| | | }, |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "extends": "@vben/ts-config/node.json", |
| | | "include": ["src"] |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | *.sh |
| | | node_modules |
| | | *.md |
| | | *.woff |
| | | *.ttf |
| | | .turbo |
| | | dist |
| | | package.json |
¶Ô±ÈÐÂÎļþ |
| | |
| | | module.exports = { |
| | | root: true, |
| | | extends: ['@vben/eslint-config/strict'], |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineBuildConfig } from 'unbuild'; |
| | | |
| | | export default defineBuildConfig({ |
| | | clean: true, |
| | | entries: ['src/index'], |
| | | declaration: true, |
| | | rollup: { |
| | | emitCJS: true, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "@vben/stylelint-config", |
| | | "version": "1.0.0", |
| | | "private": true, |
| | | "homepage": "https://github.com/vbenjs/vue-vben-admin", |
| | | "bugs": { |
| | | "url": "https://github.com/vbenjs/vue-vben-admin/issues" |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "git+https://github.com/vbenjs/vue-vben-admin.git", |
| | | "directory": "internal/stylelint-config" |
| | | }, |
| | | "license": "MIT", |
| | | "type": "module", |
| | | "exports": { |
| | | ".": { |
| | | "types": "./dist/index.d.ts", |
| | | "import": "./dist/index.mjs", |
| | | "require": "./dist/index.cjs" |
| | | } |
| | | }, |
| | | "main": "./dist/index.cjs", |
| | | "module": "./dist/index.mjs", |
| | | "types": "./dist/index.d.ts", |
| | | "files": [ |
| | | "dist" |
| | | ], |
| | | "scripts": { |
| | | "clean": "pnpm rimraf .turbo node_modules dist", |
| | | "lint": "pnpm eslint .", |
| | | "stub": "pnpm unbuild --stub" |
| | | }, |
| | | "devDependencies": { |
| | | "postcss": "^8.4.38", |
| | | "postcss-html": "^1.6.0", |
| | | "postcss-less": "^6.0.0", |
| | | "postcss-scss": "^4.0.9", |
| | | "prettier": "^3.2.5", |
| | | "stylelint": "^16.4.0", |
| | | "stylelint-config-property-sort-order-smacss": "^10.0.0", |
| | | "stylelint-config-recommended-scss": "^14.0.0", |
| | | "stylelint-config-recommended-vue": "^1.5.0", |
| | | "stylelint-config-standard": "^36.0.0", |
| | | "stylelint-config-standard-scss": "^13.1.0", |
| | | "stylelint-order": "^6.0.4", |
| | | "stylelint-prettier": "^5.0.0" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export default { |
| | | extends: ['stylelint-config-standard', 'stylelint-config-property-sort-order-smacss'], |
| | | plugins: ['stylelint-order', 'stylelint-prettier'], |
| | | // customSyntax: 'postcss-html', |
| | | overrides: [ |
| | | { |
| | | files: ['**/*.(css|html|vue)'], |
| | | customSyntax: 'postcss-html', |
| | | }, |
| | | { |
| | | files: ['*.less', '**/*.less'], |
| | | customSyntax: 'postcss-less', |
| | | extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'], |
| | | }, |
| | | { |
| | | files: ['*.scss', '**/*.scss'], |
| | | customSyntax: 'postcss-scss', |
| | | extends: ['stylelint-config-standard-scss', 'stylelint-config-recommended-vue/scss'], |
| | | rule: { |
| | | 'scss/percent-placeholder-pattern': null, |
| | | }, |
| | | }, |
| | | ], |
| | | rules: { |
| | | 'prettier/prettier': true, |
| | | 'media-feature-range-notation': null, |
| | | 'selector-not-notation': null, |
| | | 'import-notation': null, |
| | | 'function-no-unknown': null, |
| | | 'selector-class-pattern': null, |
| | | 'selector-pseudo-class-no-unknown': [ |
| | | true, |
| | | { |
| | | ignorePseudoClasses: ['global', 'deep'], |
| | | }, |
| | | ], |
| | | 'selector-pseudo-element-no-unknown': [ |
| | | true, |
| | | { |
| | | ignorePseudoElements: ['v-deep'], |
| | | }, |
| | | ], |
| | | 'at-rule-no-unknown': [ |
| | | true, |
| | | { |
| | | ignoreAtRules: [ |
| | | 'tailwind', |
| | | 'apply', |
| | | 'variants', |
| | | 'responsive', |
| | | 'screen', |
| | | 'function', |
| | | 'if', |
| | | 'each', |
| | | 'include', |
| | | 'mixin', |
| | | 'extend', |
| | | ], |
| | | }, |
| | | ], |
| | | 'no-empty-source': null, |
| | | 'named-grid-areas-no-invalid': null, |
| | | 'no-descending-specificity': null, |
| | | 'font-family-no-missing-generic-family-keyword': null, |
| | | 'rule-empty-line-before': [ |
| | | 'always', |
| | | { |
| | | ignore: ['after-comment', 'first-nested'], |
| | | }, |
| | | ], |
| | | 'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }], |
| | | 'order/order': [ |
| | | [ |
| | | 'dollar-variables', |
| | | 'custom-properties', |
| | | 'at-rules', |
| | | 'declarations', |
| | | { |
| | | type: 'at-rule', |
| | | name: 'supports', |
| | | }, |
| | | { |
| | | type: 'at-rule', |
| | | name: 'media', |
| | | }, |
| | | 'rules', |
| | | ], |
| | | { severity: 'error' }, |
| | | ], |
| | | }, |
| | | ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'], |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "extends": "@vben/ts-config/node.json", |
| | | "include": ["src"] |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "display": "Base", |
| | | "compilerOptions": { |
| | | "target": "ESNext", |
| | | "module": "ESNext", |
| | | "moduleResolution": "bundler", |
| | | "strict": true, |
| | | "declaration": true, |
| | | "noImplicitOverride": true, |
| | | "noUnusedLocals": true, |
| | | "esModuleInterop": true, |
| | | "useUnknownInCatchVariables": false, |
| | | "composite": false, |
| | | "declarationMap": false, |
| | | "forceConsistentCasingInFileNames": true, |
| | | "inlineSources": false, |
| | | "isolatedModules": true, |
| | | "skipLibCheck": true, |
| | | "noUnusedParameters": false, |
| | | "preserveWatchOutput": true, |
| | | "experimentalDecorators": true, |
| | | "resolveJsonModule": true, |
| | | "removeComments": true |
| | | }, |
| | | "exclude": ["**/node_modules/**", "**/dist/**"] |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "display": "Node Server Config", |
| | | "extends": "./base.json", |
| | | "compilerOptions": { |
| | | "module": "commonjs", |
| | | "declaration": false, |
| | | "removeComments": true, |
| | | "emitDecoratorMetadata": true, |
| | | "experimentalDecorators": true, |
| | | "target": "es6", |
| | | "sourceMap": false, |
| | | "esModuleInterop": true, |
| | | "outDir": "./dist", |
| | | "baseUrl": "./" |
| | | }, |
| | | "exclude": ["node_modules"] |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "display": "Node Config", |
| | | "extends": "./base.json", |
| | | "compilerOptions": { |
| | | "lib": ["ESNext"], |
| | | "noImplicitAny": true, |
| | | "sourceMap": true, |
| | | "noEmit": true, |
| | | "baseUrl": "./" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "@vben/ts-config", |
| | | "version": "1.0.0", |
| | | "private": true, |
| | | "homepage": "https://github.com/vbenjs/vue-vben-admin", |
| | | "bugs": { |
| | | "url": "https://github.com/vbenjs/vue-vben-admin/issues" |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "git+https://github.com/vbenjs/vue-vben-admin.git", |
| | | "directory": "internal/ts-config" |
| | | }, |
| | | "license": "MIT", |
| | | "type": "module", |
| | | "files": [ |
| | | "base.json", |
| | | "node.json", |
| | | "vue-app.json", |
| | | "node-server.json" |
| | | ], |
| | | "dependencies": { |
| | | "@types/node": "^20.12.7", |
| | | "vite": "^5.2.10" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "display": "Vue Application", |
| | | "extends": "./base.json", |
| | | "compilerOptions": { |
| | | "jsx": "preserve", |
| | | "lib": ["ESNext", "DOM"], |
| | | "noImplicitAny": false |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | *.sh |
| | | node_modules |
| | | *.md |
| | | *.woff |
| | | *.ttf |
| | | .turbo |
| | | dist |
| | | package.json |
¶Ô±ÈÐÂÎļþ |
| | |
| | | module.exports = { |
| | | root: true, |
| | | extends: ['@vben/eslint-config/strict'], |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { defineBuildConfig } from 'unbuild'; |
| | | |
| | | export default defineBuildConfig({ |
| | | clean: true, |
| | | entries: ['src/index'], |
| | | declaration: true, |
| | | rollup: { |
| | | emitCJS: true, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "name": "@vben/vite-config", |
| | | "version": "1.0.0", |
| | | "private": true, |
| | | "homepage": "https://github.com/vbenjs/vue-vben-admin", |
| | | "bugs": { |
| | | "url": "https://github.com/vbenjs/vue-vben-admin/issues" |
| | | }, |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "git+https://github.com/vbenjs/vue-vben-admin.git", |
| | | "directory": "internal/vite-config" |
| | | }, |
| | | "license": "MIT", |
| | | "type": "module", |
| | | "exports": { |
| | | ".": { |
| | | "types": "./dist/index.d.ts", |
| | | "import": "./dist/index.mjs", |
| | | "require": "./dist/index.cjs" |
| | | } |
| | | }, |
| | | "main": "./dist/index.cjs", |
| | | "module": "./dist/index.mjs", |
| | | "types": "./dist/index.d.ts", |
| | | "files": [ |
| | | "dist" |
| | | ], |
| | | "scripts": { |
| | | "clean": "pnpm rimraf .turbo node_modules dist", |
| | | "lint": "pnpm eslint .", |
| | | "stub": "pnpm unbuild --stub" |
| | | }, |
| | | "dependencies": { |
| | | "@ant-design/colors": "^7.0.2", |
| | | "vite": "^5.2.10" |
| | | }, |
| | | "devDependencies": { |
| | | "@types/fs-extra": "^11.0.4", |
| | | "@vitejs/plugin-vue": "^5.0.4", |
| | | "@vitejs/plugin-vue-jsx": "^3.1.0", |
| | | "ant-design-vue": "^4.2.1", |
| | | "dayjs": "^1.11.10", |
| | | "dotenv": "^16.4.5", |
| | | "fs-extra": "^11.2.0", |
| | | "less": "^4.2.0", |
| | | "picocolors": "^1.0.0", |
| | | "pkg-types": "^1.1.0", |
| | | "rollup-plugin-visualizer": "^5.12.0", |
| | | "sass": "^1.75.0", |
| | | "unocss": "0.59.4", |
| | | "vite-plugin-compression": "^0.5.1", |
| | | "vite-plugin-dts": "^3.9.0", |
| | | "vite-plugin-html": "^3.2.2", |
| | | "vite-plugin-mock": "^2.9.6", |
| | | "vite-plugin-purge-icons": "^0.10.0", |
| | | "vite-plugin-svg-icons": "^2.0.1" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { resolve } from 'node:path'; |
| | | |
| | | import dayjs from 'dayjs'; |
| | | import { readPackageJSON } from 'pkg-types'; |
| | | import { defineConfig, loadEnv, mergeConfig, type UserConfig } from 'vite'; |
| | | |
| | | import { createPlugins } from '../plugins'; |
| | | import { generateModifyVars } from '../utils/modifyVars'; |
| | | import { commonConfig } from './common'; |
| | | |
| | | interface DefineOptions { |
| | | overrides?: UserConfig; |
| | | options?: { |
| | | // |
| | | }; |
| | | } |
| | | |
| | | function defineApplicationConfig(defineOptions: DefineOptions = {}) { |
| | | const { overrides = {} } = defineOptions; |
| | | |
| | | return defineConfig(async ({ command, mode }) => { |
| | | const root = process.cwd(); |
| | | const isBuild = command === 'build'; |
| | | const { VITE_PUBLIC_PATH, VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv( |
| | | mode, |
| | | root, |
| | | ); |
| | | |
| | | const defineData = await createDefineData(root); |
| | | const plugins = await createPlugins({ |
| | | isBuild, |
| | | root, |
| | | enableAnalyze: VITE_ENABLE_ANALYZE === 'true', |
| | | enableMock: VITE_USE_MOCK === 'true', |
| | | compress: VITE_BUILD_COMPRESS, |
| | | }); |
| | | |
| | | const pathResolve = (pathname: string) => resolve(root, '.', pathname); |
| | | |
| | | const applicationConfig: UserConfig = { |
| | | base: VITE_PUBLIC_PATH, |
| | | resolve: { |
| | | alias: [ |
| | | { |
| | | find: 'vue-i18n', |
| | | replacement: 'vue-i18n/dist/vue-i18n.cjs.js', |
| | | }, |
| | | // @/xxxx => src/xxxx |
| | | { |
| | | find: /@\//, |
| | | replacement: pathResolve('src') + '/', |
| | | }, |
| | | // #/xxxx => types/xxxx |
| | | { |
| | | find: /#\//, |
| | | replacement: pathResolve('types') + '/', |
| | | }, |
| | | ], |
| | | }, |
| | | define: defineData, |
| | | build: { |
| | | target: 'es2015', |
| | | cssTarget: 'chrome80', |
| | | rollupOptions: { |
| | | output: { |
| | | // å
¥å£æä»¶å |
| | | entryFileNames: 'assets/entry/[name]-[hash].js', |
| | | manualChunks: { |
| | | vue: ['vue', 'pinia', 'vue-router'], |
| | | antd: ['ant-design-vue', '@ant-design/icons-vue'], |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | css: { |
| | | preprocessorOptions: { |
| | | less: { |
| | | modifyVars: generateModifyVars(), |
| | | javascriptEnabled: true, |
| | | }, |
| | | }, |
| | | }, |
| | | plugins, |
| | | }; |
| | | |
| | | const mergedConfig = mergeConfig(commonConfig(mode), applicationConfig); |
| | | |
| | | return mergeConfig(mergedConfig, overrides); |
| | | }); |
| | | } |
| | | |
| | | async function createDefineData(root: string) { |
| | | try { |
| | | const pkgJson = await readPackageJSON(root); |
| | | const { dependencies, devDependencies, name, version } = pkgJson; |
| | | |
| | | const __APP_INFO__ = { |
| | | pkg: { dependencies, devDependencies, name, version }, |
| | | lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | }; |
| | | return { |
| | | __APP_INFO__: JSON.stringify(__APP_INFO__), |
| | | }; |
| | | } catch (error) { |
| | | return {}; |
| | | } |
| | | } |
| | | |
| | | export { defineApplicationConfig }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import UnoCSS from 'unocss/vite'; |
| | | import { type UserConfig } from 'vite'; |
| | | |
| | | const commonConfig: (mode: string) => UserConfig = (mode) => ({ |
| | | server: { |
| | | host: true, |
| | | }, |
| | | esbuild: { |
| | | drop: mode === 'production' ? ['console', 'debugger'] : [], |
| | | }, |
| | | build: { |
| | | reportCompressedSize: false, |
| | | chunkSizeWarningLimit: 1500, |
| | | rollupOptions: { |
| | | // TODO: Prevent memory overflow |
| | | maxParallelFileOps: 3, |
| | | }, |
| | | }, |
| | | plugins: [UnoCSS()], |
| | | }); |
| | | |
| | | export { commonConfig }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { readPackageJSON } from 'pkg-types'; |
| | | import { defineConfig, mergeConfig, type UserConfig } from 'vite'; |
| | | import dts from 'vite-plugin-dts'; |
| | | |
| | | import { commonConfig } from './common'; |
| | | |
| | | interface DefineOptions { |
| | | overrides?: UserConfig; |
| | | options?: { |
| | | // |
| | | }; |
| | | } |
| | | |
| | | function definePackageConfig(defineOptions: DefineOptions = {}) { |
| | | const { overrides = {} } = defineOptions; |
| | | const root = process.cwd(); |
| | | return defineConfig(async ({ mode }) => { |
| | | const { dependencies = {}, peerDependencies = {} } = await readPackageJSON(root); |
| | | const packageConfig: UserConfig = { |
| | | build: { |
| | | lib: { |
| | | entry: 'src/index.ts', |
| | | formats: ['es'], |
| | | fileName: () => 'index.mjs', |
| | | }, |
| | | rollupOptions: { |
| | | external: [...Object.keys(dependencies), ...Object.keys(peerDependencies)], |
| | | }, |
| | | }, |
| | | plugins: [ |
| | | dts({ |
| | | logLevel: 'error', |
| | | }), |
| | | ], |
| | | }; |
| | | const mergedConfig = mergeConfig(commonConfig(mode), packageConfig); |
| | | |
| | | return mergeConfig(mergedConfig, overrides); |
| | | }); |
| | | } |
| | | |
| | | export { definePackageConfig }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export * from './config/application'; |
| | | export * from './config/package'; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import colors from 'picocolors'; |
| | | import { readPackageJSON } from 'pkg-types'; |
| | | import { type PluginOption } from 'vite'; |
| | | |
| | | import { getEnvConfig } from '../utils/env'; |
| | | import { createContentHash } from '../utils/hash'; |
| | | |
| | | const GLOBAL_CONFIG_FILE_NAME = '_app.config.js'; |
| | | const PLUGIN_NAME = 'app-config'; |
| | | |
| | | async function createAppConfigPlugin({ |
| | | root, |
| | | isBuild, |
| | | }: { |
| | | root: string; |
| | | isBuild: boolean; |
| | | }): Promise<PluginOption> { |
| | | let publicPath: string; |
| | | let source: string; |
| | | if (!isBuild) { |
| | | return { |
| | | name: PLUGIN_NAME, |
| | | }; |
| | | } |
| | | const { version = '' } = await readPackageJSON(root); |
| | | |
| | | return { |
| | | name: PLUGIN_NAME, |
| | | async configResolved(_config) { |
| | | const appTitle = _config?.env?.VITE_GLOB_APP_TITLE ?? ''; |
| | | // appTitle = appTitle.replace(/\s/g, '_').replace(/-/g, '_'); |
| | | publicPath = _config.base; |
| | | source = await getConfigSource(appTitle); |
| | | }, |
| | | async transformIndexHtml(html) { |
| | | publicPath = publicPath.endsWith('/') ? publicPath : `${publicPath}/`; |
| | | |
| | | const appConfigSrc = `${ |
| | | publicPath || '/' |
| | | }${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}`; |
| | | |
| | | return { |
| | | html, |
| | | tags: [ |
| | | { |
| | | tag: 'script', |
| | | attrs: { |
| | | src: appConfigSrc, |
| | | }, |
| | | }, |
| | | ], |
| | | }; |
| | | }, |
| | | async generateBundle() { |
| | | try { |
| | | this.emitFile({ |
| | | type: 'asset', |
| | | fileName: GLOBAL_CONFIG_FILE_NAME, |
| | | source, |
| | | }); |
| | | |
| | | console.log(colors.cyan(`â¨configuration file is build successfully!`)); |
| | | } catch (error) { |
| | | console.log( |
| | | colors.red('configuration file configuration file failed to package:\n' + error), |
| | | ); |
| | | } |
| | | }, |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Get the configuration file variable name |
| | | * @param env |
| | | */ |
| | | const getVariableName = (title: string) => { |
| | | function strToHex(str: string) { |
| | | const result: string[] = []; |
| | | for (let i = 0; i < str.length; ++i) { |
| | | const hex = str.charCodeAt(i).toString(16); |
| | | result.push(('000' + hex).slice(-4)); |
| | | } |
| | | return result.join('').toUpperCase(); |
| | | } |
| | | return `__PRODUCTION__${strToHex(title) || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, ''); |
| | | }; |
| | | |
| | | async function getConfigSource(appTitle: string) { |
| | | const config = await getEnvConfig(); |
| | | const variableName = getVariableName(appTitle); |
| | | const windowVariable = `window.${variableName}`; |
| | | // Ensure that the variable will not be modified |
| | | let source = `${windowVariable}=${JSON.stringify(config)};`; |
| | | source += ` |
| | | Object.freeze(${windowVariable}); |
| | | Object.defineProperty(window, "${variableName}", { |
| | | configurable: false, |
| | | writable: false, |
| | | }); |
| | | `.replace(/\s/g, ''); |
| | | return source; |
| | | } |
| | | |
| | | export { createAppConfigPlugin }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated |
| | | * https://github.com/anncwb/vite-plugin-compression |
| | | */ |
| | | import type { PluginOption } from 'vite'; |
| | | import compressPlugin from 'vite-plugin-compression'; |
| | | |
| | | export function configCompressPlugin({ |
| | | compress, |
| | | deleteOriginFile = false, |
| | | }: { |
| | | compress: string; |
| | | deleteOriginFile?: boolean; |
| | | }): PluginOption[] { |
| | | const compressList = compress.split(','); |
| | | |
| | | const plugins: PluginOption[] = []; |
| | | |
| | | if (compressList.includes('gzip')) { |
| | | plugins.push( |
| | | compressPlugin({ |
| | | ext: '.gz', |
| | | deleteOriginFile, |
| | | }), |
| | | ); |
| | | } |
| | | |
| | | if (compressList.includes('brotli')) { |
| | | plugins.push( |
| | | compressPlugin({ |
| | | ext: '.br', |
| | | algorithm: 'brotliCompress', |
| | | deleteOriginFile, |
| | | }), |
| | | ); |
| | | } |
| | | return plugins; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Plugin to minimize and use ejs template syntax in index.html. |
| | | * https://github.com/anncwb/vite-plugin-html |
| | | */ |
| | | import type { PluginOption } from 'vite'; |
| | | import { createHtmlPlugin } from 'vite-plugin-html'; |
| | | |
| | | export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) { |
| | | const htmlPlugin: PluginOption[] = createHtmlPlugin({ |
| | | minify: isBuild, |
| | | }); |
| | | return htmlPlugin; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import vue from '@vitejs/plugin-vue'; |
| | | import vueJsx from '@vitejs/plugin-vue-jsx'; |
| | | import { type PluginOption } from 'vite'; |
| | | import purgeIcons from 'vite-plugin-purge-icons'; |
| | | import DevTools from 'vite-plugin-vue-devtools'; |
| | | |
| | | import { createAppConfigPlugin } from './appConfig'; |
| | | import { configCompressPlugin } from './compress'; |
| | | import { configHtmlPlugin } from './html'; |
| | | import { configMockPlugin } from './mock'; |
| | | import { configSvgIconsPlugin } from './svgSprite'; |
| | | import { configVisualizerConfig } from './visualizer'; |
| | | |
| | | interface Options { |
| | | isBuild: boolean; |
| | | root: string; |
| | | compress: string; |
| | | enableMock?: boolean; |
| | | enableAnalyze?: boolean; |
| | | } |
| | | |
| | | async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) { |
| | | const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx()]; |
| | | |
| | | const appConfigPlugin = await createAppConfigPlugin({ root, isBuild }); |
| | | vitePlugins.push(appConfigPlugin); |
| | | |
| | | vitePlugins.push(DevTools()); |
| | | |
| | | // vite-plugin-html |
| | | vitePlugins.push(configHtmlPlugin({ isBuild })); |
| | | |
| | | // vite-plugin-svg-icons |
| | | vitePlugins.push(configSvgIconsPlugin({ isBuild })); |
| | | |
| | | // vite-plugin-purge-icons |
| | | vitePlugins.push(purgeIcons()); |
| | | |
| | | // The following plugins only work in the production environment |
| | | if (isBuild) { |
| | | // rollup-plugin-gzip |
| | | vitePlugins.push( |
| | | configCompressPlugin({ |
| | | compress, |
| | | }), |
| | | ); |
| | | } |
| | | |
| | | // rollup-plugin-visualizer |
| | | if (enableAnalyze) { |
| | | vitePlugins.push(configVisualizerConfig()); |
| | | } |
| | | |
| | | // vite-plugin-mock |
| | | if (enableMock) { |
| | | vitePlugins.push(configMockPlugin({ isBuild })); |
| | | } |
| | | |
| | | return vitePlugins; |
| | | } |
| | | |
| | | export { createPlugins }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Mock plugin for development and production. |
| | | * https://github.com/anncwb/vite-plugin-mock |
| | | */ |
| | | import { viteMockServe } from 'vite-plugin-mock'; |
| | | |
| | | export function configMockPlugin({ isBuild }: { isBuild: boolean }) { |
| | | return viteMockServe({ |
| | | ignore: /^_/, |
| | | mockPath: 'mock', |
| | | localEnabled: !isBuild, |
| | | prodEnabled: isBuild, |
| | | injectCode: ` |
| | | import { setupProdMockServer } from '../mock/_createProductionServer'; |
| | | |
| | | setupProdMockServer(); |
| | | `, |
| | | }); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Vite Plugin for fast creating SVG sprites. |
| | | * https://github.com/anncwb/vite-plugin-svg-icons |
| | | */ |
| | | |
| | | import { resolve } from 'node:path'; |
| | | |
| | | import type { PluginOption } from 'vite'; |
| | | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; |
| | | |
| | | export function configSvgIconsPlugin({ isBuild }: { isBuild: boolean }) { |
| | | const svgIconsPlugin = createSvgIconsPlugin({ |
| | | iconDirs: [resolve(process.cwd(), 'src/assets/icons')], |
| | | svgoOptions: isBuild, |
| | | }); |
| | | return svgIconsPlugin as PluginOption; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * Package file volume analysis |
| | | */ |
| | | import visualizer from 'rollup-plugin-visualizer'; |
| | | import { type PluginOption } from 'vite'; |
| | | |
| | | export function configVisualizerConfig() { |
| | | return visualizer({ |
| | | filename: './node_modules/.cache/visualizer/stats.html', |
| | | open: true, |
| | | gzipSize: true, |
| | | brotliSize: true, |
| | | }) as PluginOption; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { join } from 'node:path'; |
| | | |
| | | import dotenv from 'dotenv'; |
| | | import { readFile } from 'fs-extra'; |
| | | |
| | | /** |
| | | * è·åå½åç¯å¢ä¸çæçé
ç½®æä»¶å |
| | | */ |
| | | function getConfFiles() { |
| | | const script = process.env.npm_lifecycle_script as string; |
| | | const reg = new RegExp('--mode ([a-z_\\d]+)'); |
| | | const result = reg.exec(script); |
| | | if (result) { |
| | | const mode = result[1]; |
| | | return ['.env', `.env.${mode}`]; |
| | | } |
| | | return ['.env', '.env.production']; |
| | | } |
| | | |
| | | /** |
| | | * Get the environment variables starting with the specified prefix |
| | | * @param match prefix |
| | | * @param confFiles ext |
| | | */ |
| | | export async function getEnvConfig( |
| | | match = 'VITE_GLOB_', |
| | | confFiles = getConfFiles(), |
| | | ): Promise<{ |
| | | [key: string]: string; |
| | | }> { |
| | | let envConfig = {}; |
| | | |
| | | for (const confFile of confFiles) { |
| | | try { |
| | | const envPath = await readFile(join(process.cwd(), confFile), { encoding: 'utf8' }); |
| | | const env = dotenv.parse(envPath); |
| | | envConfig = { ...envConfig, ...env }; |
| | | } catch (e) { |
| | | console.error(`Error in parsing ${confFile}`, e); |
| | | } |
| | | } |
| | | const reg = new RegExp(`^(${match})`); |
| | | Object.keys(envConfig).forEach((key) => { |
| | | if (!reg.test(key)) { |
| | | Reflect.deleteProperty(envConfig, key); |
| | | } |
| | | }); |
| | | return envConfig; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { createHash } from 'node:crypto'; |
| | | |
| | | function createContentHash(content: string, hashLSize = 12) { |
| | | const hash = createHash('sha256').update(content); |
| | | return hash.digest('hex').slice(0, hashLSize); |
| | | } |
| | | function strToHex(str: string) { |
| | | const result: string[] = []; |
| | | for (let i = 0; i < str.length; ++i) { |
| | | const hex = str.charCodeAt(i).toString(16); |
| | | result.push(('000' + hex).slice(-4)); |
| | | } |
| | | return result.join('').toUpperCase(); |
| | | } |
| | | |
| | | export { createContentHash, strToHex }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { resolve } from 'node:path'; |
| | | |
| | | import { generate } from '@ant-design/colors'; |
| | | // @ts-ignore: typo |
| | | /* import { getThemeVariables } from 'ant-design-vue/dist/theme'; */ |
| | | import { theme } from 'ant-design-vue/lib'; |
| | | import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken'; |
| | | |
| | | const { defaultAlgorithm, defaultSeed } = theme; |
| | | const primaryColor = '#0960bd'; |
| | | |
| | | function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') { |
| | | return generate(color, { |
| | | theme, |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * less global variable |
| | | */ |
| | | export function generateModifyVars() { |
| | | const palettes = generateAntColors(primaryColor); |
| | | const primary = palettes[5]; |
| | | const primaryColorObj: Record<string, string> = {}; |
| | | |
| | | for (let index = 0; index < 10; index++) { |
| | | primaryColorObj[`primary-${index + 1}`] = palettes[index]; |
| | | } |
| | | // const modifyVars = getThemeVariables(); |
| | | const mapToken = defaultAlgorithm(defaultSeed); |
| | | const v3Token = convertLegacyToken(mapToken); |
| | | return { |
| | | ...v3Token, |
| | | // reference: Avoid repeated references |
| | | hack: `true; @import (reference) "${resolve('src/design/config.less')}";`, |
| | | 'primary-color': primary, |
| | | ...primaryColorObj, |
| | | 'info-color': primary, |
| | | 'processing-color': primary, |
| | | 'success-color': '#55D187', // Success color |
| | | 'error-color': '#ED6F6F', // False color |
| | | 'warning-color': '#EFBD47', // Warning color |
| | | 'font-size-base': '14px', // Main font size |
| | | 'border-radius-base': '2px', // Component/float fillet |
| | | 'link-color': primary, // Link color |
| | | }; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "$schema": "https://json.schemastore.org/tsconfig", |
| | | "extends": "@vben/ts-config/node.json", |
| | | "include": ["src"] |
| | | } |