node + TS服务端开发实践

主要技术栈:框架选择express,TS语言开发,TS在JS基础上增加了多种数据类型,包括其提供的接口编程、类型检查等特性,非常适合编写一套简单的服务端程序。

运行:ts-node + webpack + gulp

部署:webpack + pm2 / supervisor

全局安装Typescript即拥有一个编译器,可以使用tsc编译TS(ts后缀)为浏览器识别的原生js,使用"tsc -w"即可监听目录变化自动编译,源目录及输出目录等配置在项目根目录下tsconfig.json进行配置。

但是以上并不太适合实际开发中使用,我最终选择的方案为ts-node作为实例化编译器,开发模式下可在package.json配置"dev": "ts-node-dev 相对目录启动文件路径",安装devDependencies下依赖ts-node-dev,这样运行npm run dev即可启动项目并在终端查看实时代码错误检查。

编译生产使用webpack方案

webpack.config.js配置:

'use strict'
const path = require('path');
module.exports = {
    mode:'development',
    target:'node',
    entry:'./src/main.ts', // 启动文件路径
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'server.js',
    },
    module:{
        rules:[
            {
                test: /\.tsx?$/,
                use: [
                    {
                        loader: 'ts-loader',
                        options: {
                            // 加快编译速度
                            transpileOnly: true,
                            // 指定特定的ts编译配置,为了区分脚本的ts配置
                            configFile: path.resolve(__dirname, './tsconfig.json')
                        }
                    }
                ],
                exclude: /node_modules/
            },
        ]
    }
}

package.json配置

"scripts": {
    "dev": "ts-node-dev src/main",
    "build": "node script/set config.json && rm -rf ./dist && webpack && sh script/reverse.sh",
    "serve": "ts-node src/main",
    "start": "webpack --watch"
  },

开发跑 npm run dev 命令
打包跑 npm run build 命令

mian.ts

编写一个实例测试

const express = require('express')
const bodyParser = require('body-parser')
// const path = require('path')
const router = require('./control/router.ts')
const port = process.env.PORT || 8888
const app = express()
app.all('*', (req: any, res: any, next: any) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
    res.header('Access-Control-Allow-Methods', '*');
    res.header('Content-Type', 'application/json;charset=utf-8');
    next();
});
app.use((req: any, res: any, next: any) => {
    console.log(req.path)
    next()
})
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.use(router)
app.listen(port, () => console.log(`devServer start on port:${port}`))

连接mysql数据库

const mysql = require('mysql')
const db = {
        host: 'localhost',
        port: 3306,
        user: 'root',
        password: 'root',
        database: ''
    }
const pool = mysql.createPool(db)
module.exports = {
    connPool(sql: string, val: string, cb: Function) {
        pool.getConnection((error: any, conn: any) => {
            if (error) console.log(error)
            conn.query(sql, val, (err: any, rows: any) => {
                if (err) console.log(err)
                cb(rows)
                conn.release()
            })
        })
    },
    // json格式
    writeJson(res: any, code = 200, msg = 'ok', data = null) {
        const obj = { code, msg, data }
        if (!data) {
            delete obj.data
        }
        res.send(obj)
    },
    // Promise Type
    pConnPool(sql: string, val: string) {
        return new Promise((resolve) => {
            pool.getConnection((error: any, conn: any) => {
                if (error) console.log(error)
                conn.query(sql, val, (err: any, rows: any) => {
                    if (err) console.log(err)
                    resolve(rows)
                    conn.release()
                })
            })
        })
    },
}

完整实例

制作了cli工具封装一个完整实例,可运行:

npm i -g tsn-cli
tsn-cli init <project name>

然后选择服务端模板,等待下载完成即可。