TypeScript 工程化的实践方案

2022-11-22 14:13:53 浏览数 (1)

  • 一.TypeScript—编译选项和tsconfig.json配置选项
  • 二.使用webpack打包ts代码

上一篇系统地总结学习了TypeScript的基础常用语法。但我们学习 TypeScript 的目的不是为了造一间“小茅屋”,而是为了造“高楼大厦”,这也正是 TypeScript 的类型系统带来的优势。这一篇博客会学习TypeScript 工程化的一些知识点,具体内容包括:tsc编译选项、tsconfig.json的配置、webpack打包ts代码。

一.TypeScript—编译选项和tsconfig.json配置选项

JavaScript代码可以直接被浏览器执行,而TypeScript则需要编译后才能被执行,比如使用tsc命令编译。但这就会显得很麻烦,每次都要运行命令,编译后才能被执行。而且项目里不止写一个TypeScript文件,如果有多个ts文件,我们一个一个去编译那也太麻烦了。所以下面就来学习TypeScript的编译选项和tsconfig.json配置选项。

通过编译选项,可以让我们写TypeScript变得更加优雅,以前很多需要手动去完成的事情就可以自动完成了。我们还可以通过编译选项来对ts进行一些配置,比如我写的ts代码语法有问题,就不让它编译。又比如我希望把我的代码编译成ES6版本的都可以进行配置。

TypeScript 提供了很多不同功能的编译选项,既可以通过在 tsc 命令后跟随参数这种形式,直接编译 .ts 文件,也可以通过配置 tsconfig.json 文件中的 compilerOptions 属性来实现编译。但要注意: 当命令行上指定了输入文件时,tsconfig.json 文件会被忽略。

我们下面会通过代码和案例来具体学习,先创建一个目录 study ,然后在当前目录创建 main.ts 文件。

先来简单试一试--watch这个选项,我们在main.ts里随便编写一些代码:

代码语言:javascript复制
enum Season {
  Spring,
  Summer,
  Autumn,
  Winter
}

在命令行执行:

代码语言:javascript复制
tsc main.ts --watch

我们运行这个命令以后,ts编译器会开始自动监听文件的变化。

当我们更改main.ts文件的内容时,比如我们加入一行新的代码:

代码语言:javascript复制
enum Season {
  Spring,
  Summer,
  Autumn,
  Winter
}

let x:number=1

命令行会显示文件发生改变了,自动执行编译。

编译选项 --watch 使编译器在监视模式下运行,会监视输出文件,在它们改变时重新编译。这样的好处就是我们以后不用再手动编译main.ts这个文件了。

但是,这还有一个问题就来了,如果我还有一个ts文件,比如我再创建一个index.ts。我们也想要监视这个文件的改变,就得再开一个命令行运行监听命令。如果要监视多个文件,那这种方式其实也不够优雅,不适合我们日常的开发。我们想要只运行一个命令就可以把目录下所有的ts文件全部编译成js文件。

很简单,我们需要先在当前的目录下执行如下命令:

代码语言:javascript复制
tsc --init

--init这个选项可以初始化 TypeScript 项目并生成一个 tsconfig.json 的配置文件。我们会发现里面的内容非常乱,我们可以把大括号内的所有内容都删掉,只留一个大括号。

然后,我们运行如下命令就可以监视所有ts文件了:

代码语言:javascript复制
tsc --watch 或 tsc -w

OK,到这里,我终于引出了tsconfig.json这个文件。这个文件和普通json文件还真不一样,普通的json文件不能在里面写注释,而这个tsconfig.json这个文件,我们可以在里面任意写js注释。

代码语言:javascript复制
{
//可以写注释

/*
 可以写注释哦
*/

}

tsconfig.json是ts编译器的配置文件,如果一个目录下存在一个 tsconfig.json 文件,那么就意味着这个目录是 TypeScript 项目的根目录。ts编译器可以根据这个配置文件里的信息对代码进行编译。这个配置文件里可以写很多的配置,接下来我们要研究的就是它的配置选项

tsconfig.json 的主要配置项 一个 tsconfig.json 文件主要有以下配置项:

代码语言:javascript复制
{
  "compilerOptions": {},
  "files": [],
  "include": [],
  "exclude": [],
  "extends": "",
  "compileOnSave": false,
  "typeAcquisition": {}
}

compilerOptions配置项 下面是一份梳理的常用 compilerOptions 属性配置:

代码语言:javascript复制
{
  "compilerOptions": {
    "target": "ESNext", /* 指定编译之后的版本目标: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT' (最新版本的ES) */
    "module": "ESNext", /* 指定要使用的模块标准: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "noImplicitAny": false, /* 是否默认禁用 any */
    "declaration": true, /* 是否自动创建类型声明文件 */
    "strict": true, /* 启动所有类型检查 */
    "jsx": "preserve", /* 指定jsx代码用于的开发环境 */
    "importHelpers": true, /* 引入tslib里的辅助工具函数*/
    "moduleResolution": "node", /* 选择模块解析策略,有'node'和'classic'两种类型 */
    "experimentalDecorators": true, /* 启用实验性的装饰器特性 */
    "esModuleInterop": true,  /* 通过为导入内容创建命名空间,实现CommonJS和ES模块之间的互操作性 */
    "allowSyntheticDefaultImports": true, /* 允许从没有默认导出的模块中默认导入 */
    "allowSyntheticDefaultImports": true,/*允许对不包含默认导出的模块使用默认导入。这个选项不会影响生成的代码,只会影响类型检查。*/
    "sourceMap": true, /* 是否生成map文件 */
    "baseUrl": ".", /* 工作根目录 */
    "types": [], /* 指定引入的类型声明文件,默认是自动引入所有声明文件,一旦指定该选项,则会禁用自动引入,改为只引入指定的类型声明文件,如果指定空数组[]则不引用任何文件 */
    "paths": { /* 指定模块的路径,和 baseUrl有关联,和 webpack 中 resolve.alias 配置一样 */
      "@/*": [
        "src/*"
      ]
    },
    "lib": [ /* 译过程中需要引入的库文件的列表,不设置也行 */
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ],
    "outDir": "./dist", /* 用于指定编译后文件所在的目录 */
    "outFile": "./dist/app.js", /* 将我们的代码合并编译成一个文件(仅在module为amd或system时适用) */
    "allowJs": true, /*允许编译 js 文件,默认为false。设置为 true 时,js 文件会被 tsc 编译,否则不会。一般在项目中 js, ts 混合开发时需要设置。*/
    "checkJs": true, /*是否检查js的代码符合语法规范,默认为false*/
    "removeComments": true, /*是否移除注释,默认为false*/
    "noEmitOnError": true, /*当有错误时不生成编译后的文件,默认为false*/
    "alwaysStrict": true, /*是否为编译后的js开启严格模式,默认为false*/
  }
}

files、include、exclude和extends选项

files 是一个数组列表,写入待编译文件的相对或绝对路径,不支持 glob 匹配模式。

include 是一个数组列表,写入待编译文件的路径,支持 glob 匹配模式。

exclude 也是一个数组列表,写入排除某些文件路径,这些文件排除于待编译列表,支持 glob 匹配模式。

glob 通配符有: * 匹配 文件路径字符(不包括目录分隔符) ? 匹配一个任意字符(不包括目录分隔符) **/ 递归匹配任意子目录 如果 “files” 和 “include” 都没有被指定,编译器默认包含当前目录和子目录下所有的 TypeScript 文件(.ts, .d.ts 和 .tsx),排除在"exclude" 里指定的文件。

如果开启了 allowJs 选项,那 .js 和 .jsx 文件也属于编译器包含范围。

举例如下:

代码语言:javascript复制
{
  "files": [
  "core.ts",
  "index.ts",
  "types.ts"
  ],
  "exclude": [
    "node_modules", 
    "lib", 
    "**/*.test.ts"
  ],
  "include": [
    "src/**/*"
  ],
}

如果没有特殊指定,“exclude” 默认情况下会排除 node_modules,bower_components,jspm_packages 和 目录。

任何被 “files” 或 “include” 指定的文件所引用的文件也会被包含进来。

优先级:命令行配置 > files > exclude > include

extends:字符串类型,指向另一个要继承文件的路径。例如:

代码语言:javascript复制
{
  "extends": "config/base.json"
}

这个配置项的意思就是我们可以借助 “extends” 属性引入路径为 “config/base.json” 的配置文件中的配置选项。

二.使用webpack打包ts代码

实际开发中直接去使用ts编译器去编译代码的情况其实非常少,因为我们一般在开发一些大型项目的时侯,ts一般是结合打包工具去使用的,我们用得比较多的就是webpack。下面就来学习总结一下把ts和webpack整合到一起,使用webpack来打包ts代码。

我们先创建一个目录 study ,然后运行如下命令生成package.json文件:

代码语言:javascript复制
npm init -y

运行完命令后会在当前命令下生成package.json文件

然后运行如下命令安装webpack和webpack-cli命令行工具等开发依赖:

代码语言:javascript复制
npm i -D webpack webpack-cli typescript ts-loader

我们接下来要在根目录下手动创建一个webpack.config.js的配置文件,并在根目录下面创建src目录,src目录里创建index.ts文件:

webpack.config.js代码:

代码语言:javascript复制
//引入一个Nodejs包,用于处理路径
const path=require('path')

//webpack中所有的配置信息都应该写在module.exports中
module.exports={
    //指定入口文件
    entry: "./src/index.ts",
    //指定打包文件所在的目录
    output: {
        //指定打包后的目录
        path: path.resolve(__dirname,'dist'),
        //打包后文件的文件名
        filename: "bundle.js"
    },
    //指定webpack打包时要使用的模块
    module: {
        //指定要加载的规则
        rules: [{
            //指定规则对哪些文件生效,正则表达式
            //匹配所有以ts结尾的文件
            test: /.ts$/,
            //用ts-loader处理
            use: 'ts-loader',
            //要排除的文件
            exclude: /node-modules/
        }]
    },
    //打包模式,是生产模式production还是开发模式development
    mode: "development"
}

然后,我们根目录下创建tsconfig.json文件,编写如下配置:

代码语言:javascript复制
{
  "compilerOptions": {
    "module": "ES2015",
    "target": "ES2015",
    "strict": true
  }
}

我们使用webpack打包,还要再package.json里面的script配置节点里添加如下的配置:

代码语言:javascript复制
  "scripts": {
    "build": "webpack"
  }

到这里,我们就可以通过npm run build命令来打包项目了。当然,webpack还有很多值得配置的东西,这里就不一 一写了。而且如果是前端开发的话,不同的前端框架都有相应的脚手架可以用,也不用这么麻烦的。


预告:下一篇博客会用TypeScript来开发一个贪吃蛇小游戏,用来熟练TypeScript 。感兴趣的小伙伴们一定不要错过哦!


0 人点赞