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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@exoskeleton/astroboy

v0.1.1

Published

> powered by @exoskeleton/core and astroboy.

Downloads

15

Readme

@exoskeleton/astroboy

powered by @exoskeleton/core and astroboy.

@exoskeleton/astroboy 是基于 @exoskeleton/core 实现的一套 DI 风格的上层框架。

环境需求

  • typescript: ^3.2.0
  • node.js: ^8.0
  • astroboy: ^1.1.0-beta.6

推荐配置

  • typescript: ^3.4.5
  • node.js: ^8.0
  • astroboy: ^1.1.0-beta.6

改动记录

更多

开发(当前应用包)

  • 打包:make pkg
  • 发布 rc 版本:make rc
  • 发布稳定版本: make publish

安装

# 安装DI-core
yarn add @exoskeleton/astroboy
# 安装astroboy,或者其他基于astroboy的上层框架
yarn add astroboy@^1.1.0

使用

1.初始化应用结构

结构参考 astroboy 标准项目,这里提几个注意点:

  • 应用入口必须 ts 化:app.ts
  • 使用新的 cli 工具,支持一套配置文件来定制 cli 行为

exoskeleton.config.js

module.exports = {
  tsconfig: "tsconfig.json",
  // 编辑器调试支持
  inspect: false,
  // dev启动自动热编译,需要配合下面的编译选项使用
  compile: true,
  // 并行类型检查,默认开启
  typeCheck: false,
  // 环境变量
  env: { NODE_ENV: "qa" },
  watch: [
    path.join(__dirname, "app/**/*.*"),
    path.join(__dirname, "definitions/**/*.*"),
    path.join(__dirname, "middlewares/**/*.*")
    // more watch files
  ],
  ignore: [
    path.join(__dirname, "app/middlewares/*.*")
    // more ignore files
  ],
  // 自动编译routers,如不需要删除此设置
  routers: {
    enabled: true,
    // 暴力编译,强刷输出内容
    always: true,
    // 应用整体的url前缀
    approot: "/v1",
    // 输出文件类型,支持js
    filetype: "ts",
    // 显示编译细节
    details: true
  },
  // configs文件编译选项,如不需要删除此设置
  configCompiler: {
    enabled: true,
    // 暴力编译,强刷输出内容
    force: true,
    // 待编译文件夹相对路径
    configroot: "app/config",
    // 编译输出的相对路径
    outputroot: "config"
  },
  // middlewares文件编译选项,如不需要删除此设置
  middlewareCompiler: {
    enabled: true,
    // 暴力编译,强刷输出内容
    force: true,
    // 待编译文件夹相对路径
    root: "app/middlewares/pipes",
    // 编译输出的相对路径
    output: "app/middlewares"
  }
};

2.创建服务

栗子 🌰:

import { Injectable } from "@exoskeleton/core";
import { CallService, CoreContext } from "@exoskeleton/astroboy";

@Injectable()
export class DemoService {
  constructor(private ctx: CoreContext, private service: CallService) {}

  private x = 123456;

  public getXff() {
    return this.ctx.firstXff;
  }

  public createSession() {
    return this.service.dubboCall(
      "com.youzan.uic.session.api.service.UicSessionService",
      "createSessionId",
      []
    );
  }
}

3.创建控制器

栗子 🌰:

import {
  Controller,
  Render,
  JsonResult,
  RenderResult
} from "@exoskeleton/core";
import {
  CoreContext,
  SkynetLoggerContextPlugin,
  YouzanFrameworkGlobal,
  Index,
  GET,
  Params,
  Query
} from "@exoskeleton/astroboy";
import { DemoService } from "../services/DemoServuce";
import { DPConfigReader } from "../config/config.default";
import { ReactS01 } from "../services/RS";

@Controller("demo")
class DemoController {
  constructor(
    // configs支持注入能力,后面会讲
    private reader: DPConfigReader,
    // 注入整个ctx
    private ctx: CoreContext,
    // Render 统一渲染服务
    private render: Render,
    // Global _global能力
    private global: YouzanFrameworkGlobal,
    private dmsrv: DemoService,
    private ds: ReactS01
  ) {}

  @Index(["", "*"])
  public async pageIndex() {
    this.render.setView({
      fuckData: this.dmsrv.getXff()
    });
    this.global.setGlobal("woshinidie", 666666);
    return new RenderResult("demo/index.njk");
    // this.ctx.setState({
    //   fuckData: this.dmsrv.getXff()
    // });
    // this.ctx.setGlobal("woshinidie", 666666);
    // await this.ctx.render("demo/index.njk");
  }

  @GET("tryget/:name")
  public async getMethod(
    @Params("name") name: string,
    @Query("id", true) id: number
  ) {
    // const result = await this.dmsrv.createSession();
    console.log(this.ds.show());
    this.ds.change();
    return new JsonResult({
      name: typeof name,
      id: typeof id,
      fxx: this.ctx.firstXff,
      fxx03: this.dmsrv.getXff(),
      configs: {
        views: this.reader.global.view,
        apollo: this.reader.read("apollo")
      },
      super: {
        a: this.ctx.header,
        v: this.ctx.app,
        x: this.ctx.querystring,
        b: this.ctx.getQueryData(),
        f: this.ctx.firstXff,
        g: this.ctx.getRequestData()
      }
    });
  }
}

export = DemoController;

4.创建 configs(使用 DI 能力)

如果要使用原始的 configs,不看这里就是了

如果想使用 DI 能力提供 configs 访问,同时兼顾类型感知,可以这样写

import { ConfigReader } from "@exoskeleton/core";
import { DIFrameworkConfigs } from "@exoskeleton/astroboy";

// 本业务的配置
interface IBaseConfigs {
  pstaionDemo: {
    a: number;
    b: boolean;
  };
}

// 组装类型,让基础配置结构可选
interface InnerConfigs extends IBaseConfigs, Partial<DIFrameworkConfigs> {}

// 公开完整的configs结构,有利于后续框架使用
export interface IDemoBaseConfigs extends IBaseConfigs, DIFrameworkConfigs {}

// 公开configs服务,提供DI能力和类型感知(需要在app.ts手动注入)
export class DPConfigReader extends ConfigReader<IDemoBaseConfigs> {}

// 实现configs
export default function DefaultConfigs(): InnerConfigs {
  return {
    pstaionDemo: {
      a: 24521454,
      b: false
    },
    // 在当前项目里面覆盖默认配置
    CDN_CSS: "test"
  };
}

通过编译后的代码:

// [@exoskeleton/core] 自动生成的代码
const tslib_1 = require("tslib");
const astroboy_ts_1 = require("@exoskeleton/core");
const di_framework_1 = require("@exoskeleton/astroboy");
class DPConfigReader extends astroboy_ts_1.ConfigReader {}
module.exports = (function DefaultConfigs() {
  return {
    pstaionDemo: {
      a: 24521454,
      b: false
    }
  };
})();

5.创建中间件(使用 DI 能力)

如果要使用原始的 middlewares

如果想把 DI 能力注入 middlewares,同时兼顾类型感知,可以这样写

import { CoreContext } from "@exoskeleton/astroboy";

export default async function DemoFn(context: CoreContext) {
  console.log(context.ip);
  await this.next();
}

通过编译后的代码:

// [@exoskeleton/core] 自动生成的代码
import { injectScope, IMiddlewaresScope } from "@exoskeleton/core";
import di_framework_1 = require("@exoskeleton/astroboy");
async function DemoFn(context) {
  console.log(context.ip);
  await this.next();
}
export = (options: any = {}, app: any) =>
  injectScope(async ({ injector, next }: IMiddlewaresScope) => {
    const _p0 = injector.get(di_framework_1.CoreContext);
    await DemoFn.call({ next, options, app }, _p0);
  });

没有 DI 的 middlewares 但也要进行编译的,可以这样写:

import { serverInit } from "@exoskeleton/core";

export default function DI_INIT({ ctx, next }) {
  return serverInit(ctx, next);
}

通过编译后的代码:

// [@exoskeleton/core] 自动生成的代码
import astroboy_ts_1 = require("@exoskeleton/core");
function DI_INIT({ ctx, next }) {
  return astroboy_ts_1.serverInit(ctx, next);
}
export = (options: any = {}, app: any) => async (ctx: any, next: any) => {
  return await DI_INIT(<any>{ ctx, options, app, next });
};

6.bootstrap 启动

app.ts

import path from "path";
import { PowerServer } from "@exoskeleton/astroboy";
import {
  RENDER_RESULT_OPTIONS,
  SIMPLE_LOGGER_OPTIONS
} from "@exoskeleton/core";
import { DPConfigReader } from "./config/config.default";

const configs = {
  ROOT_PATH: path.resolve(__dirname, "..")
};

// PowerServer.Create(WscPcBase, configs)
PowerServer.Create(configs)
  .option(SIMPLE_LOGGER_OPTIONS, {
    level:
      process.env.NODE_ENV === "development" || process.env.NODE_ENV === "qa"
        ? 2
        : 3
  })
  .scoped(DPConfigReader)
  .run({
    onStart: () => {
      console.log("\nDI DEMO started!");
      console.log("\nhello world!");
      console.log("\n苟利国家生死以,岂因祸福避趋之?\n👓\n🐸\n👔\n👖\n👞");
    }
  });

hrllo world!