Egg TypeScript 项目 Egg 和 React 前端代码需要按照 TypeScript 方式编写代码,同时构建部分需要同时结合 TypeScript 和 Webpack 构建进行相关配置。TypeScript 项目与 JavaScript 项目具体实现方面主要有以下区别:

  • TypeScript 项目 js 文件改成 ts 文件, jsx 文件改成 tsx 文件
  • Egg 和 React 代码采用 TypeScript 方式编写,同时加上TypeScript 类型声明
  • 需要配置 Egg 和 React 代码 TypeScript 编译 tsconfig.json 配置文件
  • Webpack 构建开启 TypeScript React 构建,也就是开发 ts-loader

    TypeScript 配置

  • ${root}/app/web/tsconfig.json 前端 React TypeScript 配置

  • ${root/tsconfig.json 前端 Egg TypeScript 配置
  • 通过 egg-ts-helper 自动生成 Egg 代码类型声明
  1. // package.json
  2. "scripts": {
  3. "dev": "egg-bin dev -r egg-ts-helper/register",
  4. "tsc": "ets && tsc -p tsconfig.json"
  5. }
  • Webpack 开启 TypeScript React 编译支持
  1. 'use strict';
  2. module.exports = {
  3. ......
  4. module: {
  5. rules: [
  6. {
  7. ts: true
  8. }
  9. ],
  10. }
  11. };

编写代码

Egg TypeScript 代码

Egg Controller

  1. // ${root}/app/controller/index.ts
  2. import { Controller, Context } from 'egg';
  3. export default class AntDController extends Controller {
  4. public async index(ctx: Context) {
  5. await ctx.render('antd.js', {
  6. title: '--Ant Design Tab--',
  7. keywords: 'react, server side render, ant design',
  8. message: { text: 'Ant Design Tab Theme and Code Spliting' }
  9. });
  10. }
  11. }

Egg Extend

  1. // ${root}/app/extend/application.ts
  2. import { Application } from 'egg';
  3. import DB from '../lib/db/base';
  4. import DBFactory from '../lib/db/factory';
  5. const DBSymbol = Symbol('Application#db');
  6. export default {
  7. get db(this: Application): DB {
  8. if (!this[DBSymbol]) {
  9. this[DBSymbol] = DBFactory();
  10. }
  11. return this[DBSymbol];
  12. }
  13. };
  14. // ${root}/app/extend/context.ts
  15. 'use strict';
  16. import { Context } from 'egg';
  17. import DB from '../lib/db/base';
  18. export default {
  19. get db(this: Context): DB {
  20. return this.app.db;
  21. }
  22. };

Egg Middleware

  1. // ${root}/app/middleware/locals.ts
  2. import { Context } from 'egg';
  3. export default function locals() : any {
  4. return async (ctx: Context, next: () => Promise<any>) => {
  5. ctx.locals.locale = ctx.query.locale || 'cn';
  6. ctx.locals.origin = ctx.request.origin;
  7. await next();
  8. };
  9. };

Egg Service

  1. // ${root}/app/service/article.ts
  2. import { Context, Service } from 'egg';
  3. import { deserialize } from '@hubcarl/json-typescript-mapper';
  4. import Colllection from '../lib/db/collection';
  5. import Article from '../model/article';
  6. import Condition from '../lib/condition';
  7. export default class ArticeService extends Service {
  8. private context: Context;
  9. private colllection: Colllection;
  10. constructor(ctx: Context) {
  11. super(ctx);
  12. this.context = ctx;
  13. this.colllection = new Colllection(ctx.db, 'article');
  14. }
  15. public async getArtilceList(condition: Condition) {
  16. if (condition.categoryId) {
  17. condition.where.categoryId = condition.categoryId;
  18. }
  19. if (condition.status) {
  20. condition.where.status = condition.status;
  21. }
  22. if (condition.title) {
  23. condition.like.title = condition.title;
  24. }
  25. return this.colllection.getPager(condition);
  26. }
  27. }

Egg Router

  1. // ${root}/app/router.ts
  2. import { Application } from 'egg';
  3. export default (app: Application) => {
  4. const { router, controller } = app;
  5. router.get('/', controller.index.index);
  6. };

Egg Config

  1. // ${root}/config/config.default.ts
  2. import * as path from 'path';
  3. import * as fs from 'fs';
  4. import { EggAppConfig } from 'egg';
  5. export default function(app: EggAppConfig) {
  6. const exports: any = {};
  7. exports.keys = '123456';
  8. exports.middleware = [
  9. 'locals'
  10. ];
  11. return exports;
  12. }
  13. // ${root}/config/plugin.local.ts
  14. export default {
  15. webpack: {
  16. package: 'egg-webpack'
  17. },
  18. webpackreact : {
  19. package: 'egg-webpack-react'
  20. }
  21. };

React TypeScript 代码

  • 类型声明
  1. // ${root}/app/web/typings/type.ts
  2. export interface TabProps {
  3. title: string;
  4. keywords: string;
  5. description: string;
  6. message: {
  7. text: string
  8. };
  9. }
  • React 代码
  1. // ${root}/app/web/page/antd/index.tsx
  2. import React, { Component, ReactElement } from 'react';
  3. import ReactDOM from 'react-dom';
  4. import { Provider } from 'mobx-react';
  5. import ConfigStore from './store/config';
  6. import Layout from '../../component/layout';
  7. import { Tab } from './component/tab';
  8. import { TabProps } from '../../typings/type';
  9. export class App extends Component<TabProps, any> {
  10. render() {
  11. const stores = {
  12. configStore: new ConfigStore()
  13. };
  14. return <Provider {...stores}><Layout {...this.props}><Tab {...this.props} /></Layout></Provider>;
  15. }
  16. }

骨架项目