使用node+typescript搭建mvc后台(一)--使用typescript搭建express后台

2,047 阅读5分钟

使用typescript搭建express后台

项目博客地址

首先我们先用express脚手架搭建一个初始的项目环境。(用脚手架的主要目的是因为脚手架已经给我们提供了很多方便的配置。我们在次的基础上进行一定的修改就能搭建更完善的项目)

安装express脚手架

npm install -g express-generator

初始化一个项目

express node-mvc

然后我们可以用vscode打开项目更方便的操作

image.png

然后我们再安装下依赖,执行yarn或者npm install
等到依赖安装完毕。我们就可以执行npm start启动项目
image.png

然后浏览器输入localhost:3000可以看到我们的项目已经启动起来了

转换typescript

接下来要做什么。简单的来说。就是把express脚手架初始化搭建的项目先统一转化为typescript的格式。然后再在这基础上做自己一些增值上的操作

新建同名ts文件

首先我们来转化www.js这个文件。这个为项目的入口文件。也可以说是启动文件。
在同级下新建www.ts文件。同理我们把其他目录下的ts文件也统一新建过去。生成一个和原来有相同目录结构的ts项目。生成如下目录结构

image.png

新建tsconfig.json文件

tsconfig.json文件为typescript的配置文件。在typescript编译为js文件的时候会根据这个进行一定的规则匹配。
这里贴一份我目前是tsconfig.json的配置

{
    "compilerOptions": {
        "module": "commonjs", // 指定编译生成哪个模块的系统代码,考虑到兼容性,这里我们设置成 commonjs
        "target": "es6", // 目标语法
        "strict": true, // 严格模式
        "esModuleInterop": true,// 模块导入方式
        "baseUrl": "./", // 定义 ts 项目的根目录,设置 paths 前必须设置
        "outDir": "dist", // 编译输出目录,即 .ts 文件编译成 .js 文件后的输出目录。这里设置为根目录下的 /dist 目录
        "moduleResolution": "node",
        "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错。设为 false 避免当类型推论为 any 时报错
        "allowSyntheticDefaultImports": true, //(加了就能用import from)则检测导入的模块是否是 ES6 模块,如果不是,则查找模块中是否有 exports.default 导出。
        "sourceMap": true, // 是否开启sourceMap
        "experimentalDecorators": true, // 使用注解需要
        "emitDecoratorMetadata": true,
        //定义路径别名,即当我们通过路径引入一个模块时,可以使用别名来进行引入,这里第一个 * 设置是为了引入第三方模块; 第二个 '@/*' 则是为了直接快捷的导入 /src 下的模块。
        "paths": {
            "*": [
                "node_modules/*",
                "src/types/*"
            ],
            "@/*": [
                "src/*"
            ]
        },
        "lib": [
            "es5",
            "es6",
            "dom",
            "es2015.core",
            "es2015.collection",
            "es2015.generator",
            "es2015.iterable",
            "es2015.promise",
            "es2015.proxy",
            "es2015.reflect",
            "es2015.symbol",
            "es2015.symbol.wellknown",
            "esnext.asynciterable"
        ]
    },
    "include": ["src"], // 需要编译的 ts 文件,这里设置为 src 目录下的所有文件
    "exclude": [
        "node_modules"
    ]
}

主要是一些基础的配置。目前我们首要任务是把项目转为typescript项目启动。这个有兴趣的同学可以自己进行研究。

安装声明文件。

typescript的引用是需要对模块进行声明的。否者可能就找不到你安装的依赖模块。
这里先黏贴一份我目前项目的声明

"devDependencies": {
    "@types/http-errors": "^1.6.3",
    "@types/jade": "0.0.30",
    "@types/morgan": "^1.9.0",
    "@types/uuid": "^3.4.5",
    "@types/cookie-parser": "^1.4.1",
    "@types/debug": "^4.1.4",
    "@types/dotenv": "^6.1.1",
    "@types/express": "^4.17.0",
    "@types/express-flash": "0.0.0",
    "@types/lusca": "^1.6.0",
    "@types/node": "^13.9.2",
    "@types/request": "^2.48.3",
    "@types/swagger-ui-express": "^3.0.1",
    "@types/winston": "^2.3.9",
    "@types/ws": "^6.0.3",
    "nodemon": "^1.19.1"
  }

主要为一个示例,里面的lib是否需要依据个人项目而定
在后期找不到模块的时候可以考虑是否是声明模块没有安装。
这里的安装过程我就不一一去确定了。给出一个最后的package.json文件。

{
  "name": "node-mvc",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "debug": "export NODE_ENV=development&&nodemon ./src/bin/www",
    "wstart": "set NODE_ENV=production&&node ./src/bin/www",
    "wdebug": "set NODE_ENV=development&nodemon ./src/bin/www",
    "tsStart": "node  ./dist/bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "dotenv": "^8.0.0",
    "ejs": "~2.6.1",
    "express": "~4.16.1",
    "express-flash": "0.0.2",
    "express-validator": "^6.1.1",
    "file-stream-rotator": "^0.4.1",
    "fs": "0.0.1-security",
    "http-errors": "~1.6.3",
    "jade": "^1.11.0",
    "jsonwebtoken": "^8.5.1",
    "log4js": "^4.2.0",
    "lusca": "latest",
    "morgan": "~1.9.1",
    "mysql": "^2.17.1",
    "mysql2": "^1.6.5",
    "reflect-metadata": "^0.1.13",
    "routing-controllers": "^0.7.7",
    "sequelize": "^5.9.2",
    "swagger-ui-express": "^4.0.7",
    "typedi": "latest",
    "typeorm": "^0.2.18",
    "typeorm-typedi-extensions": "^0.2.3",
    "uuid": "^3.3.3",
    "winston": "^2.4.2",
    "ws": "^7.1.2"
  },
  "devDependencies": {
    "@types/http-errors": "^1.6.3",
    "@types/jade": "0.0.30",
    "@types/morgan": "^1.9.0",
    "@types/uuid": "^3.4.5",
    "@types/cookie-parser": "^1.4.1",
    "@types/debug": "^4.1.4",
    "@types/dotenv": "^6.1.1",
    "@types/express": "^4.17.0",
    "@types/express-flash": "0.0.0",
    "@types/lusca": "^1.6.0",
    "@types/node": "^13.9.2",
    "@types/request": "^2.48.3",
    "@types/swagger-ui-express": "^3.0.1",
    "@types/winston": "^2.3.9",
    "@types/ws": "^6.0.3",
    "nodemon": "^1.19.1"
  }
}

复制改写原来的js文件

接下来就改写原来的js文件为ts。如routes/users.ts
这里对typescript的语法不做过多介绍。查看一个js转ts的文件变化
这里为了快速通过编译。我把所有的类型都设置了为any
原js文件

var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

新ts文件

import express from 'express';
const router = express.Router();
router.get('/', function(req, res, next) {
    res.render('index', { title: 'Express' });
});

export default router;

编译typescript

等到所有的js文件都转为了ts后。好像。我们还不能启动。毕竟ts不是能直接运行的文件。我们先要对ts进行一次转换。之前我用的是webstorm。可以安装插件。直接把ts编译成js,可以参考如下的一篇文章webstorm下自动编译ts为js设置(ts文件修改后,自动编译到对应的目录的js)
不过目前改用vscode来编写代码了。接下来只能使用命令的方式来编译ts。(不知道vscode有没有这样的插件)。
我们先创建一个src的文件夹。到时候ts会以这个为根目录进行编译。然后把之前写的代码都复制到src下。接下来在根目录也就是有tsconfig.json的目录下执行tsc(当然前提你的先全局安装好typescript的模块)。
接下来就会在dist目录下生成编译好的文件。我们再在package.json编写一条启动命令。

"tsStart": "node ./dist/bin/www"

启动的时候可能会发现没有views文件。是因为我们一开始没有把views的页面文件拷到dist目录下。等到以后做前后端分离后可能就不需要这个了。所以现在我们再拷进去。重新刷新页面。
就可以拷到新的页面了

image.png

至此。我们便成功将一个express的js项目转为ts项目了仓库代码