npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tushi11/elpis

v1.0.34

Published

- Elpis 是一个基于 Node.js + Koa2 + Vue3 的全栈开发平台。旨在通过配置化的方式快速构建企业级管理系统。项目采用模块化架构设计,支持多项目管理。 - elpis 的设计初衷是为了解决重复性的增删改查工作,将常规的增删改查沉淀到模型中,通过模型解析器解析模型配置,加上模型数据渲染组件将数据渲染到页面,并且支持常规交互 - 最终打造一个全栈,全流程去开发一个支持多网站建设的系统平台(应用框架)。能通过配置化去沉淀 80%的重复性需求,并且提供各种各样的定制化能力,可灵活支持剩余

Readme

elpis 企业级应用框架

  • Elpis 是一个基于 Node.js + Koa2 + Vue3 的全栈开发平台。旨在通过配置化的方式快速构建企业级管理系统。项目采用模块化架构设计,支持多项目管理。
  • elpis 的设计初衷是为了解决重复性的增删改查工作,将常规的增删改查沉淀到模型中,通过模型解析器解析模型配置,加上模型数据渲染组件将数据渲染到页面,并且支持常规交互
  • 最终打造一个全栈,全流程去开发一个支持多网站建设的系统平台(应用框架)。能通过配置化去沉淀 80%的重复性需求,并且提供各种各样的定制化能力,可灵活支持剩余 20%的定制化需求开发。

问题

传统开发中,80%的时间消耗在重复性业务逻辑上:

  1. 基础 CRUD 接口的重复开发
  2. 表单 / 表格 / 搜索框等组件的重复编写
  3. 验证逻辑、交互逻辑的重复实现

解决方案

Elpis 通过 DSL 领域模型的开发范式重构开发流程:

  1. 统一建模层

    • 模型使用继承的理念,一个领域模型可以衍生出若干个项目
  2. 智能解析引擎

    • 模型 → 页面:自动生成 CRUD 标准页面

    • 模型 → 组件:动态渲染表单/表格/搜索框/详情面板/...

    • 模型 → 菜单:自动化配置前端路由

  • 一个领域模型可以衍生出若干个项目,领域模型项目的关系是对象继承关系,项目(子类)继承于领域模型(基类),领域模型可以沉淀各个项目中重复功能/页面,实现复用。

项目技术栈

| 后端技术栈 | 前端技术栈 | | ------------------------------- | --------------------------------- | | 框架: Koa2 | 框架: Vue 3 (Composition API) | | 模板引擎: Nunjucks | UI 组件库: Element Plus | | 测试框架: Mocha + Supertest | 状态管理: Vuex 4 | | 工具库: Lodash, MD5, Glob | 路由: Vue Router 4 | | | 构建工具: Webpack 5 | | | 样式预处理: Less |

项目架构设计

  • 展示层:Vue3 + element-plus + webpack5

    • 融合了多页面 SSR-MPA单页面 CSR-SPA两种模式。在配置多个单页面入口的基础上,赋予每个单页面通过前端路由跳转子页面的能力。
    • 通过服务端渲染生成多页面(SSR)入口,里面渲染的不同 页面/路由 都是一个独立的单页面 CSR-SPA 应用,是通过前端路由 router实现子页面间的无缝切换(即首屏是服务端渲染,次屏是客户端渲染的)
    • 整个方案利用起首屏里 SEO 的好处,次屏 SPA 的好处
  • BFF 层:Node.js18(Koa2)

    • 细分为接入层、业务层和服务层。
      • 接入层主要负责路由分发,通过分析页面请求来判断是进行渲染操作还是调用 BFF 接口;
      • 业务层聚焦于前端页面所需的各类业务处理,为页面功能实现提供业务逻辑支撑;
      • 服务层则主要承担获取数据的处理工作,保障数据的有效获取与传递。
  • 数据层:MySQL + log4js 日志

    • 包括了数据库,日志,后端服务接口以及其他各类数据来源。
  • (这个系统用的是 nodejs 来作为运行时页面服务器,同时它也是 API 的 BFF 层)

model 配置(核心)

model 的配置是使用 elpis 的重中之重,根据下面给到的 model 示例配置,进行项目 model 模型配置。

Model 是 Elpis 的核心配置单元,通过定义领域模型的结构、交互和接口,驱动全栈功能生成。

{
  mode: 'dashboard', // 模板类型,不同模板类型对应不一样的模板数据结构
  name: '', // 模板名称
  desc: '', // 模板描述
  icon: '', // 模板图标
  homePage: '/schema?proj_key=pdd&key=product', // 模板首页(项目配置) // proj_key=项目的文件名 || key=头部菜单栏的默认选中项 || sider_key=左侧菜单栏的默认选中项
  // 头部菜单
  menu: [
    {
      key: '', // 菜单唯一描述
      name: '', // 菜单名称
      menuType: '', // 菜单类型(菜单目录、菜单项) group | module

      // 当menuType == group时,可填
      subMenu: [
        {
          // 可递归的菜单项 menuItem
        },
          // ...
      ],

      // 当menuType == module时,可填
      moduleType: '', // 模块类型: sider | iframe | custom | schema

      // 当moduleType == sider 时
      siderConfig: {
        menu: [
          {
            // 可递归的菜单项 menuItem (除 moduleType === sider)
          },
            // ...
        ],
      },

      // 当moduleType == iframe 时
      iframeConfig: {
        path: '', // iframe 模块路径
      },

      // 当moduleType == custom 时
      customConfig: {
        path: '', // 自定义路由路径
      },

      // 当moduleType == schema 时
      schemaConfig: {
        api: '', // 数据源API(遵循 RESTFUL 规范)
        schema: {
          // 板块数据结构
          type: 'object',
          properties: {
            key1: {
              ...schema, // 标准 schema 配置(如:minLength: 2,pattern: '^[a-z0-9_]+$')
              type: '', // 字段类型(array|string|nubmer|object) // 多个类型传递数组['string','number']
              label: '', // 字段的中文名
              // 字段在 table 中的相关配置
              tableOption: {
                ...elTableColumnConfig, // 标准 el-table-column 配置
                visible: true, // 默认为 true(为 false 时,表示不在 table 中显示)


                // 当前字段的格式化配置
                formatConfig:{
                  color: 'red', // 单元格颜色(支持十六进制/rgb/颜色名)
                  // 1. 自定义格式化函数(优先级最高)// value为当前单元格的值,row为当前行的数据
                  formatFn: (value, row) => `${value}元`,

                  // 以下为预设格式化类型配置。(可选,'date'/'enum'/'number') // formatType 和 formatOptions 需同时配置。
                  // 1. 日期格式化
                  formatType: 'date', // 预设日期类型
                  formatOptions: 'YYYY-MM-DD HH:mm:ss', // 日期格式(可选,默认YYYY-MM-DD HH:mm:ss)
                  // 2. 枚举格式化(如性别、状态)
                  formatType: 'enum', // 预设枚举类型
                  formatOptions: { 1: '男', 2: '女', 3: '未知' },
                  enumColor: { 1: 'green', 2: '#e6a23c', 3: 'orange' } // 枚举颜色映射(支持颜色名/十六进制/rgb)
                  // 3. 数字格式化(如金额、百分比)
                  formatType: 'number', // 预设数字类型
                  formatOptions: { toFixed: 2, unit: '元' }, // 保留2位小数+添加单位
                }
              },
              // 字段在 search-bar 中的相关配置
              searchOption: {
                ...elComponentConfig, // 标准 el-component-column 配置
                comType: '', // 配置组件类型(如 input/select/...)
                default: '', // 默认值

                // 当 comType === select 时
                enumList: [], // 下拉框可选项 // 当 comType === 'dynamicSelect' 时,会和 API 可选项进行合并
                // 当 comType === 'dynamicSelect'
                api: '',
              },
              // 字段在不同动态 component 中的相关配置,前缀对应 componentConfig 中的键值
              // 如:componentConfig.createForm,这里对应 createFormOption
              // 字段在 createForm 中相关配置
              createFormOption: {
                ...elComponentConfig, // 标准 el-component 配置
                comType: '', // 控件类型(有:input/select/checkbox/input-number/switch/radio/dateTimePicker/textarea/cascader)
                visible: true, // 是否展示(true/false),默认为 true
                disabled: false, // 是否禁用(true/false),默认为 false
                default: '1', // 默认值   (当 comType === 'checkbox' 可配置字符串或数组)

                // 当 comType === 'select'|'radio'|'checkbox' 时生效 // 枚举列表
                enumList: [
                  { value: 1, label: 'option1' },
                  { value: 2, label: 'option2' },
                ],

                //  当 comType === 'select'时并使用了api时生效。适配接口返回字段名不一致的情况(如接口返回 name/code,可通过配置映射)
                labelKey:'name',
                valueKey: 'code',

               // 当 comType === 'select'|radio'|'checkbox' 时生效
                api: '',
                apiParams: '', // 传递接口参数

                // 当 comType === 'switch' 时生效
                switchModelType:'', // switch 类型,可选值:'boolean'、'string',默认:'boolean'

                // 当 comType === 'dateTimePicker' 时。配置 shortcuts 快捷选项时,value 需直接传递 Date 对象。禁止直接使用函数(() => {})作为 value,否则会导致组件无法解析赋值
                shortcuts: [
                  { text: '今天', value: new Date() },
                  {
                    text: '昨天',
                    // value 不能是函数类型。必须使用立即执行函数提前计算并返回Date对象
                    value: (() => {
                       return new Date().setDate(new Date().getDate() - 1);
                    })(),
                  },
                ],
              },
              // 字段在 editForm 表单中的相关配置
              editFormOption: {
                ...elComponentConfig, // 标准 el-component 配置
                comType: '', // 控件型(如 input/select/...)
                // ...... 参考 createFormOption
              },
              detailPanelOption: {
                ...elComponentConfig, // 标准 el-component 配置
              },
            },
          },
          required: [], // 必填字段列表
        },
        // table 相关配置
        tableConfig: {
          // 表格头部按钮
          headerButtons: [
            {
              label: '', // 按钮名称
              eventKey: '', // 按钮事件名称
              // 按钮事件具体配置
              eventOption: {
                // 当 eventKey === 'showComponent'时,启用 comName,决定调用哪个组件
                comName: '', // 组件名称
              },
              ...elButtonConfig, // 标准 el-button 配置
            },
            // ...
          ],
          // 表格行内按钮
          rowButtons: [
           // 按钮事件具体配置
            {
              label: '', // 按钮名称
              eventKey: '', // 按钮事件名称
              eventOption: {
                // 当 eventKey === 'showComponent'时,启用 comName,决定调用哪个组件
                comName: '', // 组件名称

                // 当 eventKey === 'useApi'
                apiOption: {
                  api: '', // 接口地址
                },

                // 当 eventKey === 'remove'时,可填
                params: {
                  // paramsKey 等于 参数的键值
                  // rowValueKey 等于 动态的参数值,格式为 schema::tableKey,到 table 行数据中找相应的字段的值
                  paramsKey: rowValueKey, // 【 例如 product_id: 'schema::product_id' 】
                },
              },
              ...elButtonConfig, // 标准 el-button 配置
            },
            // 表格多选功能配置
            showSelection: 'false' // 默认不显示多选列
            // Table所有原生属性(Element Plus TableProps类型)
            tableProps: {
              rowKey: 'id', // 表格的唯一标识字段。默认是id
              ......,
            },
            // 分页所有原生属性(Element Plus PaginationProps类型)
            paginationProps: {...}
            // ...
          ],
        },
        // search-bar 相关配置
        searchConfig: {},
        // 动态组件 相关配置
        componentConfig: {
          // create-form 表单相关配置
          createForm: {
            title: '', // 表单标题
            saveBtnText: '', // 保存按钮文案
            type: '', // 弹窗样式,可选值:'drawer'、'dialog',默认:'dialog'
            dialogWidth: '800px', // 弹窗宽度,默认:'500px'
            formLabelWidth: '70px', // 表单项标签宽度,默认:'70px'
          },
          // edit-form 表单相关配置
          editForm: {
            mainKey: '', // 表单主键,用于唯一标识要修改的数据对象
            title: '', // 表单标题
            saveBtnText: '', // 保存按钮文案
            type: '', // 弹窗样式,可选值:'drawer'、'dialog',默认:'dialog'
            dialogWidth: '800px', // 弹窗宽度,默认:'500px'
            formLabelWidth: '70px', // 表单项标签宽度,默认:'70px'
          },
          // detail-panel 相关配置
          detailPanel: {
            mainKey: '', // 表单主键,用于唯一标识要修改的数据对象
            title: '', // 详情面板标题
            type: '', // 弹窗样式,可选值:'drawer'、'dialog',默认:'dialog'
            dialogWidth: '800px', // 弹窗宽度,默认:'500px'
          },
          // ...支持用户动态扩展
        },
      },
    },
  ],
}

node 服务端启动

启动服务端

引入 elpis,并启动。其中,startServer 可以传入配置项 options,它会挂载在 koa-app 上,通过app.options访问。除此之外,options 还会传递给客户端,因此,你可以传递服务端获取到的数据,以实现数据在服务端渲染时服务端和客户端之间的同步。

// 使用框架内置服务
const { serverStart } = require('@tushi11/elpis');

// 启动 elpis 服务
const app = serverStart({
  name: 'ElpisDemo',
  // 其他配置项
  icon: '/static/logo.png',
  homePage: '/view/project-list',
});

自定义(拓展)服务端

Elpis 支持基于 elpis-core 的自定义服务端开发,目录结构遵循约定:

└── app
    ├── router-schema  # 接口参数校验规则(JSON Schema)
    ├── router         # 路由定义
    ├── controller     # 接口逻辑
    ├── service        # 业务服务
    ├── extend         # 扩展能力(如日志、工具)
    └── config         # 环境配置(多环境支持)
  • router-schema 是用来定义接口入参出参的 json-schema。实现接口的入参出参校验能力,是 elpis 的中间件api-params-verify

    // app/router-schema/**.js (一定是放在一级目录下的,每份都是配置)
    module.exports = {
      '/api/proj/product/list': {
        get: {
          query: {
            type: 'object',
            properties: {
              page: {
                type: 'string',
              },
              size: {
                type: 'string',
              },
            },
            required: ['page', 'size'],
          },
        },
      },
    };
  • router 定义后端接口路由

    module.exports = (app, router) => {
      const { demo: demoController } = app.controller;
      router.get('/api/demo', demoController.get.bind(demoController));
    };
  • controller 定义接口处理器(面向业务 )

    • app 可以通过这样的方式去访问 ==> app.controller.customModule.customController
    module.exports = (app) => {
      const BaseController = require('@tushi11/elpis').Controller.Base(app);
      return class customController extends BaseController {
        async create(ctx) {
          this.success(ctx, { user_id: 11 });
        }
      };
    };
  • service 定义接口处理服务(增删查改数据库)

    module.exports = (app) => {
      return class UserService extends BaseService {
        async get(userId) {
          const result = await database('t_user').select('*').where({
            user_id: userId,
            status: app.status.NORMAL,
          });
          return result[0] ?? {};
        }
      };
    };
  • extend 定义其他扩展能力。

    module.exports = (app) => {
      return require('moment');
    };
  • config 定义项目的变量(app/config/config.xxxx.js)

    /*
     * 默认配置 config/config.default.js
     * 本地配置 config/config.local.js
     * 测试配置 config/config.beta.js
     * 生产配置 config/config.prod.js
     */
    // config.prod.js
    module.exports = {
      name: 'demo-prod',
    };

前端开发

构建与启动

// build.js
const { frontendBuild } = require('@tushi11/elpis');

// 编译构建前端工程 - 这里会根据环境变量自动选择启动开发环境还是打包生产环境
frontendBuild(process.env._ENV);

多页面拓展(自定义页面)

  • **约定:**在 app/pages/ 目录下创建多页面入口( 以entry.xxx.js命名)

    // app/pages/demo/entry.demo.js
    import elpisBoot from '@elpisBoot'; // 调用 elpisBoot 中的方法创建vue示例
    import DemoVue from './demo.vue'; // 自定义 vue 组件
    
    // 当自定义的 vue组件 使用了<router-view> 可传递页面路由
    const routes = [
      {
        path: '/view/auth/login',
        component: () => import('./complex-view/login/login.vue'),
      },
    ];
    
    /**
     * elpisBoot 是一个 Vue3 应用的通用启动器函数,用于Vue 实例初始化,实现独立的SPA应用。支持通过配置项实现不同页面的个性化需求。
     * vue 页面主入口,用于启动 vue
     * @params pageComponent vue 入口组件
     * @param {Object} options 配置项
     * @param {Array} options.routes 路由列表
     * @param {Array} options.libs 页面依赖的第三方包
     */
    elpisBoot(DemoVue, { routes }); // 创建vue示例
  • app/pages/ 定义 vue 页面

    // demo.vue
    <template>
      <div style="color: red;">
        demo
        <el-input v-model="value" />
      </div>
    	<router-view></router-view>
    </template>
    
    <script setup>
    import { ref, watch } from 'vue'
    const value = ref('');
    
    watch(value, (newvalue, oldvalue) => {
      console.log(oldvalue, newvalue);
    })
    </script>
    
    <style scoped lang="scss"></style>

dashboard 页面扩展

dashboard / custom-view 自定义页面扩展
  • app/pages/dashboard/xxx 下写页面

    // app/pages/dashboard/todo/todo.vue
    <template>
      <h1>待开发</h1>
    </template>
    
    <script setup></script>
    
    <style lang="scss" scoped></style>
    
    <script setup>
    import { ref, watch } from 'vue'
    const value = ref('');
    
    watch(value, (newvalue, oldvalue) => {
      console.log(oldvalue, newvalue);
    })
    </script>
    
    <style scoped lang="scss"></style>
dashboard 路由配置
  • app/pages/dashboard/router.js中进行配置
module.exports = ({ routes, siderRoutes }) => {
  // 头部路由
  routes.push({
    path: '/view/dashboard/todo',
    component: () => import('./todo/todo.vue'),
  });

  // 侧边路由
  siderRoutes.push({
    path: 'todo',
    component: () => import('./todo/todo.vue'),
  });
};

组件拓展

扩展位置约定

| 扩展控制 | 目录位置 | 配置文件 | | :----------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------ | | dashboard / schema-view / components | app/pages/dashboard/complex-view/schema-view/components | app/pages/dashboard/complex-view/schema-view/components/components-config.js | | schema-form | app/pages/widgets/schema-form/complex-view | app/pages/widgets/schema-form/form-item-config.js | | schema-search-bar | app/pages/widgets/schema-search-bar/complex-view | app/pages/widgets/schema-search-bar/search-item-config.js | | header-container | app/pages/widgets/header-container/complex-view | app/pages/widgets/header-container/header-config.js | | | | |

// components-config.js 示例:
import createForm from './create-form/create-form.vue';
const ComponentConfig = {
    createForm
};
export default ComponentConfig;

// form-item-config.js 示例:
import textarea from './complex-view/textarea/textarea.vue';
const FormItemConfig = {
  textarea,
};
export default FormItemConfig;
  • schemaView 页面的实现是项目的核心,是在菜单 menu 中配置一份基于 json-schema 规范的 schema 配置,结合各个解析器,实现页面渲染

配置文件拓展

  • app/pages/configs/configs.js进行前端内容配置

    module.exports = {
      // 主题 / 布局设置
      themeSetting: {
        menuMode: 'horizontal', // 菜单类型,可选值:'horizontal'、'vertical',默认:'horizontal'
        dialogMode: 'dialog', // 弹窗样式,可选值:'drawer'、'dialog',默认:'dialog'
        useI18n: false, // 是否使用国际化
        /**1. useI18n 为true 时,全局翻译翻译: <div>{{ t('user.name') }}</div>
         *2. 带 t:: 前缀,强制翻译(即使全局 useI18n 为 false):<div>{{ t('t::user.name') }}</div>
         */
    
        // 主题设置组件的默认配置
        language: 'zh-cn',
        showCrumb: true,
        showProject: true,
        showLogo: true,
        isUniqueOpened: false,
        sideWidth: 200,
        sideTheme: 'light',
        sideDarkColor: '#1d2124',
        openMultipleTabs: true,
        theme: '#4A5DFF',
        successTheme: '#67c23a',
        warningTheme: '#e6a23c',
        dangerTheme: '#f56c6c',
        errorTheme: '#f56c6c',
        infoTheme: '#909399', //信息主题色
      },
    
      sysSetting: {
        terminal: 1,
        title: '后台管理系统',
        version: '1.0.0', // 携带项目版本号(便于后端兼容处理)
      },
    
      // 请求配置
      requestSetting: {
        // 只有一个代理则使用proxy:
        timeout: 10 * 1000, // 请求超时时长
        // baseURL: 'https://java-admin.likeadmin.cn',
        // proxyIndex: 0, // 默认不配置。配置后,根据下标获取proxyOption配置
        // 反向代理配置 (匹配的 match 如: '/public2', '/public' 要注意顺序)
        proxyOption: [
          {
            host: 'https://java-admin.likeadmin.cn',
            match: '/adminapi',
          },
          // {
          //   host: 'http://localhost:3001',
          //   match: '/public2',
          //   map: (path) => path.replace('/public2', ''),
          // },
          // {
          //   host: 'http://localhost:3000', // 目标服务器地址
          //   match: '/public', // match: /^\/public/, // 匹配需要代理的请求路径
          //   map: (path) => path.replace('/public', ''), // 重写真实请求地址。路径映射,去除 /api 前缀
          //   // jar: true, // 启用 cookie 支持
          // },
        ],
      },
    };

开发规范(约定优于配置)

组件引入与使用

  • 在 JS 中,用 大写开头的驼峰

    import HeaderContainer from '$elpisWidgets/header-container/header-container.vue';
  • 在 template 模板中,用【小写 + '-'】连接(传参数,命名都用这个规则)

    <header-container :title="'项目列表'"></header-container>

组件传参

  1. 组件传参用【'-'】,不用驼峰。

    <sub-menu :menu-item="item"></sub-menu>
  2. 组件接收参数可以用驼峰

    const { menuItem } = defineProps(['menuItem']);

方法命名规范

  • onXxx:用户点击的事件方法(如:onMenuSelect

    • 比如做埋点的时候,不是用户点击而是逻辑中调用的,那么记录就有问题了
  • handleXxx:逻辑中调用方法(如:handleMenuSelect

后端定义路由

  • 渲染页面的用 /view/ 开头: router.get('/view/:page', viewController.renderPage.bind(viewController));
  • 接口用 /api/ 开头:router.post('/api/auth/login', authController.login.bind(authController));
    • 如果携带 proj_key 的业务 api 要用/api/proj/开头: router.get('/api/proj/user', userController.get.bind(userController));

前端构建部分的目录规范如下:

  • 自定义扩展页需在app/pages/目录下创建页面入口文件;
  • 其他组件相关的扩展开发完成后,只需在对应目录的配置文件中添加组件配置,即可被 elpis 前端构建流程一并处理;
  • 模板配置则统一放置于model/目录下。

pages 的目录结构

  • pages 里所有 entry 开头的 js 文件都是多页面。

  • 多页面进去以后每一个页面渲染后都是用 vue 启动的 vue 实例,所以进来以后又是一个 spa 的单页面应用。

    • 比如进入到 dashboard 页面,又因为 dashboard 是用 boot 方法来启动的(用了 vue3 的 createApp 构建出来的),所以它又是一个单页面应用
  • 子模块/子组件,统一放到 complex-view 下面

    • 子模块的内容与该页面是强相关,所以放在同一个页面下。全局使用的组件放在 widgets 下。
    |--pages
    	|--dashboard
    		|--complex-view
    			|--header-view // 子模块父文件夹
    				|--asserts // 里面放只应用在该子模块的资源
    					|--xxx.png
    				|--header-view.vue // 必须用一个父文件夹包裹。因为把资源单独放在了通用的资源文件夹里,容易在删除整个模块时漏删了。
    		|--dashboard.vue
    		|--entry.dashboard.js

model 模型配置的目录结构

// modelList => projectList => menuList
|--app
|--model
	|-- xxx(自定义的模型名称,如buiness/people)
		|-- model.js (基类。需要放在自定义的model模型目录下)
		|-- project
			|-- xxx.js (子类。如jd.js/pdd.js。项目文件必须放在project目录下)

提交规范

<type>(<scope>): <subject>
  1. feat:新功能(Feature)的添加。
  2. fix:Bug 修复
  3. docs: 文档 (documentation)的修改
  4. style:不影响代码逻辑的样式(如空格、格式、标点等)修改。
  5. refactor:代码重构,既不添加新功能也不修复 Bug。
  6. perf:性能优化。
  7. test:添加测试用例或修改现有测试。
  8. build:与构建系统或外部依赖项相关的更改。
  9. ci:持续集成(Continuous Integration)配置或脚本的更改。
  10. chore:其他不归属上述类型的杂项事务,例如更新构建工具的版本。

文章参考:

elpis - 前端全栈框架(befool)

@yd779821/elpis

Elpis - 基于 Koa + Vue3 的企业级全栈应用框架(allen) @allen-zx/elpis

全栈领域模型框架 elpis(fivaclo) @fivaclo/elpis

@xinight/elpis

@tangfsin/elpis