Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

88 changes: 0 additions & 88 deletions .eslintrc

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/lint-and-test-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22.x'
node-version: '24.x'
- name: Install Dependencies
run: yarn
- name: Commit Linter
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22
24
100 changes: 79 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# [Tencent Server Web 2.0](https://tswjs.org)
<h1 align="center"><a href="https://tswjs.org">Tencent Server Web 3.0</a></h1>


[![license](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/Tencent/TSW/blob/master/LICENSE) [![Build Status](https://github.com/tencent/tsw/workflows/build/badge.svg)](https://github.com/Tencent/TSW/actions?query=workflow%3Abuild) [![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest) [![codecov](https://codecov.io/gh/tencent/tsw/branch/master/graph/badge.svg)](https://codecov.io/gh/tencent/tsw)
<p align="center">
<a href="https://github.com/Tencent/TSW/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg?style=for-the-badge" alt="license"></a>
<a href="https://github.com/Tencent/TSW/actions?query=workflow%3Abuild"><img src="https://img.shields.io/github/actions/workflow/status/tencent/tsw/lint-and-test-code.yml?style=for-the-badge" alt="Build Status"></a>
<a href="https://vitest.dev/"><img src="https://img.shields.io/badge/vitest-6E9F18?style=for-the-badge&logo=vitest&logoColor=white" alt="vitest"></a>
<a href="https://codecov.io/gh/tencent/tsw"><img src="https://img.shields.io/codecov/c/github/tencent/tsw?style=for-the-badge" alt="codecov"></a>
</p>

<h2 align="center">What is it</h2>

Tencent Server Web(TSW) 是一套面向 WEB 前端开发者,以提升问题定位效率为初衷,提供 **染色抓包** 和 **全息日志** 的 Node.js 基础设施。TSW 关注业务的运维监控能力,适用于 http、https 协议的业务场景,可无缝与现有应用(Koa、Express)进行整合。

TSW 2.0 在 1.0 的基础上抽丝剥茧,辅以现代化的设计模式,去除了 1.0 中的大量糟粕,同时对容器化、云原生更加友好。做到了无侵入、低成本接入。

TSW 3.0 在 2.0 的基础上全面拥抱现代化 Node.js 生态:

- **ESM 优先** — 包本身以 ESM 发布,同时完整支持 CJS 和 ESM 用户应用
- **Node.js >= 24** — 利用最新的 V8 引擎和 Node.js 特性
- 使用 AsyncLocalStorage 替代 Domain

<h2 align="center">Highlights</h2>

<table>
Expand All @@ -24,28 +34,40 @@ TSW 2.0 在 1.0 的基础上抽丝剥茧,辅以现代化的设计模式,去
</tr>
</table>

<h2 align="center">特别提醒</h2>

### TSW 1.0 迁移到 2.0 需要注意的地方
<h2 align="center">从 2.0 迁移到 3.0</h2>

- TSW 1.0 服务包含进程管理,日志管理等多项内置模块,在进行往 2.0 迁移的时候,请选择其他组件完成替代,如引入 PM2 管理 Node 进程,使用 winston 进行日志管理
- 另外 2.0 没有包含日志清理工具,建议选择 winston-rotating-file 类似工具来完成清理,避免日志存放过多,导致磁盘空间不足
TSW 3.0 包含以下 **Breaking Changes**:

- **Node.js >= 24** — 不再支持 Node.js 24 以下版本
- **ESM 包** — `@tswjs/tsw` 现在以 ESM 格式发布(`"type": "module"`),但用户应用不受影响,CJS 和 ESM 均可正常加载
- **配置文件** — 推荐使用 `export default` 语法(`.mjs` 或在 `"type": "module"` 项目中使用 `.js`);传统的 `module.exports` 写法仍然兼容
- **moment 移除** — 如果你的插件依赖了 TSW 内部的 moment,需要自行替换

<h2 align="center">Quick Start</h2>

### 1. 安装
```bash
npm install --save @tswjs/tsw
// yarn add @tswjs/tsw
# yarn add @tswjs/tsw
```
### 2. 添加配置文件
配置文件是 TSW 启动时加载进运行时的配置文件,主要声明需要使用的 [插件](#plugins) 列表。**默认会加载项目根目录下的 `tswconfig.js` 文件,也可以通过启动参数 `-c` 或者 `--config` 来手动指定配置文件路径。**

**注意事项**: 2.0 中没有集成开放平台相关逻辑,而是封装成了一个插件让用户按需使用,详情见[插件](#plugins)章节。
TSW 3.0 同时支持 CJS 和 ESM 配置文件:

**配置文件示例:**
**ESM 配置(推荐)** — 使用 `.mjs` 扩展名,或在 `"type": "module"` 的项目中使用 `.js`:
```js
// tswconfig.mjs
export default {
plugins: [
new MyPlugin({})
]
}
```

**CJS 配置** — 传统写法仍然兼容:
```js
// tswconfig.js
module.exports = {
plugins: [
new MyPlugin({})
Expand All @@ -60,15 +82,30 @@ module.exports = {
| logLevel | `DEBUG/INFO/WARN/ERROR` | `DEBUG` | yes | 设置 log level |
| winstonTransports | Array<[TransportStream](https://github.com/winstonjs/winston-transport/blob/master/index.d.ts)> | - | yes | [Winston](#winston-是什么)日志通道 |
### 3. 启动

TSW CLI 支持加载 CJS(`.js`)和 ESM(`.mjs`)入口文件:

```bash
# CJS 入口
npx @tswjs/tsw ./index.js

# ESM 入口
npx @tswjs/tsw ./index.mjs

# 指定 ESM 配置文件
npx @tswjs/tsw -c tswconfig.mjs ./index.mjs
```

**注意事项**:原先 `node --inspect ./index.js` 中的 CLI 参数如 `--inspect` 需要转化为环境变量 `NODE_OPTIONS` 来执行,如 `NODE_OPTIONS="--inspect" npx @tswjs/tsw ./index.js`。

**使用 ts**: 在保证项目有 [ts-node](https://www.npmjs.com/package/ts-node) 依赖包的情况下,按照如下方式执行即可直接加载 ts 文件。
**使用 TypeScript**: 推荐使用 [tsx](https://www.npmjs.com/package/tsx),它无需额外配置即可支持 ESM + TypeScript:
```bash
NODE_OPTIONS="--require=ts-node/register" npx @tswjs/tsw ./index.ts
NODE_OPTIONS="--import=tsx" npx @tswjs/tsw ./index.ts
```

也可以使用 [ts-node](https://www.npmjs.com/package/ts-node)(ESM 模式):
```bash
NODE_OPTIONS="--import=ts-node/esm" npx @tswjs/tsw ./index.ts
```
### CLI (Command Line Interface)

Expand All @@ -82,12 +119,27 @@ NODE_OPTIONS="--require=ts-node/register" npx @tswjs/tsw ./index.ts
2. `git clone https://github.com/Tencent/TSW.git`
3. `cd TSW`

#### Koa
#### Koa (CJS)

1. `cd examples/koa`
1. `yarn`
1. `yarn serve` 或者 `npm run serve`
1. `curl -v localhost:4443/path/to/foo -X POST -d "hello, server"`
2. `npm install`
3. `npm run serve`
4. `curl localhost:4443`

#### ESM

1. `cd examples/esm`
2. `npm install`
3. `npm run serve`
4. `curl localhost:3000` 或 `curl localhost:3000/api`

#### HTTPS

1. `cd examples/https`
2. 生成自签名证书(参考 `examples/https/README.md`)
3. `npm install`
4. `npm run serve`
5. `curl -k https://localhost:8000`

<h2 align="center">Plugins</h2>

Expand All @@ -98,7 +150,7 @@ TSW 核心的实现方式是 Hack NodeJS 自身的 `http.request` 以及 `http.c
### 一个最简单的插件

```js
export.modules = class MyPlugin() {
export class MyPlugin {
constructor() {
this.name = "MyPlugin"
}
Expand Down Expand Up @@ -134,7 +186,7 @@ export.modules = class MyPlugin() {

<h2 align="center">Cluster</h2>

TSW 2.0 是面对容器化和云原生设计的,所以没有内置 Cluster 相关功能,推荐直接使用容器的健康检查来完成服务的无损重启和故障重启机制。对于没有使用容器化方案的场景来说,我们推荐使用 [pm2](https://github.com/Unitech/pm2) 类似工具来实现多进程模式。
TSW 面对容器化和云原生设计,没有内置 Cluster 相关功能,推荐直接使用容器的健康检查来完成服务的无损重启和故障重启机制。对于没有使用容器化方案的场景来说,我们推荐使用 [pm2](https://github.com/Unitech/pm2) 类似工具来实现多进程模式。

### pm2

Expand Down Expand Up @@ -174,14 +226,16 @@ TSW 2.0 是面对容器化和云原生设计的,所以没有内置 Cluster 相

`winston` 是一个通用且轻量的日志包。`winston` 支持多个日志通道,并且可以分别定义日志优先级。除了内置的三个日志传输通道[`Console`、 `File`、`HTTP`](https://github.com/winstonjs/winston#common-transport-options),在 Winston 项目外部还会维护一些[传输模块](https://github.com/winstonjs)。查看 `winston` [官方文档](https://github.com/winstonjs/winston)。

TSW 2.0 支持使用 `winston` 传输通道记录日志信息,用户在配置文件中可以添加 `winston.transports` 实例,日志会落到对应配置中。
TSW 支持使用 `winston` 传输通道记录日志信息,用户在配置文件中可以添加 `winston.transports` 实例,日志会落到对应配置中。

### 一个简单的示例

使用 `winston` 记录 `error` 级别 以及 `debug` 级别以下的日志信息到对应文件中,当前 `config` 文件配置如下:

```js
module.exports = {
import winston from "winston";

export default {
winstonTransports: [
new winston.transports.File({ filename: 'error.log', level: 'error'}),
new winston.transports.File({ filename: 'debug.log', level: 'debug'})
Expand Down Expand Up @@ -221,6 +275,10 @@ module.exports = {

[![tsw](./static/images/user/25.png)](http://open.qq.com/ "腾讯开放平台")    [![tsw](./static/images/user/26.png)](http://kk.qq.com/ "企鹅看看")    [![tsw](./static/images/user/27.png)](http://sports.qq.com/ "腾讯体育")

<h2 align="center">Stargazers over time</h2>

[![Stargazers over time](https://starchart.cc/Tencent/TSW.svg?variant=adaptive)](https://starchart.cc/Tencent/TSW)

<h2 align="center">License</h2>

Tencent Server Web 的开源协议为 MIT, 详情参见 [LICENSE](https://github.com/Tencent/TSW/blob/master/LICENSE) 。
2 changes: 1 addition & 1 deletion docs/use-open-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

![appid-appkey](../static/images/appid-appkey.png)

1. 在项目根目录下新增配置文件 `tswconfig.js`,并参照 [开放平台插件](https://github.com/tswjs/open-platform/blob/master/packages/open-platform-plugin/README.md) 指引配置完成。
1. 在项目根目录下新增配置文件 `tswconfig.js`(CJS)或 `tswconfig.mjs`(ESM),并参照 [开放平台插件](https://github.com/tswjs/open-platform/blob/master/packages/open-platform-plugin/README.md) 指引配置完成。

1. 向之前启动的 Koa 或者原生 http server 发送请求,并且在开放平台上查看对应的日志和抓包。查看地址为下方地址拼接而成 `https://domain/log/view/YOUR_UID`

Expand Down
76 changes: 76 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import tseslint from "typescript-eslint";
import jsdoc from "eslint-plugin-jsdoc";
export default tseslint.config(
{
ignores: [
"examples/**",
"benchmark/**",
"node_modules/**",
"dist/**",
"coverage/**",
"vitest.config.ts"
]
},

...tseslint.configs.recommended,

{
files: ["**/*.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-require-imports": "off"
}
},

{
files: ["lib/**/*.ts"],
ignores: ["**/__test__/**", "**/__fixtures__/**"],
plugins: {
jsdoc
},
languageOptions: {
parserOptions: {
project: "tsconfig.json"
}
},
rules: {
"no-console": "off",

"no-underscore-dangle": "off",
"@typescript-eslint/no-explicit-any": "off",
"no-param-reassign": "off",

"max-len": ["error", { "code": 120, "ignoreComments": true }],

quotes: ["error", "double"],

"comma-dangle": ["error", "never"],

"lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],

"padding-line-between-statements": [
"error",
{ "blankLine": "always", "prev": "class", "next": "*" },
{ "blankLine": "always", "prev": "function", "next": "*" },
{ "blankLine": "always", "prev": "iife", "next": "*" },
{ "blankLine": "always", "prev": "multiline-block-like", "next": "*" },
{ "blankLine": "always", "prev": "multiline-expression", "next": "*" }
],

"jsdoc/check-param-names": "error",
"jsdoc/check-tag-names": "error",

"@typescript-eslint/no-empty-function": [
"error",
{ "allow": ["arrowFunctions"] }
],

"no-shadow": "off",
"@typescript-eslint/no-shadow": "error",

"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-require-imports": "off"
}
}
);
Loading
Loading