SAP CAP篇十三:拥抱TypeScript

本文目录

  • 本系列文章
  • 从新开始
    • 为啥要用TypeScript
    • 官方文档
    • 程序框架
      • 从`package.json`开始
      • `tsconfig.json`
      • Jest的配置 `jest.config.js`
      • 服务的实现
      • 自动化测试
        • `setup.ts`
        • 文件夹`integration`
  • 执行及测试
  • 对应代码及branch

本系列文章

SAP CAP篇一: 快速创建一个Service,基于Java的实现
SAP CAP篇二:为Service加上数据库支持
SAP CAP篇三:定义Model
SAP CAP篇四:为CAP添加Fiori Elements程序(1)
SAP CAP篇五:为CAP添加Fiori Elements程序(2)
SAP CAP篇六:为CAP添加Fiori Elements程序(3)
SAP CAP篇七:为CAP添加Fiori Launchpad入口 (Sandbox环境)
SAP CAP篇八:为CAP添加App Router并支持Fiori Launchpad (Sandbox环境)
SAP CAP篇九:升级为SAP CDS 7.0, CAP Java 2以及Spring Boot 3
SAP CAP篇十:理解Fiori UI的Annoation定义
SAP CAP篇十一:支持Media Object:图片、附件等
SAP CAP篇十二:AppRouter 深入研究

从新开始

虽然本篇是整个CAP系列的第十三篇,但是,本篇不基于任何之前的文章或代码基础,这是一个全新的分支。

为啥要用TypeScript

对于TypeScript的重要性,其实无需赘述。这是因为JavaScript是一门解释性语言,导致了在大型项目中,在调用模块之间的类型安全变成了一个黑洞。而TypeScript作为JavaScript的超集,从本源上解决了这个问题。
当然,天下没有免费的午餐,当TypeScript带来了Type的同时,也不可避免地带来了复杂性和额外的编译开支。

官方文档

当然,官方文档还是值得看看的,虽然一如既往的发散性思维。
链接:Help Doc

程序框架

从一个空的文件夹开始这个新项目。

package.json开始

创建package.json,如下:

{
    "name": "@alvachien/sapcap-fiorielements-tsapp",
    "version": "1.0.0",
    "scripts": {
        "test": "npx jest --silent",
        "start": "cds serve srv/world.cds",
        "start:ts": "cds-ts serve srv/world.cds"
    },
    "dependencies": {
        "@sap/cds": "^7.5.2"
    },
    "devDependencies": {
        "@cap-js/sqlite": "^1.4.0",
        "@types/jest": "^29.5.11",
        "@types/node": "^20.11.5",
        "axios": "^1.6.5",
        "jest": "^29.7.0",
        "ts-jest": "^29.1.2",
        "ts-node": "^10.9.2",
        "typescript": "^5.3.3"
    },
    "eslintConfig": {
        "extends": "eslint:recommended",
        "env": {
            "es2020": true,
            "node": true,
            "jest": true,
            "mocha": true
        },
        "globals": {
            "SELECT": true,
            "INSERT": true,
            "UPDATE": true,
            "DELETE": true,
            "CREATE": true,
            "DROP": true,
            "CDL": true,
            "CQL": true,
            "CXL": true,
            "cds": true
        },
        "rules": {
            "no-console": "off",
            "require-atomic-updates": "off"
        }
    }
}

tsconfig.json

作为TypeScript必备的配置文件:

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "outDir": "./gen/srv/srv",
        "rootDir": "./srv",
        "baseUrl": "./",
        "moduleResolution": "node",
        "skipLibCheck": true,
        "preserveConstEnums": true,
        "sourceMap": false,
        "allowJs": true,
        "strict": true,
        "strictNullChecks": false,
        "strictPropertyInitialization": false,
        "esModuleInterop": true
    },
    "include": [
        "./srv/**/*"
    ]
}

Jest的配置 jest.config.js

作为Jest的配置文件:

module.exports = {
  preset: "ts-jest",
  globalSetup: "./test/setup.ts"
};

服务的实现

创建一个srv文件夹,分别创建两个文件world.cdsworld.ts

world.cds如下:

service say @(path: '/say') {
  function hello (to:String) returns String;
}

word.ts则提供了实现逻辑:

import type { Request } from "@sap/cds/apis/services"

module.exports = class say {
    hello(req: Request) {
        return `Hello ${req.data.to} from a TypeScript file!`
    }
}

自动化测试

文件夹test包含了用于自动化测试的文件。

setup.ts

setup.ts用于Jest的初始化。

module.exports = async () => {
    process.env.CDS_TYPESCRIPT = "true";
};
文件夹integration

如这个文件夹的命名可见,这里文件中主要是为了集成测试而准备的。

新建hello-world.test.ts

const cds = require('@sap/cds');

describe('Hello world!', () => {

    beforeAll(() => {        
    });

    afterAll(() => {
    });

    const { GET } = cds.test.in(__dirname, '../../srv').run('serve', 'world.cds');

    it('should say hello with class impl', async () => {
        const { data } = await GET `/say/hello(to='world')`;
        expect(data.value).toMatch(/Hello world.*typescript.*/i);
    });
});

执行及测试

这时候,首先执行以下命令来安装对应的开发包:

npm i

执行下列命令就可以让这个hello world的服务跑起来:

npm run start:ts

执行下列命令来执行自动化测试:

npm run test

自动化测试结果:

> @alvachien/[email protected] test
> npx jest --silent

 PASS  test/integration/hello-world.test.ts

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.931 s, estimated 1 s

对应代码及branch

与本文配套的代码参见这里。

本篇对应的branch是9_typescript