使用ts搭建后台服务

637 阅读3分钟

项目搭建

安装express-generator

npm i express-generator -g

然后使用express 命令创建项目

// view 后面接视图的类型
// server-side表示项目的名字
express --view=jade server-side

初始化的目录如下:

image.png

文件夹整理

  1. 根目录下创建config文件夹,用来存放配置文件
  2. 根目录下创建controller文件夹, 用来存放接口逻辑代码
  3. 根目录创建model文件夹
  4. 根目录创建utils文件夹,用来存放工具文件
  5. 创建一个types文件夹, 用来存放ts声明文件

bin文件下的www放到根目录下,改成server.ts, 删除bin文件, 修改server.ts 中文件的路径引用。 将所有js文件的后缀改成ts的后缀

安装包

  1. npm i
  2. npm i typescript
  3. npm i @types/express @types/node -D

修改tsconfig的配置

  1. 执行命令: tsc --init 生成初始化tsconfig.json
  2. 修改tsconfig.json的配置项
outDir: "./dist/",
strict: false, //关闭严格检查
noImplicitAny: false, // 检测默认的any改为false
baseUrl: ".",
paths: { // 声明文件查找
    "*": ["node_modules/*", "./types/*"]
}

修改启动服务和编译项目的脚本

根目录创建一个handle-public.js 文件 写拷贝的逻辑

const shell = require("shelljs")

shell.cp("-R", "./public/", "./dist/")
shell.cp("-R", "./views/", "./dist/")

安装包:

npm i shelljs
npm i nodemon -D
npm i cross-env
npm i ts-node -D

修改package.json文件

scripts: {
    start: "npm run serve",
    serve: "node ./dist/server.js",
    build: "tsc && node handle-public.js",
    watch-dev: "cross-env NODE_ENV=development nodemon -e ts,tsx --exec 'ts-node' ./server.ts"
}

安装模块:

npm install mysql 
npm inst all @types/mysql -D

引入mysql

创建文件: config/mysql.config.ts

const devConfig = {
    host: 'localhost',
    database: 'ts',
    user: 'root',
    password: "111111"
}

const prodConfig = {
    host: 'xxx.xxx.xxx',
    database: 'ts',
    port: 3306,
}

module.exports = process.env.NODE_ENV === 'development' ? devConfig : prodConfig

创建文件: model/index.ts

import mysql = require("mysql")

const mysqlConfig = require("../config/mysql.config")
const sql = mysql.createConnection(mysqlConfig)

sql.connect()

require('./tables/image')(sql)

export = sql

检查表是否存在,不存在就创建

创建文件: model/tables/image.ts

module.exports = sql => {
    sql.query (
        'select table_name from information_schema.tables where table_name ="image" ',
        (err, res) => {
            if(res.length) return
            sql.query(`
                create table \'mage\' (
                    \'id\' int not null auto_increment,
                    \'file_key'\ varchar(45) not null,
                    \'file_name'\ valrchar(45) not null,
                    primary key (\'id\')
                )
            `)
        }
    )
}

修改文件 server.ts 文件

// 在上面增加
require("./model")

写upload的视图

新建文件: views/upload.jade

extends layout

block content
    input(type="file", name="", id="file")
    
    script.
        function uploadFile() {
            var fileObj = document.getElementById("file").files[0]
            var url = "http://localhost:3000/api/file_upload"
            
            var form = new FormData()
            form.append("file", fileObj)
            
            xhr = new XMLHttpRequest()
            xhr.open("post", url, true) // true 表示异步
            xhr.onload = uploadComplete
            xhr.onerror = uploadFailed
            xhr.upload.onloadstart = function() {
                ot = new Date().getTime()
                oloaded = 0
            }
            xhr.send(form)
        }
        
        function uploadComplete(event) {
            if(event.target.responentText === 'success') {
                console.log("success")
            }else {
                console.log("faild")
            }
        }
        
        function uploadFailed(event) {
            console.log("faild")
        }
        
        document.getElementById("file").addEventListener("change", UploadFile)

修改文件routes/index.ts, 增加路由

// 当访问http://localhost:3000/upload 的时候跳到puload.jade
router.get("upload", function(req, res, next) => {
    res.render("upload")
})

修改 app.ts, 注册一个api 的路由

var apiRouter = require("../routers/api")
app.use("api", apiRouter)

创建文件: routes/api.ts

var express = require("express")
var router = express.Router()
import controllerApi = require("../controller/api")

router.post("/file_upload", async function(req, res, next) {
        try {
            await controllerApi.upload(req)
            res.send("success")
        }else {
             res.send("error")
        }
})

module.exports = router

安装包:

npm install formidable
npm install @types/formidable -D
  1. 创建文件夹,存放图片 files
  2. 创建文件: utils/file_upload.ts
import path = require("path")
import formidable = require("formidable")

export = function(req): Promise<formidable.File> {
    return new Promise((resove, reject) => {
        const form = new formidable.IncomingForm()
        form.encoding = "utf-8"
        form.uploadDir = path.join(__dirname, "../files/")
        form.keepExtensions = true
        form.parse(req, (err, fields, files) => {
            const { file } = files
            if (!err) resolve(file)
            else reject(err)
        })
    })
}

创建文件: controller/api.ts

import file_upload = reqire("../utils/file_upload")
import apiModelServe = require("../model/server/api")

export = {
    upload: async (req: Express.Request) => {
        const file = await file_upload(req)
        const currentName = file.path.split("uoload_")[1]
        const key = currentName.split(".").[0]
        return apiModelServer.upload(key, currentName)
    }
}

创建文件: model/server/api.ts

import sql = require("../index")

export = {
    upload(key, name) {
        return new Promise((resolve, reject) => {
            sql.query(
                `insert into image (file_key, file_name) values ("${key}", "upload_${name}")`,
                (err, res) => {
                    if(err) reject(err)
                    else resolve(res)
                }
            )
        })
    }
}

发布

  1. npm run build
  2. 将打包的文件放到服务器