diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2a2965e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,28 @@ +# https://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +# @link https://youtrack.jetbrains.com/issue/WEB-21157#focus=streamItem-27-3617910.0-0 +quote_type = single + +# special for webstorm +ij_coffeescript_use_double_quotes = false +ij_css_use_double_quotes = false +ij_javascript_use_double_quotes = false +ij_less_use_double_quotes = false +ij_sass_use_double_quotes = false +ij_scss_use_double_quotes = false +ij_stylus_use_double_quotes = false +ij_typescript_use_double_quotes = false + + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..673b87b --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +node_modules +dist +package-lock.json +!.* +auto-imports.d.ts +components.d.ts +stats.html +vite-plugin-monaco-editor-nls +pnpm-lock.yaml diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 751cf46..6680271 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,18 +1,21 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution"); - +/** @type {import("eslint-define-config").EslintConfig} */ module.exports = { root: true, - env: { - node: true, - browser: true, - commonjs: true, - amd: true, - }, - extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/eslint-config-typescript/recommended", - "@vue/eslint-config-prettier", + extends: ['@element-plus/eslint-config'], + overrides: [ + { + files: ['**/*.md/*.js', '**/*.md/*.ts'], + rules: { + 'no-alert': 'off', + 'no-console': 'off', + 'import/no-unresolved': 'off', + '@typescript-eslint/no-unused-vars': 'off', + }, + }, ], -}; + rules: { + 'no-console': ['warn', { allow: ['warn', 'error'] }], + '@typescript-eslint/no-unused-vars': 'off', + 'vue/one-component-per-file': 'off', + }, +} diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..bda05d0 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,54 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Deploy Docs + +on: + push: + branches: ['main'] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - name: Cancel Previous Workflow Runs + uses: n1hility/cancel-previous-runs@v2.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v3 + with: + ref: main + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: https://registry.npmjs.com/ + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i --frozen-lockfile + + - name: Build + run: pnpm run build:docs + + - name: Deploy to Doc Repository + uses: JamesIves/github-pages-deploy-action@v4.4.0 + with: + token: ${{ secrets.DEPLOY_DOCS_COW_LOW_CODE }} + branch: main + folder: docs/.vitepress/dist + repository-name: Cow-Coder/docs-cow-low-code + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/deploy-editor.yml b/.github/workflows/deploy-editor.yml new file mode 100644 index 0000000..0177701 --- /dev/null +++ b/.github/workflows/deploy-editor.yml @@ -0,0 +1,52 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Deploy Editor + +on: + push: + branches: ['main'] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - name: Cancel Previous Workflow Runs + uses: n1hility/cancel-previous-runs@v2.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v3 + with: + ref: main + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: https://registry.npmjs.com/ + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i --frozen-lockfile + + - name: Build + run: pnpm run build:editor + + - name: Deploy to GitHub Pages + uses: JamesIves/github-pages-deploy-action@v4.4.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + folder: dist/editor + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/deploy-preview.yml b/.github/workflows/deploy-preview.yml new file mode 100644 index 0000000..fd00dca --- /dev/null +++ b/.github/workflows/deploy-preview.yml @@ -0,0 +1,54 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Deploy Preview + +on: + push: + branches: ['main'] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - name: Cancel Previous Workflow Runs + uses: n1hility/cancel-previous-runs@v2.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v3 + with: + ref: main + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + registry-url: https://registry.npmjs.com/ + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i --frozen-lockfile + + - name: Build + run: pnpm run build:preview + + - name: Deploy to Doc Repository + uses: JamesIves/github-pages-deploy-action@v4.4.0 + with: + token: ${{ secrets.DEPLOY_DOCS_COW_LOW_CODE }} + branch: main + folder: dist/preview + repository-name: Cow-Coder/preview-cow-low-code + git-config-name: github-actions[bot] + git-config-email: github-actions[bot]@users.noreply.github.com diff --git a/.github/workflows/test-unit.yml b/.github/workflows/test-unit.yml new file mode 100644 index 0000000..8ae43e4 --- /dev/null +++ b/.github/workflows/test-unit.yml @@ -0,0 +1,43 @@ +# Unit Test + +name: Unit Test + +on: + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.number || github.sha }} + cancel-in-progress: true + +jobs: + build: + name: Unit Test (${{ matrix.node-name }}) + runs-on: ubuntu-latest + strategy: + matrix: + node-version: ['16'] + include: + - node-version: '16' + node-name: 'Latest' + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i --frozen-lockfile + + - name: Lint + run: pnpm lint diff --git a/.gitignore b/.gitignore index 38adffa..1345e2a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ dist dist-ssr coverage *.local +stats*.html +manual-chunks.txt /cypress/videos/ /cypress/screenshots/ @@ -20,6 +22,7 @@ coverage # Editor directories and files .vscode/* !.vscode/extensions.json +!.vscode/settings.json .idea *.suo *.ntvs* diff --git a/.husky/pre-commit b/.husky/pre-commit index a4fc325..b6b5ee5 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm exec lint-staged +pnpm exec lint-staged +pnpm exec pretty-quick --staged diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..82c1082 --- /dev/null +++ b/.npmrc @@ -0,0 +1,4 @@ +shamefully-hoist=true +strict-peer-dependencies=false +engine-strict=true +registry=https://registry.npmmirror.com/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..91238d0 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +dist +node_modules +stats.html +pnpm-lock.yaml +components.d.ts +auto-imports.d.ts diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..1d60754 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,5 @@ +module.exports = { + semi: false, + singleQuote: true, + printWidth: 100, +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c03db94 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "scss.lint.unknownAtRules": "ignore", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + "source.fixAll.stylelint": true + }, + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5bdffea --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Cow-Coder + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index a6e2898..25052e6 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,44 @@ -# cow_code-Low-Code +
-This template should help get you started developing with Vue 3 in Vite. + + + -## Recommended IDE Setup +

CowLowCode

+ + 一款面向扩展设计的移动端低代码平台 -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). +![license](https://img.shields.io/github/license/Cow-Coder/cow-Low-code?v=1) +![language](https://img.shields.io/github/languages/top/Cow-Coder/cow-Low-code) +![last](https://img.shields.io/github/last-commit/Cow-Coder/cow-Low-code) -## Type Support for `.vue` Imports in TS +![image](https://user-images.githubusercontent.com/49338067/186590858-b5af2520-3a65-46a5-8c48-0d29f34e5ef4.png) -TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. -If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: +
-1. Disable the built-in TypeScript Extension - 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette - 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` -2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. +| 主页 :house: | 演示 :beers: | 文档 :memo: | +| ---------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------ | +| [website](https://github.com/Cow-Coder/cow-Low-code) | [demo](https://cow-coder.github.io/cow-Low-code/) | [docs](https://cow-coder.github.io/docs-cow-low-code/) | -## Customize configuration +# :sparkles: 特性 -See [Vite Configuration Reference](https://vitejs.dev/config/). +- :package: 开箱即用的高质量生态元素,包括 物料体系、事件触发器、动作处理器 等 +- :electric_plug: 可视化拖放,可视化编辑配置 +- :rainbow: 利用 JSON 配置生成页面 +- :zap: 快速生成移动端 UI 界面 +- :rocket: 减少开发成本。 +- :technologist: 使用 TypeScript 开发,提供完整的类型定义文件 -## Project Setup +# :dart: 兼容环境 -```sh -npm install -``` - -### Compile and Hot-Reload for Development - -```sh -npm run dev -``` - -### Type-Check, Compile and Minify for Production - -```sh -npm run build -``` +- 现代浏览器(Chrome >= 64, Edge >= 79, Firefox >= 78, Safari >= 12) -### Lint with [ESLint](https://eslint.org/) +# :computer: 本地调试 -```sh -npm run lint +```bash +$ git clone https://github.com/Cow-Coder/cow-Low-code.git +$ cd cow-Low-code +$ pnpm i +$ pnpm run dev:editor ``` diff --git a/commitlint.config.js b/commitlint.config.js index bb8166f..103b21e 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1,93 +1,96 @@ /** @type {import("cz-git").UserConfig} */ module.exports = { - extends: ["@commitlint/config-conventional"], + extends: ['@commitlint/config-conventional'], rules: { // @see: https://commitlint.js.org/#/reference-rules }, prompt: { - alias: { fd: "docs: fix typos" }, + alias: { fd: 'docs: fix typos' }, messages: { - type: "选择你要提交的类型 :", - scope: "选择一个提交范围(可选):", - customScope: "请输入自定义的提交范围 :", - subject: "填写简短精炼的变更描述 :\n", + type: '选择你要提交的类型 :', + scope: '选择一个提交范围(可选):', + customScope: '请输入自定义的提交范围 :', + subject: '填写简短精炼的变更描述 :\n', body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n', breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n', - footerPrefixsSelect: "选择关联issue前缀(可选):", - customFooterPrefixs: "输入自定义issue前缀 :", - footer: "列举关联issue (可选) 例如: #31, #I3244 :\n", - confirmCommit: "是否提交或修改commit ?", + footerPrefixsSelect: '选择关联issue前缀(可选):', + customFooterPrefixs: '输入自定义issue前缀 :', + footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', + confirmCommit: '是否提交或修改commit ?', }, types: [ - { value: "feat", name: "feat: 新增功能 | A new feature" }, - { value: "fix", name: "fix: 修复缺陷 | A bug fix" }, + { value: 'feat', name: 'feat: 新增功能 | A new feature' }, + { value: 'fix', name: 'fix: 修复缺陷 | A bug fix' }, { - value: "docs", - name: "docs: 文档更新 | Documentation only changes", + value: 'docs', + name: 'docs: 文档更新 | Documentation only changes', }, { - value: "style", - name: "style: 代码格式 | Changes that do not affect the meaning of the code", + value: 'style', + name: 'style: 代码格式 | Changes that do not affect the meaning of the code', }, { - value: "refactor", - name: "refactor: 代码重构 | A code change that neither fixes a bug nor adds a feature", + value: 'refactor', + name: 'refactor: 代码重构 | A code change that neither fixes a bug nor adds a feature', }, { - value: "perf", - name: "perf: 性能提升 | A code change that improves performance", + value: 'perf', + name: 'perf: 性能提升 | A code change that improves performance', }, { - value: "test", - name: "test: 测试相关 | Adding missing tests or correcting existing tests", + value: 'test', + name: 'test: 测试相关 | Adding missing tests or correcting existing tests', }, { - value: "build", - name: "build: 构建相关 | Changes that affect the build system or external dependencies", + value: 'build', + name: 'build: 构建相关 | Changes that affect the build system or external dependencies', }, { - value: "ci", - name: "ci: 持续集成 | Changes to our CI configuration files and scripts", + value: 'ci', + name: 'ci: 持续集成 | Changes to our CI configuration files and scripts', }, - { value: "revert", name: "revert: 回退代码 | Revert to a commit" }, + { value: 'revert', name: 'revert: 回退代码 | Revert to a commit' }, { - value: "chore", - name: "chore: 其他修改 | Other changes that do not modify src or test files", + value: 'chore', + name: 'chore: 其他修改 | Other changes that do not modify src or test files', }, ], useEmoji: false, - emojiAlign: "center", - themeColorCode: "", + emojiAlign: 'center', + themeColorCode: '', scopes: [], allowCustomScopes: true, allowEmptyScopes: true, - customScopesAlign: "bottom", - customScopesAlias: "custom", - emptyScopesAlias: "empty", + customScopesAlign: 'bottom', + customScopesAlias: 'custom', + emptyScopesAlias: 'empty', upperCaseSubject: false, markBreakingChangeMode: false, - allowBreakingChanges: ["feat", "fix"], + allowBreakingChanges: ['feat', 'fix'], breaklineNumber: 100, - breaklineChar: "|", + breaklineChar: '|', skipQuestions: [], issuePrefixs: [ - // 如果使用 gitee 作为开发管理 - { value: "link", name: "link: 链接 ISSUES 进行中" }, - { value: "closed", name: "closed: 标记 ISSUES 已完成" }, + /** + * Linking a pull request to an issue + * @link https://docs.github.com/cn/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue + */ + { value: 'link', name: 'link: 链接 ISSUES 进行中' }, + { value: 'closed', name: 'closed: 标记 ISSUES 已完成' }, ], - customIssuePrefixsAlign: "top", - emptyIssuePrefixsAlias: "skip", - customIssuePrefixsAlias: "custom", + customIssuePrefixsAlign: 'top', + emptyIssuePrefixsAlias: 'skip', + customIssuePrefixsAlias: 'custom', allowCustomIssuePrefixs: true, allowEmptyIssuePrefixs: true, confirmColorize: true, - maxHeaderLength: Infinity, - maxSubjectLength: Infinity, + maxHeaderLength: Number.POSITIVE_INFINITY, + maxSubjectLength: Number.POSITIVE_INFINITY, minSubjectLength: 0, scopeOverrides: undefined, - defaultBody: "", - defaultIssues: "", - defaultScope: "", - defaultSubject: "", + defaultBody: '', + defaultIssues: '', + defaultScope: '', + defaultSubject: '', }, -}; +} diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000..6f263a6 --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,234 @@ +import { defineConfig } from 'vitepress' + +const ogDescription = + '移动端低代码平台、可视化拖放编辑、页面生成工具。通过 JSON 配置就能直接生成移动端UI界面,极大减少开发成本。' +// const ogImage = 'https://vitejs.dev/og-image.png' +const ogTitle = '牛搭' +const ogUrl = 'https://github.com/Cow-Coder/cow-Low-code' + +const base = '/docs-cow-low-code/' + +export default defineConfig({ + base, + title: ogTitle, + description: ogDescription, + lang: 'zh', + appearance: false, + lastUpdated: true, + + head: [ + ['link', { rel: 'icon', type: 'image/svg+xml', href: `${base}icon.svg` }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:title', content: ogTitle }], + // ['meta', { property: 'og:image', content: ogImage }], + ['meta', { property: 'og:url', content: ogUrl }], + ['meta', { property: 'og:description', content: ogDescription }], + ['meta', { name: 'theme-color', content: '#646cff' }], + ], + + themeConfig: { + logo: { src: '/logo.svg', alt: '牛搭' }, + siteTitle: false, + editLink: { + pattern: 'https://github.com/Cow-Coder/cow-Low-code/tree/main/docs/:path', + text: '为此页提供修改建议', + }, + + socialLinks: [{ icon: 'github', link: 'https://github.com/Cow-Coder/cow-Low-code' }], + + localeLinks: { + text: '简体中文', + items: [{ text: 'English(0%)', link: '#' }], + }, + + nav: [ + { text: '指南', link: '/guide/summary', activeMatch: '/guide/' }, + { text: '开发', link: '/development/prepare', activeMatch: '/development/' }, + { text: '文档', link: '/document/start', activeMatch: '/document/' }, + { + text: '相关链接', + items: [{ text: 'Team', link: '/team' }], + }, + ], + + sidebar: { + '/guide/': [ + { + text: '开始', + items: [ + { + text: '介绍', + link: '/guide/summary', + }, + ], + }, + { + text: '概念', + items: [ + { + text: '物料组件', + link: '/guide/component', + }, + { + text: '事件与动作', + link: '/guide/event-and-action', + }, + { + text: '样式', + link: '/guide/style', + }, + ], + }, + { + text: '基础', + items: [ + { + text: '预设', + link: '/guide/preset', + }, + { + text: '预览页面', + link: '/guide/preview', + }, + { + text: '发布页面', + link: '/guide/publish', + }, + ], + }, + { + text: '高级', + items: [ + { + text: '自定义动作执行器', + link: '/guide/custom-action', + }, + { + text: '自定义事件触发器', + link: '/guide/custom-trigger', + }, + ], + }, + { + text: '其他', + items: [ + { + text: '常见问题', + link: '/guide/question', + }, + ], + }, + ], + '/development/': [ + { + text: '起航', + items: [ + { + text: '准备工作', + link: '/development/prepare', + }, + { + text: '开始', + link: '/development/start', + }, + { + text: '文件夹结构', + link: '/development/dictionary', + }, + { + text: '样式', + link: '/development/style-design', + }, + { + text: '图标', + link: '/development/icon', + }, + { + text: '构建与部署', + link: '/development/build', + }, + ], + }, + { + text: '规范', + items: [ + { + text: '代码规范', + link: '/development/coding-style', + }, + { + text: '目录/命名规范', + link: '/development/dictionary-style', + }, + { + text: '文案规范', + link: '/development/copywriting-style', + }, + { + text: 'Git提交规范', + link: '/development/git-style', + }, + ], + }, + { + text: '进阶', + items: [ + { + text: '开发物料组件', + link: '/development/add-library-component', + }, + { + text: '开发动作执行器', + link: '/development/add-event-action', + }, + ], + }, + { + text: '质量', + items: [ + { + text: 'Lint', + link: '/development/lint', + }, + { + text: 'TypeScript', + link: '/development/typescript', + }, + { + text: '测试', + link: '/development/unit-test', + }, + ], + }, + { + text: '其他', + items: [ + { + text: '通过Git更新', + link: '/development/update-by-git', + }, + { + text: '常见问题', + link: '/development/question', + }, + ], + }, + ], + '/document/': [ + { + text: '文档编写', + items: [ + { + text: '开始', + link: '/document/start', + }, + { + text: '部分划分', + link: '/document/divide', + }, + ], + }, + ], + }, + }, +}) diff --git a/docs/.vitepress/theme/components/customer-evaluate.vue b/docs/.vitepress/theme/components/customer-evaluate.vue new file mode 100644 index 0000000..790060e --- /dev/null +++ b/docs/.vitepress/theme/components/customer-evaluate.vue @@ -0,0 +1,52 @@ + + + diff --git a/docs/.vitepress/theme/components/home-preview.vue b/docs/.vitepress/theme/components/home-preview.vue new file mode 100644 index 0000000..47ba417 --- /dev/null +++ b/docs/.vitepress/theme/components/home-preview.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/docs/.vitepress/theme/components/zoom-img.vue b/docs/.vitepress/theme/components/zoom-img.vue new file mode 100644 index 0000000..80ca8d9 --- /dev/null +++ b/docs/.vitepress/theme/components/zoom-img.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 0000000..ce73486 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,3 @@ +.VPNavBarTitle .logo { + height: 60px; +} diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..99c6e68 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,21 @@ +import { h } from 'vue' +import Theme from 'vitepress/theme' +import HomePreview from './components/home-preview.vue' +import ZoomImg from './components/zoom-img.vue' +import CustomerEvaluate from './components/customer-evaluate.vue' +import './styles/vars.css' +import './styles/vitepress.css' +import './custom.css' + +export default { + ...Theme, + Layout() { + return h(Theme.Layout, null, { + 'home-features-after': () => h(HomePreview), + }) + }, + enhanceApp({ app }) { + app.component('ZoomImg', ZoomImg) + app.component('CustomerEvaluate', CustomerEvaluate) + }, +} diff --git a/docs/.vitepress/theme/styles/vars.css b/docs/.vitepress/theme/styles/vars.css new file mode 100644 index 0000000..4604aad --- /dev/null +++ b/docs/.vitepress/theme/styles/vars.css @@ -0,0 +1,118 @@ +/** +邻近色 +原色: +47CCFF 58A3BF 177EA6 75D9FF 9AE3FF +辅助色 A: +5772FF 6170BF 1C32A6 8195FF A3B1FF +辅助色 B: +3FFF87 53BF7B 14A64B 6FFFA5 95FFBD +*/ + +/** + * Colors + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-brand: #646cff; + --vp-c-brand-light: #747bff; + --vp-c-brand-lighter: #9499ff; + --vp-c-brand-lightest: #bcc0ff; + --vp-c-brand-dark: #535bf2; + --vp-c-brand-darker: #454ce1; + --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-text-dark-1); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-text-dark-1); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-text-dark-1); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #47caff 30%, #5772ff); + + --vp-home-hero-image-background-image: linear-gradient(-45deg, #5772ff 30%, #47caff 50%); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} + +/** + * VitePress: Custom fix + * -------------------------------------------------------------------------- */ + +/* + Use lighter colors for links in dark mode for a11y. + Also specify some classes twice to have higher specificity + over scoped class data attribute. +*/ +.dark .vp-doc a, +.dark .vp-doc a > code, +.dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, +.dark .VPNavBarMenuLink.VPNavBarMenuLink.active, +.dark .link.link:hover, +.dark .link.link.active, +.dark .edit-link-button.edit-link-button, +.dark .pager-link .title { + color: var(--vp-c-brand-lighter); +} + +.dark .vp-doc a:hover, +.dark .vp-doc a > code:hover { + color: var(--vp-c-brand-lightest); + opacity: 1; +} + +/* Transition by color instead of opacity */ +.dark .vp-doc .custom-block a { + transition: color 0.25s; +} diff --git a/docs/.vitepress/theme/styles/vitepress.css b/docs/.vitepress/theme/styles/vitepress.css new file mode 100644 index 0000000..a938398 --- /dev/null +++ b/docs/.vitepress/theme/styles/vitepress.css @@ -0,0 +1,84 @@ +.home-hero .image { + width: 200px; + height: 200px; +} + +.nav-bar .logo { + height: 30px; + margin-right: 2px; +} + +.content img { + border-radius: 10px; +} + +.nav-dropdown-link-item .icon { + display: none; +} + +:root { + --c-brand: #646cff; + --c-brand-light: #747bff; +} + +.custom-block.tip { + border-color: var(--c-brand-light); +} + +.DocSearch { + --docsearch-primary-color: var(--c-brand) !important; +} + +#play-vite-audio { + padding: 0; + margin-left: 5px; + display: inline-flex; +} + +#play-vite-audio img { + opacity: 0.8; +} + +/* docs-cn specific */ +.cn-footnote { + margin-top: 20px; +} + +.cn-footnote .title { + display: block; + margin-bottom: 10px; +} + +.docs-cn-github-release-tag { + font-size: 14px; + font-weight: bold; + padding: 4px 6px; + margin-left: 6px; + background: var(--c-brand); + color: white; + border-radius: 10px; +} + +#wwads-container { + position: relative; + float: right; + z-index: 9; + margin: 0 0 16px 16px; +} + +#wwads-container .wwads-text { + font-size: 12px; +} + +.page .container .content { + clear: none !important; +} + +@media (min-width: 1368px) { + #wwads-container { + position: fixed; + bottom: 10px; + right: 10px; + margin: 0; + } +} diff --git a/docs/_data/team.js b/docs/_data/team.js new file mode 100644 index 0000000..0118beb --- /dev/null +++ b/docs/_data/team.js @@ -0,0 +1,47 @@ +export const core = [ + { + avatar: 'https://www.github.com/Yziyan.png', + name: '杨志颜', + title: '开发者', + org: 'Cow-Coder', + orgLink: 'https://github.com/Cow-Coder', + desc: '牛搭团队', + links: [{ icon: 'github', link: 'https://github.com/Yziyan' }], + }, + { + avatar: 'https://www.github.com/james-curtis.png', + name: '陈柯雨', + title: '开发者', + org: 'Cow-Coder', + orgLink: 'https://github.com/Cow-Coder', + desc: '牛搭团队', + links: [{ icon: 'github', link: 'https://github.com/james-curtis' }], + }, + { + avatar: 'https://www.github.com/20empty.png', + name: '李义华', + title: '开发者', + org: 'Cow-Coder', + orgLink: 'https://github.com/Cow-Coder', + desc: '牛搭团队', + links: [{ icon: 'github', link: 'https://github.com/20empty' }], + }, + { + avatar: 'https://www.github.com/zcxspace.png', + name: '张晨曦', + title: '开发者', + org: 'Cow-Coder', + orgLink: 'https://github.com/Cow-Coder', + desc: '牛搭团队', + links: [{ icon: 'github', link: 'https://github.com/zcxspace' }], + }, + { + avatar: 'https://www.github.com/Julian0197.png', + name: '马盛康', + title: '开发者', + org: 'Cow-Coder', + orgLink: 'https://github.com/Cow-Coder', + desc: '牛搭团队', + links: [{ icon: 'github', link: 'https://github.com/Julian0197' }], + }, +] diff --git a/docs/development/add-event-action.md b/docs/development/add-event-action.md new file mode 100644 index 0000000..c3be65c --- /dev/null +++ b/docs/development/add-event-action.md @@ -0,0 +1,203 @@ +# 开发动作执行器 + +`动作执行器` 是处于一个单独的 npm 包中,其位置在 `packages\event-action` + +大致目录结构请参阅:[packages/event-action](/development/dictionary.html#packages-event-action) + +::: details 细节 +该 npm 包无法单独打包发布,只能被使用了 vite 的其他包导入使用 +::: + +::: tip 提示 +由于动作执行器其特殊性,只能采用 `tsx` 进行开发 +::: + +上篇说了实现一个 `按钮` 物料组件 + +这里我们实现如下场景 + +- 点击按钮 +- 打开配置好的指定页面 + +具体配置如下 + + + +## 动作执行器定位 + +由于我们是希望现在开发的这个 action 能够打开指定的页面,故其应该属于页面相关的动作执行器,应该应该放置在 `packages\event-action\src\actions\page` + +暂且取名为 `OpenPage`,此时对应的目录名应为 `open-page` + +目录结构如下 + +```text +page +├── open-page # OpenPage动作执行器 +│ └── index.tsx +└── index.tsx # 动作执行器 page 分类的相关配置 +``` + +## 提供动作执行器的配置页面 + +首先,我们动作执行是可以的配置的对吧。打开哪个链接呢?是新窗口打开还是本窗口打开呢? + +这些属于我们的配置参数,我们可以将其定义为一个自定义 `type` + +```ts +type JumpLinkConfig = { + url: string + blank: boolean +} +``` + +接下来我们需要定义 action 本体,并提供相应的可配置界面 + +```tsx +/** + * 这里的泛型是为了提示handle和parseTip的参数 + */ +export default defineActionHandler({ + // 动作执行器唯一标识符 + name: 'OpenPage', + // 动作的标题 + label: '打开页面', + // 动作说明 + description: '打开/跳转至指定页面', + /** + * 配置面板 + * markRaw标记为非响应式 + * @link https://staging-cn.vuejs.org/api/reactivity-advanced.html#markraw + */ + configPanel: markRaw( + defineComponent({ + // 动作执行器配置面板唯一标识符 + name: 'OpenPageConfigPanel', + props: { + // 每一个动作执行器的配置面板在实例化时都会提供四个参数,也就是下面函数的返回值 + // 分别是 + // `actionConfig` 该action的配置,用于编辑情况 + // `libraryComponentInstanceTree` 物料组件实例树 + // `focusedLibraryComponentInstanceData` 当前被选中的物料组件实例 + // `libraryComponentSchemaMap` 物料组件结构定义 键值对哈希表:组件名->组件结构 + ...getActionHandleDefaultProps(), + }, + setup(props, { expose }) { + const formRef = ref>() + const config = ref({ + url: '', + blank: true, + }) + + /** + * 如果是编辑的话 + */ + if (props.actionConfig?.openMode) { + const actionConfig = toRaw(props.actionConfig) + config.value = actionConfig.config as JumpLinkConfig + } + + // 配置页面 + const render = () => ( + <> + + + + + + + + + + ) + + // 导出配置函数 + function exportConfig(): JumpLinkConfig { + return config.value + } + + /** + * 如果此action有配置属性则必须要导出名为 `exportConfig` 的函数 + * 用户打开的 配置dialog 会调用此函数来获取config的值 + */ + expose({ + exportConfig, + }) + return render + }, + }) + ), +}) +``` + +完成上述编码之后应该就能在配置 dialog 中看到开篇所见到的样子了 + +## 处理动作执行逻辑 + +目前为止我们还并不能执行这个动作,所以现在让我们来编写执行逻辑 + +```tsx +export default defineActionHandler({ + // ...其他配置 + + /** + * 这里其实会传入三个参数 + * 分别是 + * `config` 该动作的配置,类型是上面传入的泛型 + * `libraryComponentInstanceTree` 物料组件实例树 + * `libraryComponentSchemaMap` 物料组件结构定义 键值对哈希表:组件名->组件结构 + */ + handler(props) { + /** + * 执行动作逻辑 + */ + function handle(config: JumpLinkConfig) { + config.blank ? window.open(config.url) : window.location.assign(config.url) + } + handle(props) + }, +}) +``` + +现在您可以先配置再去点击按钮体验一下了 + +## 解析动作提示信息 + +您可能会看到属性面板的事件中不仅显示动作执行器名称,也显示了操作的详细,那是怎么显示的呢? + + + +下面我们一起来编写 `action 提示信息` + +```tsx +export default defineActionHandler({ + // ...其他配置 + + /** + * 同样这里有三个入参 + * 分别是 + * `config` 该动作的配置,类型是上面传入的泛型 + * `libraryComponentInstanceTree` 物料组件实例树 + * `libraryComponentSchemaMap` 物料组件结构定义 键值对哈希表:组件名->组件结构 + */ + parseTip(config) { + let link = '', + tip = '' + const jumpConfig: JumpLinkConfig = config + tip = '跳转至' + link = jumpConfig.url + + // 这里可以选择返回组件亦或是字符串 + return () => ( + <> + {tip} + {link} + + ) + }, +}) +``` + +::: tip 结束 +Congratulation!您已经掌握编写动作执行器的基本方法,开始向丛林跟深处进发吧! +::: diff --git a/docs/development/add-library-component.md b/docs/development/add-library-component.md new file mode 100644 index 0000000..e52a001 --- /dev/null +++ b/docs/development/add-library-component.md @@ -0,0 +1,227 @@ +# 开发物料组件 + +在开发之前首先需要确认组件的定位,是属于 `通用组件` 还是 `业务组件` 亦或是其他大类。 + +再次要确定其小类,也就是属于 `表单` 还是 `展示` 还是其他小类。其对应关系如下 + + + +大致目录结构请参阅:[packages/event-action](/development/dictionary.html#packages-library) + +这里我们以 `通用组件` -> `展示` 中的 `按钮` 物料组件为例进行说明讲解 + +## 开始 + +牛搭采用的是 `monorepo` 架构来处理预览模块和 editor 共用物料组件的文件。在 `packages` 下的每一个目录都是一个单独的 npm 包。 + +::: warning 注意 +并不是 `packages/*` 下的每一个包都能够单独发布。 + +如 `packages/event-action` 就只能被使用了 vite 的包(如 `packages/editor` )进行导入使用 +::: + +根据上述说明的组件定位,现在进入 `packages\library\src\components\generic\input\button` 文件夹,这里就是存放 `button` 物料组件的位置 + +请注意,这里文件的存放方式。根据规范,需要按照如下要求进行存放 + +```text +input +├── button +│ └── index.vue +└── textbox + └── index.vue +``` + +::: danger 警告 +**不能**像这样,将物料组件平铺在目录下 + +```text +input +├── button.vue +└── textbox.vue +``` + +::: + +## 最简示例 + +在这里您可以选择使用 `.vue` 或者 `.tsx`,这里以 `.vue` 为例 + +一个最简单的物料看起来是这样的: + +```vue + + + + +``` + +请观察上面的代码,与开发中后台时候的组件有什么异同? + +是的,并没有什么不同,这里开发与中后台的开发十分相似。只不过多了一些配置选项,下面我们一一进行讲解。 + +## 导出对象 + +下面是这个 button 物料组件 ` +``` + +::: tip 结束 +Congratulation!您已经掌握编写物料组件的基本方法,开始向丛林跟深处进发吧! +::: diff --git a/docs/development/build.md b/docs/development/build.md new file mode 100644 index 0000000..d4a1d5b --- /dev/null +++ b/docs/development/build.md @@ -0,0 +1,81 @@ +# 构建与部署 + +## 构建 + +开发完成之后,使用 `pnpm run build:editor` 进行构建,构建打包成功之后,会在根目录生成 `dist/editor` 文件夹,里面就是构建打包好的文件。 + +::: tip 提示 +如果需要构建 `docs`、`preview` + +请使用 `pnpm run build:docs`、`pnpm run build:preview` + +其中打包生成的目录分别位于 `docs/.vitepress/dist`、`dist/preview` + +如果需要构建 `vite-plugin-monaco-editor-nls`、`build-utils` 等,请执行对应 `package.json` 中的相应脚本 +::: + +## 预览 + +生成好的 dist 文件夹一般需要部署至服务器才算部署发布成功,但为了保证构建出来的文件能正常运行,开发者通常希望能在本地先预览一下,这里介绍两种方式 + +- 执行相应 `package.json` 中的脚本 + 例如 `packages\editor\package.json` 中的 `preview` 命令 + +```sh +# -C 选项,请参阅:https://pnpm.io/zh/pnpm-cli#%E9%85%8D%E7%BD%AE%E9%A1%B9 +pnpm -C packages\editor preview +``` + +- 本地服务器预览 + +```sh +# 进入打包的后目录 +cd packages\editor +# 本地预览,默认端口8080 +npx http-server +``` + +## 分析构建文件体积 + +如果构建文件很大,可以通过 [rollup-plugin-visualizer](https://www.npmjs.com/package/rollup-plugin-visualizer) 插件进行代码体积分析,从而优化你的代码。 + +打包之后您应该能在对应包的根目录下找到 `stat.html` 文件 + +打开之后可以看到具体的体积分布,以分析哪些依赖有问题。 + + + +## 部署 + +简单的部署只需要将最终生成的静态文件,dist 文件夹的静态文件发布到 cdn 或者静态服务器即可 + +### 使用 nginx 处理跨域 + +使用 nginx 处理项目部署后的跨域问题 + +1. 配置前端项目接口地址 + +```text +http://10.10.10.10:8080/api +``` + +2. 在 nginx 配置请求转发到后台 + +```nginx +server { + listen 80; + server_name example.com; + # 接口代理,用于解决跨域问题 + location /api { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # 后台接口地址 + proxy_pass http://10.10.10.10:8080/api; + proxy_redirect default; + add_header Access-Control-Allow-Origin *; + add_header Access-Control-Allow-Headers X-Requested-With; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; + } +} +``` diff --git a/docs/development/coding-style.md b/docs/development/coding-style.md new file mode 100644 index 0000000..d39e324 --- /dev/null +++ b/docs/development/coding-style.md @@ -0,0 +1,40 @@ +# 代码规范 + +## IDE 编辑器 + +如果您使用的是 WebStorm,那么可以在设置中开启下列功能: + +- `语言和框架 > JavaScript > 代码质量工具 > ESLint` 勾选 `保存时运行eslint --fix` +- `语言和框架 > JavaScript > Prettier` 勾选 `执行"重新格式化代码"操作时` 和 `保存时` + +如果您使用的是 Visual Studio Code,框架源码里已提供相关配置文件,可直接测试效果:在保存代码时,会自动对当前文件进行代码格式化操作。 + +## husky & lint-staged + +由于 IDE 能做的事比较有限,只能对代码的书写规范进行格式化,对于一些无法自动修复的错误代码,如果没有改正到就被推送到 git 仓库,在多人协作开发时,可能会影响到别人的开发体验。所以我们集成了 husky 和 lint-staged 这两个依赖来解决这一问题。 + +在提交代码时,husky 会通过 lint-staged 对 /src 目录下的 js vue scss 文件进行分别进行 eslint 和 stylelint 检测,如果有报错,则会阻止本次代码提交,直到开发者修改完所有错误代码后,才允许提交到 git 仓库,这样可以确保 git 仓库里的代码不会有语法错误。 + +::: tip 提示 +可通过修改 `.eslintignore` 和 `.prettierignore` 忽略无需做代码规范校验的文件,例如在项目中导入了一些第三方的插件或组件,我们就可以将其进行忽略。 +::: + +## 配置代码规范 + +配置文件主要有 3 处,分别为 + +- IDE 配置(`.editorconfig`) +- ESLint 配置(`.eslintrc.cjs` 和 `.eslintignore`) +- Prettier 配置(`.prettierrc.cjs` 和 `.prettierignore`) + +通过下面命令会将代码进行一次格式校验,如果规则支持自动修复,则会将不符合规则的代码自动进行格式化。 + +```shell +pnpm run lint:fix +``` + +而使用 `pnpm run lint` 可以检测当前代码还有哪些地方是不符合规范的。 + +## 关闭代码规范校验 + +注重代码规范是一个程序员的职业基本素养,并且当多人协助开发时,它是保证代码一致性的最佳手段。 diff --git a/docs/development/copywriting-style.md b/docs/development/copywriting-style.md new file mode 100644 index 0000000..0bfc13c --- /dev/null +++ b/docs/development/copywriting-style.md @@ -0,0 +1,44 @@ +# 文案规范 + +::: info 信息 +本文档难免也有不符合规范之处,期待您的修正。 +::: + +## 时间、日期表示方式 + +为了格式区分,年月日之间用半角短横线『-』,时分秒之间使用半角冒号『:』 表示范围之间使用半角波浪线『~』或使用中文 『至』,并在其前后加上间隔以示区分 + +`2014-04-16 09:30:00 ~ 2014-04-20 18:00:00` + +`2014-04-16 至 2014-04-20` + +## 空格规范 + +1. 全角字符和半角字符搭配时,需要添加空格。最常见的全角字符:汉字。常用的半角字符:英文、数字。 +2. 中文链接之间增加添加空格。 + +## 特殊数值的表示方式 + +1. 金额的间隔方式: `1,000,000`。 +2. 小数点后保留两位:`200.00`。 + +## 以下情况不使用句号 + +1. 输入框下的提示。 +2. 表格中的句子。 +3. 句末为文字链(链接前使用句号)。 + +## 专业精准的用词建议 + +1. 使用『你』代替『您』,以拉近与用户之间的距离,尽量不使用『我』,避免对象指向不明。 +2. 使用『编辑』代替『修改』。 +3. 使用『其他』代替『其它』,『其他』的应用范围更广。 +4. 使用『此』代替『该』,当要表达当前事物时,『此』更加明确。 +5. 使用『抱歉』而不用『对不起』,如果是我们系统造成的结果,可以使用『抱歉』,如果是用户自己造成的结果,则不使用这类词。 +6. 使用『登录』而不用『登陆』,登录是登记记录用户输入信息的意思,切勿用成『着陆』的陆。 + +::: tip 提示 +此页参考自:[Ant-Design-设计基础简版](https://github.com/ant-design/ant-design/wiki/Ant-Design-%E8%AE%BE%E8%AE%A1%E5%9F%BA%E7%A1%80%E7%AE%80%E7%89%88) + +了解更多请查阅:[文案 - Ant Design](https://ant-design.antgroup.com/docs/spec/copywriting-cn) +::: diff --git a/docs/development/dictionary-style.md b/docs/development/dictionary-style.md new file mode 100644 index 0000000..371eb86 --- /dev/null +++ b/docs/development/dictionary-style.md @@ -0,0 +1,160 @@ +# 目录/命名规范 + +由于我们没有找到类似 `Airbnb JavaScript Style` 这类高质量的目录规范。所以我们根据自己的调研结果整理出来了一套适用于本项目的目录规范 + +::: info 提示 +详细的调研结果请参阅:https://cw39gvucrn.feishu.cn/docx/doxcnU18YY3qxxDvScQuHEPiUvd + +这里是示例,可以帮助您更好的理解:https://boardmix.cn/app/editor/Wldc0peQxM_G5R7Z_M9VMQ +::: + +总体上,我们命名使用全称。尽量避免使用缩写。 + +## 组件文件名 + +中划线 + +> [单文件组件文件的大小写](https://v2.cn.vuejs.org/v2/style-guide/index.html#%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6%E6%96%87%E4%BB%B6%E5%90%8D%E7%9A%84%E5%A4%A7%E5%B0%8F%E5%86%99%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90) +> +> 官方描述是`大驼峰`和`中划线`二选一 + +## 组件目录结构 + +```text +├─组件名 +│ ├─components +│ │ ├─单文件组件.vue +│ │ ├─单文件组件.vue +│ ├─index.vue +``` + +## 全局 css、css 变量位置 + +```text +/src/asset/style +``` + +## 全局 css 变量文件名 + +```text +/src/asset/style/xxx.scss +``` + +## 组件内 style、hooks、types 等位置 + +```text +. +├─index.vue/index.tsx +├─index.module.less +├─other.less +``` + +## hook 文件名 + +中划线 + +## 全局 hook 目录结构 + +```text +/src/hooks +├─use-xxx.ts +``` + +## 项目全局常量位置 + +``` +/src/constants +``` + +## 项目全局类型声明文件 d.ts 位置 + +``` +/types +``` + +## 项目全局类型定义文件位置 + +``` +/src/types +``` + +## 子组件(二级组件、三级组件以及其他后代组件)位置 + +平铺型(除非该组件还有附带 css,或者子组件) + +``` +├─组件名 +│ ├─components +│ │ ├─单文件组件.vue +│ │ ├─单文件组件.vue +│ ├─index.vue +``` + +## interface 和 type 变量名是否加前后缀 + +❌ + +## enum 变量名是否带后缀 + +✅ + +## interface 和 type 名称命名 + +大驼峰 + +## 组件内工具函数文件命名(未调研) + +[util.ts](https://pro.ant.design/zh-CN/docs/folder#:~:text=%7C%20%20%20%E2%94%94%E2%94%80%E2%94%80-,util.ts,-//%20%E8%BF%99%E9%87%8C%E5%8F%AF%E4%BB%A5%E6%9C%89) + +## 组件分组(未调研) + +分类文件夹下不得有裸露的组件,可以有统一导出文件`index.ts`,必须用文件夹包裹。同等于[一级组件](https://cw39gvucrn.feishu.cn/docx/doxcnU18YY3qxxDvScQuHEPiUvd#doxcnJ7d7uW5YKUIRjGt4y1sELf) + +``` +library + ├── generic + │ ├── input + │ │ └── button + │ │ └── index.vue + │ └── show + │ ├── image + │ │ └── index.vue + │ └── swipe + │ ├── components + │ └── index.vue + └── index.ts +``` + +## 组件名、文件夹名称哪些单词可以缩写 + +- 组件名任何情况下不得缩写,参考[完整单词的组件名强烈推荐](https://v2.cn.vuejs.org/v2/style-guide/#%E5%AE%8C%E6%95%B4%E5%8D%95%E8%AF%8D%E7%9A%84%E7%BB%84%E4%BB%B6%E5%90%8D%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90) +- 文件夹名称任何情况下不得缩写 + +## 属性 + +- 初始化属性,命名方式为: default + 属性名 +- 强制渲染属性: forceRender + - 强制渲染子组件: force + 子组件名 + Render +- 数据源: dataSource +- children : + - 主要展示区域内容 ,避免额外的属性名称 + - 选项相关诸如 Option 、TreeNode + - 自定义包裹组件可以考虑 coponent 如果 children 会存在它用的情况 +- 展示相关命名方式为: show + 属性名 +- 功能相关命名方式为: 属性名 + able +- 禁用子组件功能: disabled + 子组件名 +- 主图标: icon + - 多个图标: 功能 + Icon +- 触发点: trigger + - 子功能触发: 子功能 + Trigger + - 在触发某个时间时处理某件事情: xxx + On + 事件名 (例:destroyOnClose) + +## 事件 + +- 触发事件: on + 事件名 +- 在触发之前的事件: before + 事件名 +- 在触发之后的事件: after + 事件名 + +::: details 细节 +[属性](#属性) 和 [事件](#事件) 部分参考自:[Ant Design](https://github.com/ant-design/ant-design/wiki/API-Naming-rules) +::: diff --git a/docs/development/dictionary.md b/docs/development/dictionary.md new file mode 100644 index 0000000..450090b --- /dev/null +++ b/docs/development/dictionary.md @@ -0,0 +1,263 @@ +# 文件夹结构 + +牛搭采用 `monorepo` 架构实现物料组件(libraryComponent)和动作处理器(actionHander)在编辑器(editor)和预览模块(preview)等多个包之间共用 + +下面的图示将更好的帮助您理解 + + + +::: details 细节 +了解更多 `monorepo` 相关,请参阅: +[Monorepo 是什么,为什么大家都在用?](https://zhuanlan.zhihu.com/p/77577415) +::: + +## 概览 + +```text +cow-Low-code +├── .husky # git钩子 +│ ├── _ +│ ├── commit-msg # 校验commit msg规范 +│ └── pre-commit # 校验&格式化代码 +├── .vscode # vscode预设 +│ ├── extensions.json +│ └── settings.json +├── docs # 项目文档 +├── internal # 内部package +│ ├── build-utils # 构建工具 +│ ├── vite-plugin-monaco-editor-nls # monaco-editor 汉化插件 +│ └── vscode-language-pack-zh-hans # monaco-editor 中文语言包插件 +├── packages # 项目主要package +│ ├── constant # 全局常量 +│ ├── editor # 页面编辑器 +│ ├── event-action # 事件动作执行器 +│ ├── library # 物料组件库 +│ ├── preview # 预览模块 +│ ├── types # 全局类型定义 +│ └── utils # 全局工具库 +├── .editorconfig # IDE编辑器选项预设 +├── .eslintignore # eslint 忽略规则 +├── .eslintrc.cjs # eslint 配置 +├── .npmrc # pnpm 配置 +├── .prettierignore # prettier 忽略规则 +├── .prettierrc.cjs # prettier 配置 +├── LICENSE +├── README.md +├── commitlint.config.js # commit lint 配置 +├── package.json +├── pnpm-lock.yaml +└── pnpm-workspace.yaml # monorepo 工作空间配置 +``` + +## packages/constant + +全局常量 + +```text +constant +├── src +│ └── index.ts # 常量 +└── package.json # 每一个包都必须包含该文件 +``` + +## packages/editor + +页面编辑器 + +```text +editor +├── config # editor 项目配置文件 +│ ├── plugins # vite 插件 +│ ├── vite.config.base.ts # 基础 vite 配置 +│ ├── vite.config.dev.ts # 开发环境 vite 配置 +│ └── vite.config.prod.ts # 生产环境 vite 配置 +├── public +│ └── icon.svg +├── src +│ ├── assets # 静态资源/全局样式 +│ ├── components # 通用组件 +│ ├── constant # 全局常量 +│ ├── directive # 全局自定义指令 +│ ├── hooks # 全局组合式函数 +│ ├── library # 导入 packages/library +│ ├── plugins # 项目用到的npm包,直接写在main.ts不方便,就放这里 +│ ├── router # 路由 +│ ├── stores # pinia store +│ ├── types # editor 类型定义 +│ ├── utils # 工具库 +│ ├── views # 业务页面入口 +│ ├── App.vue +│ └── main.ts +├── types # editor 类型声明 +│ ├── auto-imports.d.ts # unplugin-auto-import 自动生成 +│ ├── color-picker.d.ts # color-picker-v3 类型声明 +│ ├── components.d.ts # unplugin-vue-components 自动生成 +│ ├── env.d.ts # vite/client 类型声明 +│ └── global.d.ts # 其他全局类型声明 +├── index.html # 入口文件 +├── package.json +├── pnpm-lock.yaml +├── postcss.config.js # 服务于 tailwind +├── stats.html # rollup-plugin-visualizer 打包大小分析 +├── tailwind.config.js # tailwind 配置文件 +├── tsconfig.config.json # node 环境typescript配置 +└── tsconfig.json # web 环境typescript配置 +``` + +## packages/event-action + +事件动作执行器 + +```text +event-action +├── src +│ ├── actions # 触发器 +│ │ ├── component # 组件类触发器 +│ │ ├── other # 其他类别触发器 +│ │ ├── page # 页面类触发器 +│ │ └── service # 服务类触发器 +│ └── utils # 工具库 +│ └── util.ts +├── types # 类型声明 +│ └── env.d.ts # vite/client 类型声明 +├── index.ts +├── package.json +└── tsconfig.json # web 环境typescript配置 +``` + +## packages/library + +物料组件库 + +```text +library +├── src +│ ├── components # 物料组件 +│ │ ├── business # 业务组件 分类 对应于 editor 业务组件 tab +│ │ │ └── show # 展示 小类 对应于 editor 业务组件 tab 下的 show collapse +│ │ │ └── swipe # 幻灯片 +│ │ └── generic # 通用组件 分类 +│ │ ├── input # 表单 小类 +│ │ │ ├── button # 按钮 +│ │ │ │ └── index.vue # 按钮组件入口 +│ │ │ └── textbox # 文本框 +│ │ │ └── index.vue +│ │ └── show # 展示 小类 +│ │ ├── collapse # 折叠面板 +│ │ │ ├── components # 子组件 +│ │ │ │ └── preview.vue +│ │ │ └── index.vue # 组件入口 +│ │ ├── image # 图片 +│ │ │ └── index.vue +│ │ ├── notice-bar # 通知栏 +│ │ │ └── index.vue +│ │ └── swipe # 轮播图 +│ │ ├── components # 子组件 +│ │ │ └── preview.vue +│ │ └── index.vue # 入口 +│ ├── hooks # 组合式函数 +│ │ ├── use-library-component-custom-trigger.ts +│ │ └── use-multi-click.ts +│ └── utils # 工具库 +│ └── library.ts +├── types # 类型声明 +│ └── env.d.ts +├── index.ts # 物料组件库入口文件 +├── package.json +├── tsconfig.config.json # node 环境typescript配置 +└── tsconfig.json # web 环境typescript配置 +``` + +## packages/preview + +预览模块 + +文件夹结构同 `packages/editor` 这里不再赘述 + +```text +preview +├── config +│ ├── plugins +│ ├── vite.config.base.ts +│ ├── vite.config.dev.ts +│ └── vite.config.prod.ts +├── src +│ ├── plugins +│ ├── router +│ ├── stores +│ ├── views +│ ├── App.vue +│ └── main.ts +├── types +│ ├── auto-imports.d.ts +│ ├── components.d.ts +│ └── env.d.ts +├── index.html +├── package.json +├── tsconfig.config.json +└── tsconfig.json +``` + +## packages/types + +全局类型定义 + +```text +types +├── src +│ ├── action.ts # 动作处理器 相关类型定义 +│ ├── event-trigger.ts # 事件触发器 相关类型定义 +│ ├── library-component.ts # 物料组件 相关类型定义 +│ ├── panel.ts # 操作面板/设置器 相关类型定义 +│ └── util.ts # 工具库 相关类型定义 +├── index.ts # 入口文件 +├── package.json +└── tsconfig.json # web 环境typescript配置 +``` + +## packages/utils + +全局工具库 + +``` +utils +├── src +│ ├── action.ts # 动作处理器 工具库 +│ └── library.ts # 物料组件 工具库 +├── index.ts # 入口文件 +└── package.json +``` + +## internal/build-utils + +构建工具,用于定位构建输出目录 + +```text +build-utils +├── src +│ ├── index.ts # 构建工具入口文件 +│ └── paths.ts # 打包输出路径配置 +├── build.config.ts # unbuild 打包工具配置文件 +├── package.json +└── tsconfig.json # node 环境typescript配置 +``` + +## internal/vite-plugin-monaco-editor-nls + +monaco-editor i18n 插件,自行修复维护,不依赖原作者 + +```text +vite-plugin-monaco-editor-nls +├── src +│ ├── locale # 旧版语言包 +│ └── index.ts # 插件入口 & 核心 +├── README.md +├── package.json +└── tsconfig.json +``` + +## internal/vscode-language-pack-zh-hans + +由于没有适用于 vite 的 monaco-editor 相关语言包作为 npm 包单独发布 + +所以这里直接将语言包内置于项目之中,随时同步官方 [vscode-loc](https://github.com/microsoft/vscode-loc) diff --git a/docs/development/git-style.md b/docs/development/git-style.md new file mode 100644 index 0000000..71fdb6e --- /dev/null +++ b/docs/development/git-style.md @@ -0,0 +1,75 @@ +# Git 提交规范 + +有关更多信息,请参阅[约定式提交](https://www.conventionalcommits.org/zh-hans/v1.0.0/) + +Git 命令学习,请参阅[Learn Git Branching](https://oschina.gitee.io/learn-git-branching/) + +## 提交格式 + +```text +type(): subject + + + +