├── .commitlintrc.js ├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ └── site.yaml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── README.md ├── group.png ├── package.json ├── packages ├── ui │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── scripts │ │ ├── bundleLess.ts │ │ ├── genColor.ts │ │ └── tools.ts │ ├── src │ │ ├── button │ │ │ ├── button.tsx │ │ │ ├── index.ts │ │ │ └── style │ │ │ │ ├── index.less │ │ │ │ └── index.ts │ │ ├── components.ts │ │ ├── index.ts │ │ ├── style.ts │ │ └── style │ │ │ ├── colors.less │ │ │ ├── dark.less │ │ │ ├── default.less │ │ │ └── index.less │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.vite-config.json │ ├── tsconfig.vitest.json │ ├── vite.config.bundle.style.ts │ ├── vite.config.bundle.ts │ ├── vite.config.style.ts │ └── vite.config.ts └── utils │ ├── build.config.ts │ ├── package.json │ ├── src │ ├── index.ts │ └── tools │ │ └── index.ts │ ├── test │ └── tools.test.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── site ├── .gitignore ├── .npmrc ├── .vuepress │ ├── client.ts │ ├── config.ts │ └── configs │ │ ├── navbar │ │ ├── index.ts │ │ └── zh.ts │ │ └── sidebar │ │ ├── index.ts │ │ └── zh.ts ├── README.md ├── components │ ├── button │ │ ├── example │ │ │ └── basic.vue │ │ └── index.md │ └── index.md ├── package.json └── tsconfig.json └── tsconfig.json /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends:[ 3 | "@commitlint/config-angular" 4 | ], 5 | rules:{ 6 | 'type-enum':[ 7 | 2, 8 | 'always', 9 | [ 10 | 'build', 11 | 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'chore' 12 | ] 13 | ] 14 | } 15 | }; -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | packages/ui/lib 2 | packages/ui/es 3 | dist 4 | 5 | .commitlintrc.js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: '@mistjs/eslint-config-vue', 3 | } 4 | -------------------------------------------------------------------------------- /.github/workflows/site.yaml: -------------------------------------------------------------------------------- 1 | name: site 2 | on: 3 | push: 4 | tags: 5 | - site* 6 | 7 | jobs: 8 | site: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: pnpm/action-setup@v2.1.0 13 | with: 14 | version: 7 15 | - uses: actions/setup-node@v3 16 | with: 17 | node-version: 16 18 | - run: pnpm install --no-frozen-lockfile 19 | - run: pnpm site:build 20 | - uses: crazy-max/ghaction-github-pages@v2 21 | with: 22 | target_branch: gh-pages 23 | build_dir: site/.vuepress/dist 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | *.log 4 | *.tmp 5 | dist 6 | node_modules -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx commitlint --edit 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 前端组件库 2 | 3 | monorepo + typescript + tsx + vitest + pnpm + eslint + husky + 自动部署 + vuepress@next 4 | 5 | 6 | es // button import es6 按需加载 vite tree shaking 7 | lib // ssr lib commonjs 8 | dist // cdn bundle 9 | 10 | git commit -am "update" 11 | 12 | feat: 新特性或者新功能 13 | 14 | fix: 修复 bug 15 | 16 | chore: 构建过程或者其他无关的改动 17 | 18 | refactor: 重构 19 | 20 | ci: 持续集成,自动部署 21 | 22 | wx: aibayanyu2022 23 | -------------------------------------------------------------------------------- /group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yanyu-fe/vue3-component-demo/e54d584f646f3e79a4834d1e56caffce4583a5a0/group.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-component-demo", 3 | "version": "1.0.0", 4 | "packageManager": "pnpm@7.0.0", 5 | "description": "", 6 | "keywords": [], 7 | "license": "ISC", 8 | "author": "", 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/yanyu-fe/vue3-component-demo.git" 12 | }, 13 | "main": "index.js", 14 | "scripts": { 15 | "prepare": "husky install", 16 | "site": "pnpm --filter=site dev", 17 | "site:build": "pnpm --filter=site build" 18 | }, 19 | "dependencies": { 20 | "vue": "^3.2.35" 21 | }, 22 | "devDependencies": { 23 | "@commitlint/cli": "^16.3.0", 24 | "@commitlint/config-angular": "^16.3.0", 25 | "@mistjs/eslint-config-vue": "^0.0.2", 26 | "@types/jsdom": "^16.2.14", 27 | "@vitejs/plugin-vue-jsx": "^1.3.10", 28 | "@vue/test-utils": "^2.0.0", 29 | "eslint": "^8.16.0", 30 | "husky": "^7.0.4", 31 | "jsdom": "^19.0.0", 32 | "lint-staged": "^12.4.1", 33 | "typescript": "^4.6.4", 34 | "vite": "^2.9.9", 35 | "vitest": "^0.9.4" 36 | }, 37 | "lint-staged": { 38 | "*.{ts,tsx,vue}": "eslint . --fix" 39 | }, 40 | "bugs": { 41 | "url": "https://github.com/yanyu-fe/vue3-component-demo/issues" 42 | }, 43 | "homepage": "https://github.com/yanyu-fe/vue3-component-demo#readme", 44 | "pnpm": { 45 | "peerDependencyRules": { 46 | "ignoreMissing": [ 47 | "webpack" 48 | ] 49 | } 50 | }, 51 | "resolutions": { 52 | "@babel/traverse": "7.17.9" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/ui/.gitignore: -------------------------------------------------------------------------------- 1 | es 2 | lib -------------------------------------------------------------------------------- /packages/ui/README.md: -------------------------------------------------------------------------------- 1 | # ui-design 2 | 3 | # less 4 | 5 | ## NodeJS 脚本 6 | 7 | 8 | 9 | ## sideEffects 10 | 11 | https://github.com/happylindz/blog/issues/15 12 | -------------------------------------------------------------------------------- /packages/ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@yanyu-front/ui-design", 3 | "version": "1.0.1", 4 | "description": "", 5 | "keywords": [], 6 | "license": "ISC", 7 | "author": "", 8 | "main": "lib/index.js", 9 | "module": "es/index.js", 10 | "types": "es/index.d.ts", 11 | "files": [ 12 | "lib", 13 | "es", 14 | "dist" 15 | ], 16 | "publishConfig": { 17 | "access": "public" 18 | }, 19 | "sideEffects":[ 20 | "es/**/style/**.less", 21 | "lib/**/style/**.less", 22 | "dist/**.css" 23 | ], 24 | "scripts": { 25 | "build:comp": "vite build", 26 | "genColor": "esno scripts/genColor.ts", 27 | "bundleLess": "esno scripts/bundleLess.ts", 28 | "bundleStyle": "vite build --config vite.config.style.ts", 29 | "bundle": "vite build --config vite.config.bundle.ts", 30 | "bundleLessMin": "vite build --config vite.config.bundle.style.ts", 31 | "bundleMin": "pnpm bundleLessMin && pnpm bundle", 32 | "build": "run-s build:comp genColor bundleLess bundleStyle bundleMin" 33 | }, 34 | "dependencies": { 35 | "@yanyu-fe/utils": "workspace:^1.0.0", 36 | "vue": "^3.2.35" 37 | }, 38 | "devDependencies": { 39 | "@ant-design/colors": "^6.0.0", 40 | "@types/jsdom": "^16.2.14", 41 | "@types/less": "^3.0.3", 42 | "@types/node": "^17.0.35", 43 | "@vitejs/plugin-vue": "^2.3.3", 44 | "@vitejs/plugin-vue-jsx": "^1.3.10", 45 | "@vue/test-utils": "^2.0.0", 46 | "@vue/tsconfig": "^0.1.3", 47 | "cpy": "^9.0.1", 48 | "esno": "^0.15.0", 49 | "fast-glob": "^3.2.11", 50 | "jsdom": "^19.0.0", 51 | "less": "^4.1.2", 52 | "npm-run-all": "^4.1.5", 53 | "typescript": "^4.6.4", 54 | "vite": "^2.9.9", 55 | "vite-plugin-dts": "^1.1.1", 56 | "vitest": "^0.9.4" 57 | }, 58 | "resolutions": { 59 | "@babel/traverse": "7.17.9" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/ui/scripts/bundleLess.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs' 2 | import { dirname, resolve } from 'path' 3 | import cpy from 'cpy' 4 | import fg from 'fast-glob' 5 | import less from 'less' 6 | import { ES_DIR, LIB_DIR, SRC_DIR } from './tools' 7 | 8 | export const bundleLess = async() => { 9 | await Promise.all([ 10 | cpy(`${SRC_DIR}/**/*.less`, ES_DIR), 11 | cpy(`${SRC_DIR}/**/*.less`, LIB_DIR), 12 | ]) 13 | 14 | const lessFiles = await fg('**/index.less', { 15 | cwd: SRC_DIR, 16 | onlyFiles: true, 17 | }) 18 | for (const lessFile of lessFiles) { 19 | const filePath = `${SRC_DIR}/${lessFile}` 20 | const lessContent = await fs.readFile(filePath, 'utf8') 21 | const code = await less.render(lessContent, { 22 | paths: [SRC_DIR, dirname(filePath)], 23 | }) 24 | await Promise.all([ 25 | fs.writeFile(resolve(ES_DIR, lessFile.replace('.less', '.css')), code.css), 26 | fs.writeFile(resolve(LIB_DIR, lessFile.replace('.less', '.css')), code.css), 27 | ]) 28 | } 29 | } 30 | 31 | bundleLess() 32 | -------------------------------------------------------------------------------- /packages/ui/scripts/genColor.ts: -------------------------------------------------------------------------------- 1 | import { promises as fs } from 'fs' 2 | import { blue, generate, gold, green, red } from '@ant-design/colors' 3 | import { dir_path } from './tools' 4 | 5 | const genColor = (color: string, prefix = 'blue') => { 6 | const colors = generate(color) 7 | const darkColors = generate(color, { 8 | theme: 'dark', 9 | backgroundColor: '#222728', 10 | }) 11 | let code = `@${prefix}-base: ${colors[5]};\n` 12 | for (let i = 0; i < colors.length; i++) { 13 | if (i === 5) 14 | code += `@${prefix}-${i + 1}: @${prefix}-base;\n` 15 | else 16 | code += `@${prefix}-${i + 1}: ${colors[i]};\n` 17 | } 18 | 19 | code += `\n\n@${prefix}-dark-base: ${darkColors[5]};\n` 20 | for (let i = 0; i < darkColors.length; i++) { 21 | if (i === 5) 22 | code += `@${prefix}-dark-${i + 1}: @${prefix}-dark-base;\n` 23 | else 24 | code += `@${prefix}-dark-${i + 1}: ${darkColors[i]};\n` 25 | } 26 | return code 27 | } 28 | 29 | const run = async() => { 30 | let code = '' 31 | // 主色 32 | code += genColor(blue[5], 'blue') 33 | code += '\n\n' 34 | // 警告 35 | code += genColor(gold[5], 'gold') 36 | code += '\n\n' 37 | // 成功 38 | code += genColor(green[5], 'green') 39 | code += '\n\n' 40 | // 失败 41 | code += genColor(red[5], 'red') 42 | code += '\n\n' 43 | 44 | // 生成一个colors.less的文件放到src/style文件夹下 45 | await fs.writeFile(dir_path('../src/style/colors.less'), code, 'utf8') 46 | } 47 | 48 | run() 49 | -------------------------------------------------------------------------------- /packages/ui/scripts/tools.ts: -------------------------------------------------------------------------------- 1 | import { dirname, resolve } from 'path' 2 | import { fileURLToPath } from 'url' 3 | 4 | export const __dirname = dirname(fileURLToPath(import.meta.url)) 5 | export const dir_path = (...args: string[]) => resolve(__dirname, ...args) 6 | export const SRC_DIR = dir_path('../src') 7 | export const ES_DIR = dir_path('../es') 8 | export const LIB_DIR = dir_path('../lib') 9 | -------------------------------------------------------------------------------- /packages/ui/src/button/button.tsx: -------------------------------------------------------------------------------- 1 | import type { PropType } from 'vue' 2 | import { computed, defineComponent } from 'vue' 3 | export default defineComponent({ 4 | name: 'YButton', 5 | props: { 6 | type: { 7 | type: String as PropType<'default'|'primary'>, 8 | default: 'default', 9 | }, 10 | }, 11 | setup(_props, { slots }) { 12 | const prefixCls = 'ui-btn' 13 | const cls = computed(() => ({ 14 | [prefixCls]: true, 15 | [`${prefixCls}-${_props.type}`]: _props.type !== 'default', 16 | })) 17 | return () => { 18 | return 19 | } 20 | }, 21 | }) 22 | -------------------------------------------------------------------------------- /packages/ui/src/button/index.ts: -------------------------------------------------------------------------------- 1 | import type { App, Plugin } from 'vue' 2 | import Button from './button' 3 | 4 | Button.install = (app: App) => { 5 | app.component(Button.name, Button) 6 | return app 7 | } 8 | 9 | export default Button as typeof Button & Plugin 10 | -------------------------------------------------------------------------------- /packages/ui/src/button/style/index.less: -------------------------------------------------------------------------------- 1 | @import "../../style/index.less"; 2 | 3 | @btn-prefix:~"@{ui-prefix}-btn"; 4 | 5 | .@{btn-prefix}{ 6 | &-primary{ 7 | background: @primary-color; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/src/button/style/index.ts: -------------------------------------------------------------------------------- 1 | import '../../style/index.less' 2 | import './index.less' 3 | -------------------------------------------------------------------------------- /packages/ui/src/components.ts: -------------------------------------------------------------------------------- 1 | export { default as Button } from './button' 2 | -------------------------------------------------------------------------------- /packages/ui/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue' 2 | import * as components from './components' 3 | 4 | export * from './components' 5 | 6 | export default { 7 | install(app: App) { 8 | for (const component in components) { 9 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment 10 | // @ts-expect-error 11 | const Comp = components[component] 12 | if (Comp.install) 13 | app.use(Comp) 14 | } 15 | return app 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /packages/ui/src/style.ts: -------------------------------------------------------------------------------- 1 | import './button/style' 2 | -------------------------------------------------------------------------------- /packages/ui/src/style/colors.less: -------------------------------------------------------------------------------- 1 | @blue-base: #1890ff; 2 | @blue-1: #e6f7ff; 3 | @blue-2: #bae7ff; 4 | @blue-3: #91d5ff; 5 | @blue-4: #69c0ff; 6 | @blue-5: #40a9ff; 7 | @blue-6: @blue-base; 8 | @blue-7: #096dd9; 9 | @blue-8: #0050b3; 10 | @blue-9: #003a8c; 11 | @blue-10: #002766; 12 | 13 | 14 | @blue-dark-base: #1a80df; 15 | @blue-dark-1: #1d2d3d; 16 | @blue-dark-2: #1c3954; 17 | @blue-dark-3: #1f4769; 18 | @blue-dark-4: #1e5689; 19 | @blue-dark-5: #1c6bb4; 20 | @blue-dark-6: @blue-dark-base; 21 | @blue-dark-7: #3d9cea; 22 | @blue-dark-8: #65b8f4; 23 | @blue-dark-9: #8ed0f9; 24 | @blue-dark-10: #b7e3fb; 25 | 26 | 27 | @gold-base: #faad14; 28 | @gold-1: #fffbe6; 29 | @gold-2: #fff1b8; 30 | @gold-3: #ffe58f; 31 | @gold-4: #ffd666; 32 | @gold-5: #ffc53d; 33 | @gold-6: @gold-base; 34 | @gold-7: #d48806; 35 | @gold-8: #ad6800; 36 | @gold-9: #874d00; 37 | @gold-10: #613400; 38 | 39 | 40 | @gold-dark-base: #da9917; 41 | @gold-dark-1: #373122; 42 | @gold-dark-2: #4f3f20; 43 | @gold-dark-3: #634f22; 44 | @gold-dark-4: #83631f; 45 | @gold-dark-5: #ae7e1b; 46 | @gold-dark-6: @gold-dark-base; 47 | @gold-dark-7: #e9b53b; 48 | @gold-dark-8: #f4cd63; 49 | @gold-dark-9: #f8df8c; 50 | @gold-dark-10: #fbedb5; 51 | 52 | 53 | @green-base: #52c41a; 54 | @green-1: #f6ffed; 55 | @green-2: #d9f7be; 56 | @green-3: #b7eb8f; 57 | @green-4: #95de64; 58 | @green-5: #73d13d; 59 | @green-6: @green-base; 60 | @green-7: #389e0d; 61 | @green-8: #237804; 62 | @green-9: #135200; 63 | @green-10: #092b00; 64 | 65 | 66 | @green-dark-base: #4bac1c; 67 | @green-dark-1: #223323; 68 | @green-dark-2: #284521; 69 | @green-dark-3: #305624; 70 | @green-dark-4: #386e22; 71 | @green-dark-5: #418d1f; 72 | @green-dark-6: @green-dark-base; 73 | @green-dark-7: #6bc03b; 74 | @green-dark-8: #8fd561; 75 | @green-dark-9: #b3e58c; 76 | @green-dark-10: #d5f3bb; 77 | 78 | 79 | @red-base: #f5222d; 80 | @red-1: #fff1f0; 81 | @red-2: #ffccc7; 82 | @red-3: #ffa39e; 83 | @red-4: #ff7875; 84 | @red-5: #ff4d4f; 85 | @red-6: @red-base; 86 | @red-7: #cf1322; 87 | @red-8: #a8071a; 88 | @red-9: #820014; 89 | @red-10: #5c0011; 90 | 91 | 92 | @red-dark-base: #d5232c; 93 | @red-dark-1: #362226; 94 | @red-dark-2: #4d2227; 95 | @red-dark-3: #61262a; 96 | @red-dark-4: #81252a; 97 | @red-dark-5: #ab242b; 98 | @red-dark-6: @red-dark-base; 99 | @red-dark-7: #e9494b; 100 | @red-dark-8: #f47471; 101 | @red-dark-9: #f89f9a; 102 | @red-dark-10: #fbc9c4; 103 | 104 | 105 | -------------------------------------------------------------------------------- /packages/ui/src/style/dark.less: -------------------------------------------------------------------------------- 1 | @import "colors"; 2 | @html-dark-selector: ~"html[data-theme='dark']"; 3 | 4 | @{html-dark-selector} { 5 | --@{ui-prefix}-primary-color: @blue-dark-base; 6 | } 7 | -------------------------------------------------------------------------------- /packages/ui/src/style/default.less: -------------------------------------------------------------------------------- 1 | @import "colors"; 2 | @ui-prefix: ~"ui"; 3 | @html-selector: html; 4 | 5 | @{html-selector}{ 6 | --@{ui-prefix}-primary-color: @blue-base; 7 | } 8 | 9 | @primary-color: var(~"--@{ui-prefix}-primary-color"); 10 | -------------------------------------------------------------------------------- /packages/ui/src/style/index.less: -------------------------------------------------------------------------------- 1 | @import "default"; 2 | @import "dark"; 3 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.web.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "baseUrl": "." 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.vite-config.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.vite-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node", "vitest"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [], 7 | "types": ["node", "jsdom"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/vite.config.bundle.style.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | 3 | export default defineConfig({ 4 | build: { 5 | outDir: 'dist', 6 | emptyOutDir: false, 7 | minify: true, 8 | rollupOptions: { 9 | external: [ 10 | 'vue', 11 | '@yanyu-fe/utils', 12 | ], 13 | output: { 14 | exports: 'named', 15 | globals: { 16 | 'vue': 'Vue', 17 | '@yanyu-fe/utils': 'yanyuUtils', 18 | }, 19 | }, 20 | }, 21 | lib: { 22 | entry: 'src/style.ts', 23 | formats: ['umd', 'cjs', 'es'], 24 | name: 'uiDesign', 25 | }, 26 | }, 27 | }) 28 | -------------------------------------------------------------------------------- /packages/ui/vite.config.bundle.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vueJsx from '@vitejs/plugin-vue-jsx' 3 | import vue from '@vitejs/plugin-vue' 4 | export default defineConfig({ 5 | plugins: [vueJsx(), vue()], 6 | build: { 7 | outDir: 'dist', 8 | emptyOutDir: false, 9 | minify: true, 10 | rollupOptions: { 11 | external: [ 12 | 'vue', 13 | '@yanyu-fe/utils', 14 | ], 15 | output: { 16 | exports: 'named', 17 | globals: { 18 | 'vue': 'Vue', 19 | '@yanyu-fe/utils': 'yanyuUtils', 20 | }, 21 | }, 22 | }, 23 | lib: { 24 | entry: 'src/index.ts', 25 | formats: ['umd', 'cjs', 'es'], 26 | name: 'uiDesign', 27 | }, 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /packages/ui/vite.config.style.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import fg from 'fast-glob' 3 | 4 | const files = fg.sync('**/style/index.ts', { 5 | cwd: process.cwd(), 6 | onlyFiles: true, 7 | }) 8 | 9 | export default defineConfig({ 10 | build: { 11 | target: 'modules', 12 | outDir: 'es', 13 | emptyOutDir: false, 14 | minify: false, 15 | rollupOptions: { 16 | external: (id) => { 17 | if (id.endsWith('.less')) 18 | return true 19 | 20 | return false 21 | }, 22 | input: files, 23 | output: [ 24 | // esm 25 | { 26 | format: 'es', 27 | dir: 'es', 28 | entryFileNames: '[name].js', 29 | preserveModules: true, 30 | preserveModulesRoot: 'src', 31 | }, 32 | // cjs 33 | { 34 | format: 'cjs', 35 | dir: 'lib', 36 | entryFileNames: '[name].js', 37 | preserveModules: true, 38 | preserveModulesRoot: 'src', 39 | }, 40 | ], 41 | }, 42 | // 这一块是不会被使用的 43 | lib: { 44 | entry: '', 45 | formats: ['es', 'cjs'], 46 | }, 47 | }, 48 | plugins: [ 49 | { 50 | name: 'vite-plugin-style', 51 | generateBundle(config, bundle) { 52 | const keys = Object.keys(bundle) 53 | for (const key of keys) { 54 | const bundler: any = bundle[key] 55 | bundler.code = bundler.code.replace('./style/index.less', '../../style/index.less') 56 | bundler.code = bundler.code.replace('../../index.less', './index.less') 57 | this.emitFile({ 58 | type: 'asset', 59 | fileName: key.replace('index.js', 'css.js'), 60 | source: bundler.code.replace(/\.less/g, '.css'), 61 | }) 62 | } 63 | }, 64 | }, 65 | ], 66 | }) 67 | -------------------------------------------------------------------------------- /packages/ui/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vueJsx from '@vitejs/plugin-vue-jsx' 3 | import vue from '@vitejs/plugin-vue' 4 | import dts from 'vite-plugin-dts' 5 | export default defineConfig({ 6 | build: { 7 | target: 'modules', 8 | outDir: 'es', 9 | emptyOutDir: false, 10 | minify: false, 11 | rollupOptions: { 12 | external: [ 13 | 'vue', 14 | '@yanyu-fe/utils', 15 | ], 16 | input: ['src/index.ts'], 17 | output: [ 18 | // esm 19 | { 20 | format: 'es', 21 | dir: 'es', 22 | entryFileNames: '[name].js', 23 | preserveModules: true, 24 | preserveModulesRoot: 'src', 25 | }, 26 | // cjs 27 | { 28 | format: 'cjs', 29 | dir: 'lib', 30 | entryFileNames: '[name].js', 31 | preserveModules: true, 32 | preserveModulesRoot: 'src', 33 | }, 34 | ], 35 | }, 36 | // 这一块是不会被使用的 37 | lib: { 38 | entry: 'src/index.ts', 39 | formats: ['es', 'cjs'], 40 | }, 41 | }, 42 | plugins: [ 43 | vue(), 44 | vueJsx(), 45 | dts(), 46 | ], 47 | }) 48 | -------------------------------------------------------------------------------- /packages/utils/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | export default defineBuildConfig({ 3 | entries: [ 4 | './src/index', 5 | ], 6 | declaration: true, 7 | rollup: { 8 | emitCJS: true, 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@yanyu-fe/utils", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "license": "ISC", 7 | "author": "", 8 | "main": "dist/index.cjs", 9 | "module": "dist/index.mjs", 10 | "types": "dist/index.d.ts", 11 | "files": [ 12 | "dist" 13 | ], 14 | "scripts": { 15 | "build": "unbuild", 16 | "test": "vitest" 17 | }, 18 | "dependencies": { 19 | "vue": "^3.2.35" 20 | }, 21 | "devDependencies": { 22 | "@vue/tsconfig": "^0.1.3", 23 | "typescript": "^4.6.4", 24 | "unbuild": "^0.7.4", 25 | "vite": "^2.9.9", 26 | "vitest": "^0.9.4" 27 | }, 28 | "resolutions": { 29 | "@babel/traverse": "7.17.9" 30 | }, 31 | "publishConfig": { 32 | "access": "public" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/utils/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tools' 2 | -------------------------------------------------------------------------------- /packages/utils/src/tools/index.ts: -------------------------------------------------------------------------------- 1 | export const isStr = (str: any): str is string => typeof str === 'string' 2 | export const isNum = (num: any): num is number => typeof num === 'number' 3 | -------------------------------------------------------------------------------- /packages/utils/test/tools.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | import { isStr } from '../src' 3 | 4 | describe('tools', () => { 5 | it('should be true', () => { 6 | expect(isStr('')).toBe(true) 7 | expect(isStr(1)).toMatchInlineSnapshot('false') 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /packages/utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "outDir": "dist", 6 | "moduleResolution": "node", 7 | "sourceMap": true, 8 | "declaration": true, 9 | "resolveJsonModule": true, 10 | "esModuleInterop": true, 11 | "newLine": "LF", 12 | "forceConsistentCasingInFileNames": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "noImplicitAny": true, 15 | "noImplicitThis": true, 16 | "strictBindCallApply": true, 17 | "strictNullChecks": true, 18 | "strictPropertyInitialization": true, 19 | "stripInternal": true, 20 | "skipLibCheck": true 21 | }, 22 | "include": [ 23 | "src/**/*.ts", 24 | ], 25 | "exclude": [ 26 | "node_modules" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/**' 3 | - '!**/test/**' 4 | - site 5 | -------------------------------------------------------------------------------- /site/.gitignore: -------------------------------------------------------------------------------- 1 | .temp 2 | .cache -------------------------------------------------------------------------------- /site/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true -------------------------------------------------------------------------------- /site/.vuepress/client.ts: -------------------------------------------------------------------------------- 1 | import { defineClientConfig } from "@vuepress/client"; 2 | // @ts-ignore 3 | import uiDesign from "ui-design"; 4 | import "ui-design/style"; 5 | 6 | export default defineClientConfig({ 7 | enhance({app}){ 8 | app.use(uiDesign); 9 | } 10 | }) 11 | -------------------------------------------------------------------------------- /site/.vuepress/config.ts: -------------------------------------------------------------------------------- 1 | import { defineUserConfig,defaultTheme ,viteBundler} from "vuepress"; 2 | import * as navbar from "./configs/navbar"; 3 | import * as sidebar from "./configs/sidebar"; 4 | import vueJsx from "@vitejs/plugin-vue-jsx"; 5 | import { codeBlockPlugin } from "@yanyu-fe/vuepress-plugin-code-block" 6 | import { resolve } from "path"; 7 | export default defineUserConfig({ 8 | title:"前端组件库", 9 | base: process.env.NODE_ENV === "production" ? "/vue3-component-demo/" : "/", 10 | plugins: [ 11 | codeBlockPlugin() 12 | ], 13 | locales:{ 14 | "/":{ 15 | lang:"zh-CN", 16 | title:"ui-design", 17 | } 18 | }, 19 | lang: "zh-CN", 20 | theme: defaultTheme({ 21 | locales: { 22 | "/": { 23 | navbar: navbar.zh, 24 | sidebar: sidebar.zh 25 | } 26 | } 27 | }), 28 | bundler:viteBundler({ 29 | viteOptions:{ 30 | plugins:[vueJsx()], 31 | resolve:{ 32 | alias:{ 33 | "ui-design/style":resolve(__dirname,"../../packages/ui/src/style.ts"), 34 | "ui-design":resolve(__dirname,"../../packages/ui/src/index.ts"), 35 | } 36 | }, 37 | css:{ 38 | preprocessorOptions:{ 39 | less:{ 40 | modifyVars:{ 41 | "html-dark-selector": "~'html.dark'" 42 | } 43 | } 44 | } 45 | } 46 | }, 47 | }) 48 | }) 49 | -------------------------------------------------------------------------------- /site/.vuepress/configs/navbar/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./zh"; 2 | -------------------------------------------------------------------------------- /site/.vuepress/configs/navbar/zh.ts: -------------------------------------------------------------------------------- 1 | export const zh = [ 2 | { 3 | text: '组件', 4 | link: '/components/', 5 | }, 6 | ]; -------------------------------------------------------------------------------- /site/.vuepress/configs/sidebar/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./zh"; -------------------------------------------------------------------------------- /site/.vuepress/configs/sidebar/zh.ts: -------------------------------------------------------------------------------- 1 | export const zh = { 2 | '/components/':[ 3 | "/components/", 4 | "/components/button/", 5 | ] 6 | } -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | # 前端组件库 2 | -------------------------------------------------------------------------------- /site/components/button/example/basic.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /site/components/button/index.md: -------------------------------------------------------------------------------- 1 | # Button 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /site/components/index.md: -------------------------------------------------------------------------------- 1 | # 组件预览 -------------------------------------------------------------------------------- /site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "site", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "license": "ISC", 7 | "author": "", 8 | "main": "index.js", 9 | "scripts": { 10 | "dev": "vuepress dev", 11 | "build": "vuepress build" 12 | }, 13 | "dependencies": { 14 | "vue": "^3.2.35", 15 | "vuepress": "^2.0.0-beta.45" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-vue-jsx": "^1.3.10", 19 | "@vuepress/client": "^2.0.0-beta.45", 20 | "@yanyu-fe/vuepress-plugin-code-block": "^0.1.1", 21 | "less": "^4.1.2" 22 | }, 23 | "resolutions": { 24 | "@babel/traverse": "7.17.9" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /site/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "isolatedModules": true, 8 | "strict": true, 9 | "jsx": "preserve", 10 | "sourceMap": true, 11 | "resolveJsonModule": true, 12 | "esModuleInterop": true, 13 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 14 | "skipLibCheck": true, 15 | "baseUrl": ".", 16 | "paths": { 17 | "ui-design": ["../packages/ui/src/index.ts"], 18 | "ui-design/style": ["../packages/ui/src/style.ts"], 19 | } 20 | }, 21 | "exclude": ["node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "isolatedModules": true, 8 | "strict": true, 9 | "jsx": "preserve", 10 | "sourceMap": true, 11 | "resolveJsonModule": true, 12 | "esModuleInterop": true, 13 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"], 14 | "skipLibCheck": true, 15 | "baseUrl": ".", 16 | "paths": { 17 | } 18 | }, 19 | } 20 | --------------------------------------------------------------------------------