关于全栈工程师工具 EggBorn.js

摘自http://cnodejs.org/topic/59eebce1f8d374775c0157d7

EggBorn.js是什么

EggBorn.js是一款顶级Javascript全栈开发框架。

EggBorn.js是采用Javascript进行全栈开发的最佳实践。 EggBorn.js不重复造轮子,而是采用业界最新的开源技术,进行全栈开发的最佳组合。 EggBorn.js前端采用Vue.js + Framework7 / Vue Router + Webpack,后端采用Koa.js + Egg.js,数据库采用mysql。 EggBorn.js时刻跟踪开源技术的最新成果,并持续优化,使整个框架时刻保持最佳状态。

EggBorn.js重点解决什么问题:业务模块化

Javascript技术的蓬勃发展,为前后端开发带来了更顺畅的体验,显著提升了开发效率。但仍有网友质疑Javascript能否胜任大型Web应用的开发。大型Web应用的特点是随着业务的增长,需要开发大量的页面组件。面对这种场景,一般有两种解决方案:

1 采用单页面的构建方式,缺点是产生的部署包很大。 2 采用页面异步加载方式,缺点是页面过于零散,需要频繁与后端交互。

EggBorn.js实现了第三种解决方案:

3 页面组件按业务需求归类,进行模块化,并且实现了模块的异步加载机制,从而弥合了前两种解决方案的缺点,完美满足大型Web应用业务持续增长的需求。

EggBorn.js的技术特点

  • 业务模块化:页面组件按模块组织
  • 加载方式灵活:模块既可异步加载,也可同步加载
  • 模块高度内聚:模块包括前端页面组件和后端业务逻辑
  • 参数配置灵活:模块中的前后端可以单独进行参数配置
  • 国际化:模块中的前后端均支持独立的国际化
  • 模块隔离:模块的页面、数据、逻辑、路由、配置等元素均进行了命名空间隔离处理,避免模块之间的变量污染与冲突
  • 超级易用的事务处理:只需在路由记录上配置一个参数,即可完美实现数据库的事务处理。
  • 渐进式开发:由于模块的高度内聚,可以将业务以模块的形式沉淀,在多个项目中重复使用,既可贡献到npm开源社区,也可部署到公司内部私有npm仓库。

有了EggBorn.js,从此可复用的不仅仅是组件,还有业务模块。

快速上手

安装EggBorn.js脚手架
$ npm install -g egg-born
新建项目
$ egg-born project_name
$ cd project_name
$ npm install

EggBorn.js目前提供了2个项目脚手架,分别是

  • front-backend-mysql – 前后端全栈项目模板
  • front – 前端项目模板,后端可采用其他方案
配置mysql连接参数

如果采用了front-backend-mysql模板,请配置mysql连接参数(空数据库即可)

编辑src/backend/config/config.default.js文件

  // mysql
  config.mysql = {
    clients: {
      // donot change the name
      __ebdb: {
        host: ‘127.0.0.1‘,
        port: ‘3306‘,
        user: ‘travis‘,
        password: ‘‘,
        database: ‘egg-born‘,
      },
    },
  };
运行项目

启动后端服务

$ npm run dev:backend

启动前端服务

$ npm run dev:front

EggBorn.js架构图

系统架构

项目文件结构

模块文件结构

模块开发

命名约定

为了不断沉淀业务模块,达到高度可复用的效果,所有模块的命名空间必须充分隔离,避免相互污染与冲突,故采用如下命名方式:

egg-born-module-{providerId}-{moduleName}

如模块egg-born-module-a-version,各环节命名信息如下:

  • providerId: a
  • moduleName: version
  • fullName: egg-born-module-a-version
  • relativeName: a-version
  • 前端页面路由地址: /a/version/{page}
  • 后端API路由地址:/a/version/{controller}/{action}
加载机制

模块既支持异步加载,也支持同步加载。默认是异步加载,如果要同步加载,只需在模块名称后面加上-sync后缀,如模块egg-born-module-aa-login-sync

新建模块

进入src/module目录执行脚手架,创建模块文件骨架

$ egg-born module_relative_name

EggBorn.js目前提供了2个模块脚手架,分别是

  • module – 全栈模块模板
  • module-front – 前端模块模板
模块前端开发
前端页面路由

front/src/routes.js中添加页面路由,如

function load(name) {
  return require(`./pages/${name}.vue`).default;
}

export default [
  { path: ‘welcome/:who‘, component: load(‘welcome‘) },
  { path: ‘profile‘, component: load(‘profile‘), meta: { requiresAuth: true } },
  { path: ‘/login‘, component: load(‘login‘) },
];
  • path: 路径,支持参数。以/开头,代表根页面组件。login页面组件通常这样配置
  • component: 页面组件对象
  • meta: 路由元数据
  • meta.requiresAuth: 如果页面组件需要登录,须设为true

在页面中引用页面组件,请使用绝对路径,如

<f7-list-item link="/aa/hello/welcome/You" title="Welcome"></f7-list-item>
<f7-list-item link="/aa/hello/profile" title="Profile"></f7-list-item>
前端状态管理

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。EggBorn.js采用Vuex实现了完全隔离的模块状态管理机制。在front/src/store.js中添加状态,如

export default function(Vue) {

  return {
    state: {
      message: ‘hello world‘,
    },
  };

}

在页面组件中访问本模块状态

const message = this.$local.state.message;

在页面组件中访问其他模块状态

const message = this.$store.state[providerId][moduleName].message;

更多信息,请参阅: Vuex

前端参数配置

front/src/config/config.js中添加配置信息,如

export default {
  mode: 1,
};

只支持在页面组件中访问本模块内部的参数配置

const mode = this.$config.mode;
前端国际化

front/src/config/locale目录添加国际化文件 zh-cn.js文件中的语言定义示例如下

export default {
  mode: ‘模式‘,
  "Hello world! I‘m %s.": ‘您好,世界!我是%s。‘,
};

国际化语言采取全局合并的方式,有利于语言资源的共享,在页面组件中访问方式如下

const mode = this.$text(‘mode‘);
const message = this.$text("Hello world! I‘m %s.",‘zhennann‘);
模块后端开发
后端api路由

backend/src/routes.js中添加api路由,如

const home = require(‘./controller/home.js‘);

module.exports = [
  { method: ‘get‘, path: ‘home/index‘, controller: home, action: ‘index‘, transaction: true },
];
  • method: get/post等方法
  • path: 路径,支持参数
  • component: Controller对象
  • action: Controller方法,如果不设置,则自动采用path尾部单词
  • transaction: 默认为false,如果设为true,则启用数据库事务

在前端页面组件中访问本模块api路由

this.$api.get(‘home/index‘).then(data => {
}).catch(err => {
});

在前端页面组件中访问其他模块api路由

this.$api.get(‘/providerId/moduleName/home/index‘).then(data => {
}).catch(err => {
});
后端Controller

后端Controller的实现方式与Egg.js保持一致

module.exports = app => {
  class HomeController extends app.Controller {

    async index() {
      const message = await this.service.home.index();
      this.ctx.success(message);
    }

  }
  return HomeController;
};

更多信息,请参阅: Egg.js Controller

后端Service

Service用于封装业务逻辑,供Controller调用,实现方式与Egg.js保持一致。

module.exports = app => {
  class Home extends app.Service {

    async index() {
      const res = await this.ctx.db.queryOne(‘show tables‘);
      return res;
    }

  }

  return Home;
};

与Egg.js不同之处在于,Service使用ctx.db操作数据库,从而自动支持数据库事务。

更多信息,请参阅: Egg.js Service

后端Controller调用

为了支持大型Web系统的开发,EggBorn.js支持模块后端Controller之间的调用,如

const message = await this.ctx.performAction({
  method: ‘get‘,
  url: ‘home/index‘,
  query: {
    username: ‘kevin‘,
  },
  params: {
    mode: 1,
  },
  body: {
    content: ‘ready‘,
  },
});
  • method: get/post等方法
  • url: 访问本模块的Controller使用相对路径,访问其他模块的Controller使用以/开头的绝对路径。
  • queryparamsbody: 与常规的Controller参数保持一致
后端数据库操作

后端数据库操作与Egg.js保持一致

更多信息,请参阅: Egg.js MySQL

后端数据库事务

EggBorn.js提供了更为便利的数据库事务实现方式,只需在后端api路由记录中配置transaction参数,Service使用ctx.db操作数据库。如果是主Controller通过ctx.performAction调用子Controller,数据库事务开启规则如下:

主Controller配置
子Controller配置
子Controller实际启用

true
true
true

true
false
true

false
true
true

false
false
false

后端参数配置

backend/src/config/config.js中添加配置信息,如

module.exports = appInfo => {
  const config = {};

  config.message = "Hello world! I‘m %s.";

  return config;
};

访问本模块内部的参数配置示例如下

const message = this.ctx.config.message;
后端国际化

backend/src/config/locale目录添加国际化文件 zh-cn.js文件中的语言定义示例如下

module.exports = {
  "Hello world! I‘m %s.": ‘您好,世界!我是%s。‘,
  ‘not found‘: ‘未发现‘,
};

国际化语言采取全局合并的方式,有利于语言资源的共享,访问方式如下

const notFound = this.ctx.text(‘not found‘);
const message = this.ctx.text("Hello world! I‘m %s.", ‘zhennann‘);
后端错误处理

backend/src/config/errors.js文件中添加错误代码

// error code should start from 1001
module.exports = {
  1001: ‘not found‘,
};

返回错误信息示例如下

this.ctx.fail(1001);

也可抛出异常示例如下

this.ctx.throw(1001);

模块管理

模块依赖

EggBorn.js通过package.json文件管理模块依赖关系。比如,模块aa-module1依赖aa-module2,需要在模块aa-module1的package.json文件中作如下配置

{
  "name": "egg-born-module-aa-module1",
  "version": "0.0.1",
  "eggBornModule": {
    "dependencies": {
      "aa-module2": "0.0.1"
    }
  },
  "dependencies": {
    "egg-born-module-aa-module2": "^0.0.1"
  }
}

设置"egg-born-module-aa-module2": "^0.0.1",是为了在安装模块aa-module1时自动安装模块aa-module2。如果模块没有公开发布,就不必设置。

模块数据版本

模块一般都要操作数据库,当模板版本升级时,数据库结构也有可能变动。EggBorn.js实现了模块数据版本的管理,便于业务模块的积累沉淀。

在模块的package.json文件中配置fileVersion为当前数据版本

{
  "name": "egg-born-module-aa-module1",
  "version": "0.0.1",
  "eggBornModule": {
    "fileVersion": 1
  }
}

在模块后端添加Api路由

{ method: ‘post‘, path: ‘version/update‘, controller: version }

添加version Controller

module.exports = app => {
  class VersionController extends app.Controller {

    async update() {
      await this.service.version.update(this.ctx.getInt(‘version‘));
      this.ctx.success();
    }

  }
  return VersionController;
};

添加version Service

module.exports = app => {

  class Version extends app.Service {

    async update(version) {
      if (version === 1) {
        // do something
      }
    }

  }

  return Version;
};

当启动后端服务时,EggBorn.js自动检测模块数据版本的变化,并执行相应的路由,完成数据的版本升级。

模块发布

当项目中的模块代码稳定后,可以将模块公开发布,贡献到开源社区。也可以在公司内部建立npm私有仓库,然后把模块发布到私有仓库,形成公司资产,便于重复使用。模块发布步骤如下

$ cd path/to/module      -- 进入模块目录
$ npm install            -- 安装模块依赖
$ npm run build:front    -- 构建前端代码
$ npm run build:backend  -- 构建后端代码
$ npm publish            -- 发布至npm仓库

测试驱动

目前只支持后端测试驱动

后端Controller测试

backend/test/controller目录添加Controller测试文件

// controller/home.test.js
const { app, mock, assert } = require(‘egg-mock/bootstrap‘);
const parseMockUrl = function(url) {
  const prefix = app.mockUtil.parseUrlFromPackage(__dirname);
  return `${prefix}${url}`;
};

describe(‘test/controller/home.test.js‘, () => {

  it(‘action:index‘, async () => {
    const result = await app.httpRequest().get(parseMockUrl(‘home/index‘));
    assert(result.body.code === 0);
  });

});
后端Service测试

backend/test/service目录添加Service测试文件

// service/home.test.js
const { app, mock, assert } = require(‘egg-mock/bootstrap‘);
const parseMockUrl = function() {
  return app.mockUtil.parseUrlFromPackage(__dirname);
};

describe(‘test/service/home.test.js‘, () => {

  it(‘index‘, async () => {
    const ctx = app.mockContext({ mockUrl: parseMockUrl() });
    const message = await ctx.service.home.index();
    assert(message);
  });

});
执行测试

在项目根目录执行测试

$ npm run test:backend
$ npm run cov:backend

前端架构配置

前端启动文件

前端架构提供两种方案

  1. Vue.js + Framework7
  2. Vue.js + Vue Router

Framework7是移动开发专属UI界面库,内置路由机制。 Vue Router是Vue.js官方路由库,使用Vue Router可搭配其他各种UI界面库。

src/front/main.js文件中进行切换

// choose one

//   framework7
import main from ‘./framework7/main.js‘;

//   vuerouter
// import main from ‘./vuerouter/main.js‘;

// export
export default main;
前端参数配置

src/front/config/config.js文件中的参数配置可以覆盖模块的参数

export default{
  module: {
    ‘aa-hello‘: {
      mode: 2,
    },
  },
};
前端国际化

src/front/config/locale目录添加国际化文件,可以覆盖模块的国际化语言 zh-cn.js文件中的语言定义示例如下

export default {
  mode: ‘模式‘,
};

后端架构配置

后端架构

后端架构基于Egg.js,完整支持Egg.js提供的所有功能与特性

更多信息,请参阅: Egg.js

后端参数配置

src/backend/config/config.default.js文件中的参数配置可以覆盖模块的参数

module.exports = appInfo => {
  const config = {};

  // module config
  config.module = {
    ‘aa-hello‘: {
      mode: 2,
    },
  };

  return config;
};
后端国际化

src/backend/config/locale目录添加国际化文件,可以覆盖模块的国际化语言 zh-cn.js文件中的语言定义示例如下

module.exports = {
  mode: ‘模式‘,
};

项目部署

构建前端代码
$ npm run build:front
启动后端服务
$ npm run start:backend
停止后端服务
$ npm run stop:backend
后端服务启动参数配置

编辑build/config.js文件

// backend
const backend = {
  port: 7002,
  hostname: ‘127.0.0.1‘,
};
nginx配置

强烈建议使用nginx托管前端静态资源,并反向代理后端服务,配置如下

server {
  listen 80;
  server_name example.com www.example.com;
  set $node_port 7002;

  root /path/to/www;

  location  /api/ {
    proxy_http_version 1.1;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://127.0.0.1:$node_port$request_uri;
    proxy_redirect off;
  }

}

GitHub贡献

有任何疑问,欢迎提交 issue, 或者直接修改提交 PR

时间: 2024-10-29 12:32:59

关于全栈工程师工具 EggBorn.js的相关文章

1001种玩法 | 有了这些工具,你离全栈工程师又近了一步

2016中国软件开发白皮书中提到,市场上对技术开发人才的技能需求已经不单单只再是某个领域的初级开发者,那些精通前后端的全栈工程师逐渐被市场亲睐.目前web开发群体5成以上为全栈开发者.预示着随着市场需求的不断变化,市场对开发者逐渐有了更高要求,精通前后端的全栈工程师将成为IT界新一代宠儿.新智云www.enncloud.cn 近几年来经常听到有人提全栈工程师,甚至还有一些公司直接挂出名为"全栈工程师"的招聘职位,开出的薪资更是水涨船高.那么你想要进化成这样的一个斜杠青年需要哪些辅助工具

“全栈”工程师 请不要随意去做

今天我来给大家说说 "全栈工程师" 的事儿. 写这篇文的背景原因: 很简单就是最近越来越多的人想做[全栈工程师],他们的目标就是全栈,他们才入行短短1-2年,甚至刚从培训班出来:我的目标是做全栈,我啥都要学会,啥都会写,这样我就是大牛了,可以挣大钱,就算创业,我也不用招那么多人,一个人搞定一个产品,融资上市 ,CEO白富美,balabala... 我给他的回复是: 去你xx的,你连JS 数组和对象用法都搞不清,抄几个效果,看几个视频教程摸索摸索就要做万能人了? "全栈&quo

《web全栈工程师的自我修养》阅读笔记

在买之前以为这本书是教你怎么去做一个web全栈工程师,以及介绍需要掌握的哪些技术的书,然而看的过程中才发现,是一本方法论的书.读起来的感觉有点像红衣教主的<我的互联网方法论>,以一些自己的经历和感悟来阐述web全栈工程师需要具备哪些素质,而不仅仅是需要哪些技术.这算是我买的书中看的最快的一本书. 在阅读这本书之前,我对全栈工程师的理解还停留在node阶段,随着node在服务端的风生水起,有一段时间会认为使用nodejs作为服务端开发,前后端统一使用js开发,便是所谓的全栈开发,比较流行的技术栈

技术栈选择与全栈工程师

很多朋友的第一门语言是一个强类型语言.可能是C/C++/Java/C#. 做到一定年份了,积累了丰富的经验,发现自己好像大多数东西能做,客户端.服务端.手机.游戏,很多场景自己都可以进行开发. 在各种场景下都能开发. 在各种场景下都遇到有力的竞争对手. 竞争对手貌似不少人比自己开发效率高. 类似这样的技术人员,我们可以称之为C蛮. ---------------- C蛮和队长的故事 -------------- C蛮浑身肌肉,手持精金巨斧. 无论看到什么怪物,嗷呜一声吼.狂暴+吹大+高等魔化武器

读&lt;专栏&#183;谈谈全栈工程师&gt;

原文地址:http://leihuang.org/2014/12/12/read-Full-Stack-Developer/ 昨天晚上看海贼王给看睡着了(11点的左右),导致早上5点就醒了,怎么办呢,找点东西打发点时间,本来想看看知乎的,但是最近对知乎的氛围很失望,总感觉好浮躁的氛围,当然这些跟我关注的人有关系,改天清理清理. 犹豫了半天,想着还是看本薄点的书吧,下了个豆瓣阅读软件,因为以前没用过,本来想找书,结果点进了豆瓣专栏,还以为里面是书.进去之后才发现是别人写的专栏.也没想太多,看到有科

《web全栈工程师的自我修养》 读书笔记

作者:余果. 人民邮电出版社.2015年9月第1版. 值得轻快一读,另外此书里推荐的书籍很好.Full-Stack Engineer! 一.如何成为全栈工程师 1 定义:全栈工程师是指,一个能处理数据库.服务器.系统工程和客户端的所有工作的工程师.根据项目不同,可能分为移动栈.web栈,或原生应用程序栈. 2 研发流水线 产品经理 >交互设计>>视觉设计>>前端开发/后台开发>>测试>>发布 3 代表性的全栈框架 LAMP.MEAN 4 建议:先精后广

通往全栈工程师的捷径 —— React

下图是 React 在国内的百度搜索指数,是拿 React 和 Nodejs 做了个对比,可以看出 React 的关注度也已经逼近 nodejs. 虽然在关注总量上 React 还远不及 jQuery 和 Angular 等等,但它的增长幅度超乎你想象,你知道这意味着什么吗?这意味着关注 React,你就比大多数人走在了业界的前沿! 一.什么是react 引用官网的简介,react就是”一个用来构建用户界面的 javascript 库”. React 起源于 Facebook 的内部项目,因为

全栈工程师的能力点

全栈工程师是对于除了bat的主站以外的大多数项目,这样的能力也许不是一个方面的专家,但是能再一定时间快速解决一个问题.可能做服务器的发展成全站更容易一些,但是一切能力都是可以通过练习实践去做的很好的, 全栈应该有一下几方面:运维,服务端开发,架构,大数据,搜索,前端,移动端(android,ios) 下面开始我们的全栈之路 运维: 这个能力涉的方面有, 域名(dns),cdn, 机器(linux)数据监测配置,负载,容器调整配置,jvm(这里拿java做说明)数据监测调整:数据库配置.集群,负载

努力成长为一只全栈工程师

完全转到互联网行业来之后,就一直在读书,内容都是计算机领域的,除了读书还看视频,是关于计算机基础理论课的,应用方面的就不看视频了,太贫太慢,不如文档来得快.看书也尽量挑进阶一点的,比如书名包含“性能”.“进阶”.“设计模式”.“算法”,其实这些对一个互联网领域的熟练工来说,应该也是标配了.看这些书的目的就是为了让自己更专业,能够解决更多的问题,写代码写得更明白. 换到新公司这几个月以来,除了觉得自己要恶补知识之外,有两点让自己非常庆幸,一是原来在大公司的经历让自己已经足够职业了,清楚地知道工作对