Giter Site home page Giter Site logo

nger's Introduction

Vue logo

用ng自由组合开发小程序

项目名称意义,用ng的人!I am a nger!

Warning! Warning! Warning! 这不仅仅是一个前端项目。

vue、react相继都有了小程序的开发框架,作为一个nger,也该为社区做点事情了! 很遗憾,由于ng和小程序的差异性,我们暂时没打算直接把ng项目转换成小程序,而是用ng的一套**(依赖注入装饰器等)来规范开发小程序!以达到一套代码多平台运行。

技术栈说明:Typeorm/Nestjs/Angular/Ngrx/JSX/Injector(依赖注入)/Decorator(装饰器)/Webpack/Less/Sass/Gulp...

系统架构

面向终端用户对开发者友好的框架

Vue logo

用装饰器实现应用跨平台,如Controller装饰器,在前端就是发送http请求,在后端就是响应http请求 主要目标nger-compiler根据平台需求,选择性的去除或修改代码,nger-platform-*提供装饰器解析器。 将ng中的ngIf、ngFor通过编译器,拓展到其他运行环境,如小程序等。

依赖环境

  1. 安装nodejs
  2. 安装docker
  3. 安装docker-compose
  4. npm install
  5. docker-compose up -d
  6. npm start

目录规范

开发文档

  • 核心概念
    • TypeContext 每个用装饰器装饰过得类都会有一个TypeContext,主要作用是查询装饰器参数。
    • NgModuleRef @NgModule装饰器装饰的类的运行时实例,每个NgModule在系统运行时创建
    • ComponentRef @Component装饰的类实例,需要NgModuleRef创建。
    • PipeRef @Pipe装饰的类实例,需要NgModuleRef创建。
    • DirectiveRef @Directive装饰的类实例,需要NgModuleRef创建。
    • PageRef @Page装饰的类实例,需要NgModuleRef创建。
    • ControllerRef @Controller装饰的类实例,需要NgModuleRef创建。
  • 内置周期钩子
    • APP_INITIALIZER 系统初始化时运行,依赖注入还没有注册完毕,可在此时动态插入或替换某注入服务。并自动执行NgModule类中的构建方法。Platform需要注入此类型钩子,才能正常运行。
    • APP_ALLREADY APP_INITIALIZER所有钩子执行完毕后执行。这时依赖注入已准备完毕,所有服务可通过injector的方式获取。这个周期内,不要修改依赖注入服务。

核心**

ng的依赖注入

开发进度

命令行工具

  • yarn cli build构建打包
    • 手机h5 yarn cli build h5
    • pc网站 yarn cli build pc
    • 微信公众号 yarn cli build wechat
    • 微信小程序 yarn cli build weapp
    • 支付宝小程序 yarn cli build alipay
    • 百度智能小程序 yarn cli build swap
    • 字节跳动小程序 yarn cli build tt
    • ios客户端 yarn cli build ios
    • android客户端 yarn cli build android
  • 初始化 yarn cli init demo
  • yarn cli init初始化
  • yarn cli test单元测试
  • yarn cli start启动服务
  • yarn cli publish发布到当前src模块应用商城

核心库

  • angular装饰器
  • typeorm装饰器
    • entity
      • ChildEntity
      • Entity
      • TableInheritance
    • columns
      • Column
      • CreateDateColumn
      • ObjectIdColumn
      • PrimaryColumn
      • PrimaryGeneratedColumn
      • UpdateDateColumn
      • VersionColumn
    • listeners
      • AfterInsert
      • AfterLoad
      • AfterRemove
      • AfterUpdate
      • BeforeInsert
      • BeforeRemove
      • BeforeUpdate
      • EventSubscriber
    • relations
      • JoinColumn
      • JoinTable
      • ManyToMany
      • ManyToOne
      • OneToMany
      • OneToOne
      • RelationCount
      • RelationId
    • transaction
      • Transaction
      • TransactionManager
      • TransactionRepository
    • tree
      • Tree
      • TreeChildren
      • TreeLevelColumn
      • TreeParent
    • other
      • Check
      • EntityRepository
      • Exclusion
      • Generated
      • Unique
  • nest装饰器
    • Get (可选)发送get请求
    • Post (可选)发送post请求
    • Controller (可选)Api层,用于后端
  • 其他装饰器
    • Page 页面
    • Command (可选)命令行
    • Option (可选)命令参数
    • It (可选)单元测试
  • 生命周期
    • OnInit
    • DoCheck
    • OnDestroy
    • AfterContentInit
    • AfterContentChecked
    • AfterViewInit
    • AfterViewChecked

生态

模块及文档连接 作用
nger-module-gulp gulp打包相关

任务安排

开发重点 nger-compiler 到 nger-di 目标src目录中的文件,编译到各个平台,并运行。

  • 扫描项目目录,并记录每个文件导出的有装饰器装饰的类及名称。
  • 根据运行目标,去掉没有用的或者可以去掉的一些内容,例如@It,@Command,@Option
  • @Component装饰的类生成对应的Component(ComponentInstance)
  • @Page装饰的类生成对应的Page(PageInstance)
  • 搜集配置信息生成json文件
  • 编译html生成wxml文件
  • 编译scss/less/styl生成wxss文件
  • 编译生成js文件

TODO

小程序适配思路

其实小程序和ng的适配度还蛮高的!

  • @Component正好和Component对应。不唯一,可以有任意个实例
  • App和NgModule对应。全局唯一
  • @Directive和小程序的指令对应,这里有区别ng中可以自定义指令,小程序不行。不唯一。
  • @Page和小程序的Page对应。全局唯一

Controller

客户端运行时需要编译器转码

import { Controller, Get, Post } from 'nger-core'
@Controller({
    path: '/'
})
export class IndexController {
    info: any = {
        username: 'nger',
        age: 28
    }
    @Get()
    userInfo() {
        return this.info;
    }
    @Post()
    setUserInfo(username: string, age: number) {
        this.info = {
            username,
            age
        }
    }
}
// to
import { Get, Post, Controller } from 'nger-core'
@Controller({
    path: '/'
})
export class NgerUserController {
    @Get()
    userInfo: () => Promise<any>;
    @Post()
    setUserInfo: (username: string, age: number) => Promise<any>;
}

@Page

// TODO

@Page({
    path: `pages/index/index`,
    template: `<view></view>`
})
export class ImsPage{}

// pages/index/index.js

// pages/index/index.json

// pages/index/index.wxss

// pages/index/index.wxml

@Component

// **/ims-demo.ts
import {Component,Input,EventEmitter} from 'nger-core';

@Component({
    selector: 'ims-demo',
    template: `<view (onTap)="click"></view>`
})
export class ImsDemo {
    @Input()
    title: string;

    @Output()
    bindmyevent: EventEmitter;

    click(e){
        this.bindmyevent.emit(e);
    }
}

// to
// **/ims-demo.js
const instance = new ImsDemo();
Component({
    behaviors: [],
    data: {
        instance: instance
    },
    properties: {
        // Input
        title: instance.title
    },
    lifetimes: {
        created(){
            instance.ngOnInit()
        },
        attached() { 
            instance.onViewInit()
        },
        ready(){
            instance.onAfterViewInit()
        },
        moved() { 
            instance.onMoved()
        },
        detached() { 
            instance.onDestory()
        },
        error() { 
            instance.onError()
        },
    },
    pageLifetimes: {
        show(){
            instance.onShow()
        },
        hide(){
            instance.onHide()
        },
        resize(){
            instance.onResize()
        }
    },
    methods: {
        click: instance.click
    }
})
// **/ims-demo.json
{}
// **/ims-demo.wxss

// **/ims-demo.wxml
<view onTap="click"></view>

ngIf

<ng-template [ngIf]="condiction"></ng-template>
<!-- to -->
<ng-template wx:if="{{condiction}}"></ng-template>
<ng-template [ngIf]="condiction" [ngIfELse]="elseBlock">condiction</ng-template>
<ng-template #elseBlock>elseBlock</ng-template>
<!-- to -->
<ng-template wx:if="{{condiction}}"></ng-template>
<ng-template wx:else>elseBlock</ng-template>
<ng-template [ngIf]="condiction" [ngIfThen]="thenBlcok" [ngIfELse]="elseBlock"></ng-template>
<ng-template #thenBlcok>thenBlcok</ng-template>
<ng-template #elseBlock>elseBlock</ng-template>
<!-- to -->
<ng-template wx:if="{{condiction}}">thenBlcok</ng-template>
<ng-template wx:else>elseBlock</ng-template>

ngFor

<ng-template ngFor let-item="it" let-i="index" [ngForOf]="items"></ng-template>
<!-- to -->
<ng-template wx:for="items" wx:for-item="it" wx:for-index="i"></ng-template>

多平台SDK统一接口

用于启动测试

用于启动cli

express环境

express环境

typeorm环境

小程序运行

依赖注入实现

带色打印工具

  • Logger 接口
  • ConsoleLogger Loggerconsole实现

资助

Vue logo

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.