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 🙏

© 2026 – Pkg Stats / Ryan Hefner

ecodecc

v1.0.0

Published

## 简介

Readme

开始

简介

Ecode 是一个代码生成器,用于生成业务代码,让用户只专注于业务逻辑本身,而不用理会关于依赖引用和一些细枝末节的语法处理,最终得到一个完整且干净的应用。

Ecode主要利用TS面向对象的语法特性作为编译器前端,在此基础上,你可以使用for循环、模块导入导出等手段实现代码的复用。

该方案等侵入型非常低,它的最小编译单位是组件,因此可以在不改变项目架构的情况下使用。

目前Ecode仅支持Angular工程代码的生成。

快速上手

安装

npm i -g ecodecc
# or
yarn add ecodecc --global
# or
pnpm add -g ecodecc

配置文件

配置文件目前仅支持默认读取,无法指定,因此命名必须为ecode.config.js。编译运行会以配置文件为参照路径,因此需要在配置文件中指定入口和出口(日后支持更多配置),目前配置文件支持的选项不多,仅支持入口和出口:

// ecode.config.js

module.exports = {
  entry: './views',
  output: './src/app/pages',
};

入口一般指一个文件夹,这个文件夹中的所有文件,最终都会按照一定的依赖规则,编译至output所指定的文件夹中。

书写第一个模块

// views/first.ts
import { Module, Component } from 'ecode/dist/render'

export default new Module({
  id: 'hello',
	children: [
    new Component({
      id: 'member',
      children: []
    })
  ]
})

编译

编译命令是 ecode go [path], path是可选参数,指向 ecode.config.js ,默认指向命令行的执行目录。

import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'

import { FirstRoutingModule } from './first-routing.module'
import { MemberComponent } from './member.component'

@NgModule({
  imports: [FirstRoutingModule, CommonModule],
  declarations: [MemberComponent],
  exports: [],
  providers: []
})
export class FirstModule {}

封装一个简单的组件

这是一个真实的、用于业务上的组件类,它仅仅是对于antd的分割线组件进行简单的二次封装,根据antd的官方文档可知,要使用divider组件,必须引用NzDividerModule,并注册到我们工程的相关module中。

分割线的使用很直观,也不存在嵌套的关系,因此,children只需要传一个空数组即可。在Render函数中也仅仅需要返回几个最简单的属性,其中imports属性会用于构建依赖关系。

import { Render } from 'ecode/dist/render';

export class Line extends Render {
  constructor() {
    super({ children: [] });
  }
  render() {
    return {
      type: 'element',
      imports: [
        {
          target: [{ name: 'NzDividerModule', type: 'module' }],
          from: 'ng-zorro-antd/divider',
        },
      ],
      template: `<nz-divider></nz-divider>`,
      data: [],
      methods: [],
    };
  }
}

生成后的文件

生成的文件中包含Angular模块最基础的几个部分(上述例子中未必会完整体现)包含:

  1. 引用;如NgModule、CommonModule等Angular Module必须依赖的模块。
  2. 注册;该模块下辖的Component、Service等部件,并合理地注册。

使用

一个完整组件创建和使用的过程如下:

  • 新建文件,引入Render基类。
  • 封装出一个元素类。
  • 在类的constructor函数中接收你希望传入的几类API,有几个API是约定俗成的,如id、children等。将这些必要的数据传入super函数中,其他API可以由用户自定义其行为,例如放置在模板中或将其渲染成数据。

基础概念

为了增强业务表达能力,需要介绍一下几个基本概念。

组件的实例化

组件需要实例化后才能够使用,每个组件都是一个类,每个类会带有自己的方法,这些方法主要是为了针对性地减少信息量。

在封装一个类时,需要让它继承Render类,Render类中已经包含了几种常见的基本逻辑,例如自动维护事件和回调函数之间的联系。

在使用业务中使用这个组件时,尽可能通过实例方法或静态方法来使用。

为什么除了实例方法外还需要静态方法?

因为在实际业务中,有可能会出现组件逻辑相互引用的场景,如果组件未能合理地初始化,使用指令时会报错,因此为了让前端语法得以运行,有需要的话,需要有静态方法作为弥补。

指令

指令是操作组件的方式,一般建议设计得比较贴合人类的直观感受:

  • 如我们通过指令唤起一个弹框:Modal.wakeUp()

  • 如我们通过指令清空一个表单:Form.reset()

  • 如我们通过指令发起一个请求:httpS.send('foo')

指令中会包含完整的逻辑,如非空判断、错误判断等。

Callback数据结构

Callback数据结构专注于描述业务逻辑;

在形式上,它是一个数组,一般而言是一维的,根据需要也可以是多维的;

Callback中的每一个元素,要么是指令(这些指令在编译时会运行并返回字符串),要么是字符串,当然,字符串一般仅用于弥补指令能力的不足,不是推荐的做法。

由于指令生成的代码会可能有重复的部分,因而在部分场景下,可能需要将其封闭在一个作用域内,这时可以使用中括号[]将一部分逻辑约束在一个block内。

引入

ecode既包含一个编译器,也包含多个导出的API。这些API的使用方式是基本是一致的,都是通过实例化后传入父元素的children字段中,只是每个元素由于复杂度和职能不同,在实例化时传入的参数不一致,幸好TS能够给予比较详细的类型提示,因此不需要死记硬背。

ecode仅提供了几个重要且基本的类,内部封装了自身所需要的逻辑关系,但仅仅是这样还不足以应付业务,因此在业务中需要基于Render类自行封装。接下来一一介绍:

Module类

建议作为最小生成单位来编译,即在一个文件中导出一个Module实例。

在实例化时,它需要设置两个属性

  • id
  • children;它直属的children成员类型需要是Module或Component

Component 类

尽管建议将Module作为最小的编译单位,但Component也可以作为最小的编译单位,即一个文件中导出一个Component实例,之所以不推荐是因为如此一来,就需要用户手动处理与Component相关的依赖关系了。举个例子:一个UI组件foo需要依赖一个fooModule的模块,用户需要手动将fooModule注册到父Module文件中,生成后的组件才能够正常地使用。

在实例化时,它需要设置多个属性:

  • id
  • imports
  • children
  • init

Render 类

我们一般不会直接使用render类,但会使用继承Render类来使用,当然,需要保持必要的一致性:

首先,由于它继承自Render类,因而它需要有一个constructor函数并包含一个super方法,向super传入正确的属性。

其次,需要包含一个render方法,该方法返回一个对象,包含以下几个属性:

  • type;用于声明当前的组件类型
  • imports;是个对象数组,含有target、from
  • template; 用于
  • data;
  • methods;

导出

嵌套

几个简单的例子

Canvas

Line

Button

自定义组件

Service

# import 

@Component({
  selector: '# name',
  template: `# template`
})
export class #nameComponent {
  # data
  # create
  constructor(# inject) {
    # data
    # create
  }
  ngOnInit() {
    # init
  }
  #methods
}