本文目录
本系列文章
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.cds
和world.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/sapcap-fiorielements-tsapp@1.0.0 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
。