Giter VIP home page Giter VIP logo

midwayjs / midway Goto Github PK

View Code? Open in Web Editor NEW
7.2K 104.0 559.0 1.22 GB

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

Home Page: https://www.midwayjs.org/

License: MIT License

TypeScript 61.20% JavaScript 3.00% Shell 35.61% CSS 0.17% HTML 0.03%
enterprise framework web typescript ioc dependency-injection-container midway serverless serverless-framework aws

midway's Introduction

Midway Logo

Midway - 一个面向未来的云端一体 Node.js 框架

GitHub license GitHub tag Build Status Test Coverage lerna PRs Welcome Gitpod Ready-to-Code Code Style: MidwayJS Leaderboard

English | 简体中文

资源

特性

  • 🐘 全功能:支持 Web 应用/Serverless/FaaS/微服务/小程序后端等多种场景,基于装饰器和依赖注入开发企业级应用
  • 🐦 前端集成:全新的云端一体应用研发体验,零 API 调用,使用 "React Hooks " 风格一体研发
  • 🐴 跨平台:支持部署至普通 Server 或 Serverless/FaaS 环境
  • 🐶 扩展:组件化扩展能力,另外支持使用 Koa/Express/Egg.js 生态插件
  • 🐂 示例: 官方提供多种场景的示例代码,方便开发者快速上手
  • 🛡 TypeScript 全面支持

描述

Midway 是一个适用于构建 Serverless 服务,传统应用、微服务,小程序后端的 Node.js 框架。

Midway 可以使用 Koa,Express 或 Egg.js 作为基础 Web 框架。它还提供了独立使用的基本解决方案,例如 Socket.io,GRPC,Dubbo.js 和 RabbitMQ 等。

此外,Midway 也适用于前端/全栈开发人员的 Node.js 无服务器框架。构建下一个十年的应用程序。可在 AWS,阿里云,腾讯云和传统 VM /容器上运行。与 React 和 Vue 轻松集成。 🌈

Demo

使用装饰器开发 Web 应用

import { Controller, Get, Provide } from '@midwayjs/decorator';

@Provide()
@Controller('/')
export class HomeController {

  @Get('/')
  async home() {
    return `Welcome to midwayjs!`;
  }
}

使用函数开发全栈应用

后端代码 src/apis/lambda/index.ts

import {
  Api,
  Get,
  Query,
  useContext,
} from '@midwayjs/hooks';

export default Api(
  Get(),
  Query<{
    page: string;
    limit: string;
  }>(),
  async () => {
    const ctx = useContext();
    return {
      page: ctx.query.page,
      limit: ctx.query.limit,
    };
  }
);

前端调用 src/page/index.tsx

import getArticles from './api';
const response = await getArticles({
  query: { page: '0', limit: '10' },
});
console.log(response); // { page: '0', limit: '10' }

手动调用

fetch('/api/articles?page=0&limit=10')
  .then((res) => res.json())
  .then((res) => console.log(res)); // { page: '0', limit: '10' }

快速上手

$ npm -v

## 选择模版
$ npm init midway

## 进入项目路径
cd my_midway_app && npm run dev

文档和社区

社区优秀示例展示

1、Cool-Admin - 一个很酷的后台权限管理框架

image

VSC Plugin

答疑

群里会有热心的朋友,也会有新版本发布推送。

贡献

请告知我们可以为你做些什么,不过在此之前,请检查一下是否有 已经存在的Bug或者意见

如果你是一个代码贡献者,请参考代码贡献规范。

谁在使用

image 你也想加 Logo ?可以点击 这里 添加。

License

我们的代码使用 MIT 协议,请放心使用。

FOSSA Status

midway's People

Contributors

chenzhaozheng avatar cyjake avatar czy88840616 avatar danielsss avatar ddzyan avatar dependabot[bot] avatar depfu[bot] avatar developeryvan avatar echosoar avatar ghostoy avatar guangwong avatar ilyydy avatar jiumengs avatar kurten avatar legendecas avatar lellansin avatar lxxyx avatar mariodu avatar nawbc avatar odex21 avatar renovate[bot] avatar stone-jin avatar tw93 avatar waitingsong avatar wakegiser avatar wang-ran avatar yemangran avatar yuu2lee4 avatar yviscool avatar zqun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

midway's Issues

关于 example 的想法

未来 example 会越来越多,每个example为了可维护性和稳定性有一些要求:

  • 保证在最新版本的midway下可用
  • 需要有测试
  • 整体需要有回归机制,比如每次发布版本时候自动运行所有 example 的测试

Plans about english website and documents?

Thanks for nice project. Is there any plans about provide english website and documents? It'll be better for non-Chinese developers. (And maybe somebody can translate it to another language too. 😄)

egg-graphql的connector无法从ctx上取到service

export default class CarConnector {
    ctx;
    mysql;
    redis;
    service;
    constructor(ctx) {
      this.ctx = ctx;
      this.mysql = ctx.app.mysql.get('g7tv');
      this.redis = ctx.app.redis;
      this.service = ctx.service.carDayCount;
    }

    fail(message: string | Error): Error  {
        if (typeof message === 'string') {
            return new Error(message);
        }
        return message;
    }
    getStatisticsInfo(args) {
        return this.service.getStatisticsInfo(args);
    }
    getCarStatusCount() {
        return this.service.getCarStatusCount();
    }
    async getCarCount({ ymd }) {
        const userinfo = await this.ctx.g7User();
        return this.service.findOne({
            ymd,
            orgroot: userinfo.orgroot,
        });
    }
}

这是egg里的写法 能从ctx上取到service。。。但midway这里就取不到。。

统一 tslint

  • @然云 提供了 tslint 基础包
  • 基础包发布
  • 内部 midway 框架使用
  • midway 框架及相关模块使用
  • midway 相关 demo 使用
  • 脚手架统一修改
  • 文档记录

ManagedResolverFactory中create递归调用

@provide()
class TestA{
@inject()
testB: TestB;
}


@provide()
class TestB {
@inject()
testA: TestA;
}
  • 以上场景出现递归调用,max call 栈溢出
  • 默认单实例,需要create中判断单实例往上挪至设置属性之前即可

[RFC] Customize decorator support

Background

Currently we have customize decorator requirement related with #85.

As framework provider we can't control how users using decorator with our framework. In fact, developers can freely define their decorator function anywhere with native support by TypeScript.

But, there is a problem while users directly using the native decorators, that the native decorators function is more like for the project itself, and it could be inconvenient for reusing in other project. The key problem is that the decorators is not compatible with the midway & egg's plugin mechanism.

when you want to encapsulate a decorator function to a plugin for others to reuse. it seems like, we should define it like this:

// plugin/app.ts
module.exports = (app) => {
   app.enumerableDecorator = function () {
     // ...
   }
}

it seems like the decorators function could be mix up with other plugin object. And the after the definition, we could find it's difficult to use it:

// project/app.ts
module.exports = (app) => {
  class Sth {
    @app.enumerableDecorator(false)
    foo() { ... }
  }
}

In this case, to be more graceful to use decorator functions, we'd like to import it from the framework's uniform export.

Aims

There is inconvenience, so there is requirement. We want to change this situation, by:

  • Provide uniform decorator register function, so that users wouldn't define it anywhere, and avoid the conflict between user-defined and framework-defined decorators.
  • Make decorators compatible with plugin mechanism, so that users can encapsulate their decorator in plugin which can be simply install by NPM.
  • Supply the consistent usage for developers to retrieve and use decorators.

Solution

For all the aims, we need a decorator manager to achieve.

The manager is defined in the package/context, and initialized in midway-core, while we should refactor the old implements like midway-hsf or midway-schedule, to keep the on-premise core decorators clear and simple.

And the decorator manager is preset up on the app object, so that users can register decorators by app.decorator.register in plugins. This could effect some logic in the web-loader.

// register

module.exports = (app) => {
  app.registerDecorator('myCount', () => {
    // ...
  })
}

Last, we supply a definition in midway which refer the singleton manager object, so that users can retrieve an use the decorators like:

import { DecoratorManager } from 'midway'

const { myCount } = DecoratorManager;

class UserController {
  @myCount()
  @get('/')
  index() {
  	//...
  }
}

config/logger 实例的定义

用户提出缺少这个定义,在使用时不是很方便。同时也要考虑下插件以及整个 midway 体系的定义机制。

初学者想问一下我这样做对吗

不会排版只能这样贴代码了 不知道这样做对吗,我用eggjs的方式配置 egg-mongoose插件 然后下面这样定义模型
控制器里面直接 这样用

import { provide, plugin, scope, ScopeEnum } from 'midway'
@scope(ScopeEnum.Singleton)
@provide('UserModel')
export class UserModel {
  constructor(@plugin('mongoose') mongoose) {
    const Schema = mongoose.Schema
    const UserSchema = new Schema({
      username: {
        type: String
      },
      password: {
        type: String
      }
    })
    return mongoose.model('User', UserSchema, 'user')
  }
}

run 目录的问题

  • 1、看起来需要有个命令去清理它,或者每次开发时清理上一次
  • 2、看起来需要一份 pluginContext 的key,方便用户可以 @plugin() 插件
  • 3、run/router 中没有路由装饰器的信息

是否考虑向 typeorm 捐赠?

typeorm 说它是node.js 里最好的orm 也不为过。
https://github.com/typeorm/typeorm

可惜 typeorm 太缺钱了,以至于 至今未能发布 1.0 ,甚至 0.3.x 没正式版。
官方现在发布issues 筹集资金。

typeorm 是个伟大的项目,是否可以考虑一起向 typeorm 捐赠??

连接池的基础类

在使用 knex,mysql,sequelize 等三方类的定义中,需要获取一个connection,但是在 midway 的体系中,默认的 ioc 是请求作用域,这就导致如果用户在连接池实例的配置上不做处理的话,每个请求都会创建一个连接导致出问题。

建议在 DAO 层产出一个基础单例类,用于使用

pm2/Pandora 启动后访问报错

PM2

按照文档,在项目目录下新增server.js

require('midway/server');

然后运行pm2

pm2 start server.js

程序可以正常跑起来,但是访问路径后报错

Please set config.keys first

检查dist目录发现没有生成代码。

Pandora

使用默认procfile.js文件

'use strict';
module.exports = pandora => {
  pandora
    .fork('backend', require.resolve('midway/server'));
};

pandora全局安装,并运行

pandora start

错误情况与PM2相同
** 如果是dev运行则正常 **

内部初始化脚本误用的解决方案

由于外部社区版本和内部版本脚手架不同,并且在内部无法启动外部的脚手架(包名冲突),有不少同学安装了外部的 midway-init,导致启动失败,已出现多例。

需要做一些提醒。

reload worker 问题

lib目录/service/文件更改之后无法监听到文件变化
src/interface.ts 文件更改也不会监听到文件变化

  • Node Version:
  • Egg Version:
  • Plugin Name:
  • Plugin Version:
  • Platform:
  • Mini Showcase Repository:

梳理 NODE_ENV between midway-bin and egg-bin

  • Node Version:
  • Egg Version:
  • Plugin Name:
  • Plugin Version:
  • Platform:
  • Mini Showcase Repository:

image
(example from midway-schedule)

Strange behavior while NODE_ENV is different while do test among test/fixtures/${projects} in TypeScript mode.

本地走 start_build 的时候依旧依赖了 ts-node

exports.registerTypescriptEnvironment = options => {
  let tsFlag = options.typescript;
  // 只有是 ts 应用,并且在本地环境才判断是否加载 ts-node
  /* istanbul ignore if*/
  if (tsFlag && !exports.isTypeScriptEnvironment() && exports.isDev()) {
    try {
      require('ts-node/register');
    } catch (e) {
      throw new Error('Need ts-node(https://github.com/TypeStrong/ts-node) be installed!');
    }
  }
};

走 start_build 的时候这个逻辑依旧为 true,也就是说本地没法用 dist 来测试

featrue request: throw error while directly call decorators

import { provide, controller } from '@ali/midway';

provide()               // @provide() 
controller('/test')     // @controller('/test') 
export default class TestController {
  // ...
}

To avoid the mistake while developer forget to use '@' to call decorators.

v1.0 的发布

计划在 12 月中旬发布 1.0,尽快进入 1.0 的版本迭代,这样在开发过程中的版本升级会变的比较容易。

TODO

  • 和 egg 一样的文档部分需要补充
  • 现有的 MR 和 issue 能清理的尽量清理掉
  • 发布稿 (ATA, 知乎,掘金等)

injection 的子类获取 metadata 错误

@provide('32')
class Parent {
  @inject()
  parentTest;
}


class Child extends Parent {

  @inject()
  childTest;
}

const meta1 = Reflect.getMetadata(TAGGED_CLS, Child);
console.log(meta1);  // 这个时候不应该取到值


const meta1 = Reflect.getMetadata(TAGGED_PROP, Child);
console.log(meta1);  // 这个时候取不到值

前端框架集成目录约定

最近有在做类似 antd 的集成 #92 ,思考一些目录结构上的问题,像 antd 这样的框架,目前也有 ts 的版本,如果集成的话,可能会在环境上和后端产生冲突。

这是 antd-ts 产生的目录结构。
image

以及这是 egg 和 antd design 集成的例子。https://github.com/eggjs/egg-ant-design-pro

@midwayjs/midwaycollaborators 可以一起看看

如何写多个配置文件

看文档是支持多环境配置文件的。我添加了一个单元测试配置文件,按egg的命名
config.unittest.ts

export = (appInfo: any) => {
  const config: any = exports = {};

  config.sequelize = {
    host: 'localhost',
    port: '3306',
    user: 'root',
    password: '123456',
    database: 'test_unittest',
    dialect: 'mysql',
  };
  return config;
};

但是没有用,还是使用的default的配置,是不是我写法有问题?

默认egg插件配置不对需要覆盖的问题

原因

有些插件默认使用了 baseDir 去找 package.json ,由于 midway的 appDir === baseDir ,可能存在部分隐患。

虽然可以用配置覆盖的方式去处理,比如内部我们大部分插件都会用到,就放在了默认的配置中,但是在社区版本的插件还是属于使用自由的,这个时候就会产生问题。

  • 1、假如有插件在配置中依赖了别的模块,如果覆盖的话,势必也会引入这个依赖,导致框架的复杂度上升。
  • 2、如果大部分用户没有这个插件依赖,也会被默认模块依赖进去,会造成资源浪费。

IoC class 绑定容器 @inject 调用不到

场景1:写在同一个文件 controller/home.ts
问题:通过this.getload.get() 取不到上文中绑定到容器的GetLoad
报错:Error: GetLoad is not valid in current context

// controller/home.ts
import { controller, Container, async, init, scope, get, post, provide, priority, inject } from 'midway';

@provide('GetLoad')
class GetLoad {
 
  async get() {
    return 'ok'
  }
}

@async()
@provide()
@priority(-1)
@controller('/')
export class HomeController {

  @inject()
  ctx;

  @inject('GetLoad')
  getload;

  public async index(ctx?) {
      const getload = await this.getload.get();
      console.log(getload)
  }

}

场景2:
问题:运行getload.get() 时,取不到bull.ts文件绑定的Bull方法,在Get等浏览器请求方法内有效(程序内调用报错)
报错:Error: Bull is not valid in current context

// controller/home.ts

import { controller, Container, async, init, scope, get, post, provide, priority, inject } from 'midway';

@provide('GetLoad')
class GetLoad {

  @inject()
  ctx;

  @inject('Bull')
  bull;
 
  async get() {
    
      const bull = this.bull;
      console.log(bull);

  }
}

const getload = new GetLoad();

getload.get();
// lib/bull.ts

import { provide, inject } from 'midway';

@provide('Bull')
export class Bull {

    @inject()
    ctx;    

    public async load() {
        console.log('----ctx---->', this.ctx)
    }
}
  • Node Version: 10.13.0
  • Egg Version: 2.13.0
  • Midway Version: 0.4.5

bug: providerWrapper oops

  • Node Version: v8.11.4
  • Midway Version: midway-core: v0.3.5
  • Platform: Mac
  • Mini Showcase Repository:
2018-09-26 17:47:07,183 ERROR 56714 [-/182841/::1/21765af0-c171-11e8-9b86-756c6b91c033/61ms GET /buildtask] nodejs.Error: _schema is not valid in current context
    at MidwayContainer.get (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@injection/src/factory/applicationContext.ts:180:13)
    at MidwayContainer.get (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@injection/src/factory/container.ts:159:18)
    at MidwayRequestContainer.get (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@midway-core/src/requestContainer.ts:56:26)
    at Function.get [as _schema] (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@injection/src/factory/common/Autowire.ts:87:28)
    at /Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@lodash/lodash.js:4911:32
    at baseForOwn (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@lodash/lodash.js:2996:24)
    at Function.forOwn (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@lodash/lodash.js:13015:24)
    at Function.patchDollar (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@injection/src/factory/common/Autowire.ts:112:7)
    at ManagedResolverFactory.afterEachCreated (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@midway-core/src/container.ts:308:18)
    at ManagedResolverFactory.createAsync (/Users/lellansin/workspace/shop-air-w/node_modules/[email protected]@injection/src/factory/common/ManagedResolverFactory.ts:446:15)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

扩展context的疑问

参考了examples里的extend-koa项目,context扩展就是export了一个对象,如果我在扩展中需要使用到ctx的相关数据时怎么操作呢?

默认脚手架未生成 public 文件

默认脚手架未生成 public 文件,导致 init 后运行 start_build 失败,因为缺少 public 文件,建议运行时提前检查下或者在模板里增加。

重名的类在 ioc 中的处理方案讨论

有几种处理:

1、默认能重名,重名即覆盖,增加警告输出?(container 默认行为)
2、不能重名,报错 (injection 默认行为)
3、midway 中增加配置,默认不能重名

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.