一塊兒學 TypeScript 配置篇

本篇主要介紹 TypeScript 中的 tsconfig.json 文件的做用以及配置參數.主要介紹文件選項和編譯選項兩部分.node

若是一個目錄下存在一個 tsconfig.json 文件,那麼它意味着這個目錄是 TypeScript 項目的根目錄。tsconfig.json 文件中指定了用來編譯這個項目的根文件和編譯選項。 一個項目能夠經過如下方式之一來編譯:jquery

  • 不帶任何輸入文件的狀況下調用 tsc,編譯器會從當前目錄開始去查找 tsconfig.json文 件,逐級向上搜索父目錄。
  • 不帶任何輸入文件的狀況下調用 tsc,且使用命令行參數 --project(或 -p )指定一個包含 tsconfig.json 文件的目錄。

當命令行上指定了輸入文件時,tsconfig.json文件會被忽略。es6

文件選項

files

它的含義是編譯器須要編譯的相對或絕對文件路徑的單個文件列表。web

{
  "files": [
    "src/index.ts"
  ]
}
複製代碼

這時執行 tsc 命令,編譯器會編譯 src/index.ts 文件。typescript

include

它的含義是編譯器須要編譯的文件或者目錄。json

{
  "include": [
    "src"
  ]
}
複製代碼

這時執行 tsc 命令,編譯器會編譯 src 目錄下的全部 ts 文件。bash

exclude

它的含義是編譯器須要排除的文件或者目錄。默認會排除 node_modules 目錄下的全部文件。app

{
  "exclude": [
    "src/lib"
  ]
}
複製代碼
    1. 若是 filesincludes 都沒有指定,編譯器默認包含當前目錄下全部的 ts 文件。(.ts.d.ts.tsx
    1. 若是 exclude 存在,exclude 配置優先級高於 filesincludes 配置
    1. excludeincludes 配置支持 glob 通配符:*?**

extends

咱們能夠把一些配置抽離出一個配置文件,再 tsconfig.json 文件引入,方便之後管理與維護。dom

// tsconfig.json

{
  "extends": "./base.json"
}
複製代碼

在主配置文件中,設置文件選項會覆蓋調繼承文件中的相同的配置項。函數

compileOnSave

它可讓 IDE 在保存文件時,編譯器自動編譯。

{
  "compileOnSave": true
}
複製代碼

目前只有個別 IDE 支持。

編譯選項

大體配置以下所示:

{
  "compilerOptions": {
    "incremental": true,                // 增量編譯
    "tsBuildInfoFile": "./buildFile",   // 增量編譯文件的存儲位置
    "diagnostics": true,                // 打印編譯信息

    "target": "es5",           // 目標語言的版本
    "module": "commonjs",      // 生成代碼的模塊標準
    "outFile": "./app.js",     // 將多個相互依賴的文件生成一個文件,能夠用在 AMD 模塊中

    "lib": [],                 // TS 須要引用的庫,即聲明文件,es5 默認 "dom", "es5", "scripthost"

    "allowJs": true,           // 容許編譯 JS 文件(js、jsx)
    "checkJs": true,           // 容許在 JS 文件中報錯,一般與 allowJS 一塊兒使用
    "outDir": "./out",         // 指定輸出目錄
    "rootDir": "./",           // 指定輸入文件目錄(用於輸出)

    "declaration": true,         // 生成聲明文件
    "declarationDir": "./d",     // 聲明文件的路徑
    "emitDeclarationOnly": true, // 只生成聲明文件
    "sourceMap": true,           // 生成目標文件的 sourceMap
    "inlineSourceMap": true,     // 生成目標文件的 inline sourceMap
    "declarationMap": true,      // 生成聲明文件的 sourceMap
    "typeRoots": [],             // 聲明文件目錄,默認 node_modules/@types
    "types": [],                 // 聲明文件包

    "removeComments": true,    // 刪除註釋

    "noEmit": true,            // 不輸出文件
    "noEmitOnError": true,     // 發生錯誤時不輸出文件

    "noEmitHelpers": true,     // 不生成 helper 函數,需額外安裝 ts-helpers
    "importHelpers": true,     // 經過 tslib 引入 helper 函數,文件必須是模塊

    "downlevelIteration": true,    // 降級遍歷器的實現(es3/5)

    "strict": true,                        // 開啓全部嚴格的類型檢查
    "alwaysStrict": false,                 // 在代碼中注入 "use strict";
    "noImplicitAny": false,                // 不容許隱式的 any 類型
    "strictNullChecks": false,             // 不容許把 null、undefined 賦值給其餘類型變量
    "strictFunctionTypes": false,          // 不容許函數參數雙向協變
    "strictPropertyInitialization": false, // 類的實例屬性必須初始化
    "strictBindCallApply": false,          // 嚴格的 bind/call/apply 檢查
    "noImplicitThis": false,               // 不容許 this 有隱式的 any 類型

    "noUnusedLocals": true,                // 檢查只聲明,未使用的局部變量
    "noUnusedParameters": true,            // 檢查未使用的函數參數
    "noFallthroughCasesInSwitch": true,    // 防止 switch 語句貫穿
    "noImplicitReturns": true,             // 每一個分支都要有返回值

    "esModuleInterop": true,               // 容許 export = 導出,由import from 導入
    "allowUmdGlobalAccess": true,          // 容許在模塊中訪問 UMD 全局變量
    "moduleResolution": "node",            // 模塊解析策略
    "baseUrl": "./",                       // 解析非相對模塊的基地址
    "paths": {                             // 路徑映射,相對於 baseUrl
      "jquery": ["node_modules/jquery/dist/jquery.slim.min.js"]
    },
    "rootDirs": ["src", "util"],           // 將多個目錄放在一個虛擬目錄下,用於運行時

    "listEmittedFiles": true,        // 打印輸出的文件
    "listFiles": true,               // 打印編譯的文件(包括引用的聲明文件)
  }
}
複製代碼

接下來,咱們會逐個分析上面的配置項。

incremental

它的含義是增量編譯,TypeScript 編譯器在第一次編譯後會生成一個能夠編譯信息的文件,在以後的編譯以後會根據這個文件提升編譯的速度。該文件默認會在根目錄下名稱爲 tsconfig.tsbuildinfo

{
  "program": {
    "fileInfos": {
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.d.ts": {
        "version": "49ff9798f592c8b7e628fd881401e68810c1b3589ecd7a41b32b3c287374cde0",
        "signature": "49ff9798f592c8b7e628fd881401e68810c1b3589ecd7a41b32b3c287374cde0"
      },
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.es5.d.ts": {
        "version": "ff5688d6b2fcfef06842a395d7ff4d5730d45b724d4c48913118c889829052a1",
        "signature": "ff5688d6b2fcfef06842a395d7ff4d5730d45b724d4c48913118c889829052a1"
      },
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.dom.d.ts": {
        "version": "2d53f3741e5a4f78a90f623387d71a1cc809bb258f10cdaec034b67cbf71022f",
        "signature": "2d53f3741e5a4f78a90f623387d71a1cc809bb258f10cdaec034b67cbf71022f"
      },
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.webworker.importscripts.d.ts": {
        "version": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b",
        "signature": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b"
      },
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.scripthost.d.ts": {
        "version": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9",
        "signature": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9"
      },
      "./src/index.ts": {
        "version": "a0e2a405f15ab7f6218e22c622acc2706d51eae2aa90f302f81f68628e22cd55",
        "signature": "ec8f4696ee1308e5fbc9f50626f5677f0f15bd7c228311cbcc0669233461fa1d"
      }
    },
    "options": {
      "incremental": true,
      "configFilePath": "./tsconfig.json"
    },
    "referencedMap": {},
    "exportedModulesMap": {},
    "semanticDiagnosticsPerFile": [
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.d.ts",
      "./src/index.ts",
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.es5.d.ts",
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.dom.d.ts",
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.webworker.importscripts.d.ts",
      "../../../../../usr/local/lib/node_modules/typescript/lib/lib.scripthost.d.ts"
    ]
  },
  "version": "3.6.2"
}
複製代碼

tsBuildInfoFile

能夠修改增量編譯文件的存儲文件夾和文件名

diagnostics

打印編譯信息。

Files:            6
Lines:        24817
Nodes:       111372
Identifiers:  41045
Symbols:      27914
Types:         8268
Memory used: 68338K
I/O read:     0.01s
I/O write:    0.00s
Parse time:   0.42s
Bind time:    0.23s
Check time:   1.13s
Emit time:    0.02s
Total time:   1.80s
複製代碼

target

設置目標語言的版本,可設置爲 ES3ES5ES2015 等等,默認爲 ES3

module

設置生成代碼的模塊標準,能夠設置爲 CommonJSAMDUMD 等等。

outFile

將多個相互依賴的文件生成一個文件,能夠用在 AMD 模塊中。

咱們建立兩個文件,分別爲 index.tsamd.ts,以下所示:

// ./src/index.ts
import a = require('./amd')

let str: string = 'abc'
複製代碼
// ./src/amd.ts

let amd: number = 0

export = amd
複製代碼

index.ts 引入 amd.ts,咱們再設置一下 tsconfig.json 文件。

{
  "compilerOptions": {
    "module": "amd",
    "outFile": "./app.js"
  }
}
複製代碼

而後在命令行執行 tsc 命令,編譯器會將兩個 ts 文件合併編譯成一個 app.js 文件。

define("amd", ["require", "exports"], function (require, exports) {
 "use strict";
    var amd = 0;
    return amd;
});
define("index", ["require", "exports"], function (require, exports) {
 "use strict";
    exports.__esModule = true;
    var str = 'abc';
});
複製代碼

lib

指定 ts 須要引用的庫,即聲明文件,若 target 設置爲 es5 時,lib 默認爲 ["dom", "es5", "scripthost"]

例如,咱們想在 ts 中使用 es2019 的方法。能夠在 lib 配置裏添加 es2019

allowJs

容許編譯器編譯 JS 文件(js、jsx)。

checkJs

容許在 JS 文件中報錯,一般與 allowJS 一塊兒使用。

outDir

指定輸出目錄

rootDir

指定輸入文件目錄

declaration

編譯器編譯時,容許生成聲明文件(.d.ts)。

declarationDir

指定聲明文件的生成的目錄。

emitDeclarationOnly

編譯器編譯時,只容許生成聲明文件。

sourceMap

編譯器編譯時,生成目標文件的 sourceMap 文件。

inlineSourceMap

編譯器編譯時,將 sourceMap 生成在 js 文件中。

declarationMap

編譯器編譯時,生成聲明文件的 sourceMap。

typeRoots

設置聲明文件目錄,默認 node_modules/@types

types

這是聲明文件包,若是設置了某一個聲明文件,那麼編譯器只會加載這個聲明文件。

removeComments

是否刪除註釋

noEmit

執行 tsc 不會輸出任何文件

noEmitOnError

發生錯誤時不輸出文件

noEmitHelpers

設置爲 true 時,不生成 helper 函數。先看下面示例:

class B {}

class A extends B {}

export = A
複製代碼

咱們建立了一個模塊。而後在控制檯執行 tsc,下面就是編譯後的結果:

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var B = /** @class */ (function () {
    function B() {
    }
    return B;
}());
var A = /** @class */ (function (_super) {
    __extends(A, _super);
    function A() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return A;
}(B));
module.exports = A;
複製代碼

編譯器會自動生成 __extends

若是咱們將 noEmitHelpers 這個配置設置爲 true 以後。編譯後的結果以下:

"use strict";
var B = /** @class */ (function () {
    function B() {
    }
    return B;
}());
var A = /** @class */ (function (_super) {
    __extends(A, _super);
    function A() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return A;
}(B));
module.exports = A;
複製代碼

上面的編譯後的結果中 __extends 未定義。ts 已經爲開發者定義了一個配置項,方便解決該問題。 就是接下來要介紹的配置 importHelpers

importHelpers

經過 tslib 引入 helper 函數,文件必須是模塊。編譯結果以下:

"use strict";
var tslib_1 = require("tslib");
var B = /** @class */ (function () {
    function B() {
    }
    return B;
}());
var A = /** @class */ (function (_super) {
    tslib_1.__extends(A, _super);
    function A() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return A;
}(B));
module.exports = A;
複製代碼

若提示 tslib 未找到時,能夠手動安裝它。

downlevelIteration

降級遍歷器的實現,下面是一個 es6 語法:

let a = [1, 2, 3]
let b = [4, ...a]
複製代碼

咱們打開這項配置,進行編譯後結果以下:

var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (this && this.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
var a = [1, 2, 3];
var b = __spread([4], a);
複製代碼

會生成兩個 helper 函數。

strict

表示開啓全部嚴格的類型檢查,若 strict 爲 true,alwaysStrictnoImplicitAnystrictNullChecksstrictFunctionTypesstrictPropertyInitializationstrictBindCallApplynoImplicitThis 選項默認都爲 true。

alwaysStrict

在代碼中注入 use strict

noImplicitAny

不容許隱式的 any 類型。

strictNullChecks

不容許把 nullundefined 賦值給其餘類型變量。

strictFunctionTypes

不容許函數參數雙向協變。

strictPropertyInitialization

類的實例屬性必須初始化。

strictBindCallApply

嚴格的 bindcallapply 檢查。

function add (a: number, b: number) {
  return a + b
}

add.call(undefined, 1, '2')
// Error: Argument of type '"2"' is not assignable to parameter of type 'number'.
複製代碼

noImplicitThis

不容許 this 有隱式的 any 類型。

class A {
  name: string = 'abc'
  getName () {
    return function () {
      console.log(this.name)
    }
  }
}
// Error: 'this' implicitly has type 'any' because it does not have a type annotation.
複製代碼

noUnusedLocals

檢查只聲明,未使用的局部變量

noUnusedParameters

檢查未使用的函數參數

noFallthroughCasesInSwitch

防止 switch 語句貫穿

noImplicitReturns

每一個分支都要有返回值

esModuleInterop

容許 export = 方式導出,也能夠用 import = 的方式導入。

allowUmdGlobalAccess

容許在模塊中訪問 UMD 全局變量

moduleResolution

模塊解析策略,這裏提供兩種解析策略 nodeclassicts 默認使用 node 解析策略。

  • classic 模塊解析策略

適用於 AMDSystemES2015

若是一個模塊使用相對方式導入時,ts 就會依次解析同級目錄 .ts.d.ts 文件。

// /root/src/moduleA.ts

import { b } from './moduleB'

/** * /root/src/moduleB.ts * /root/src/moduleB.d.ts */
複製代碼

若是使用非相對方式導入時以下, ts 會從當前目錄的 node_modules 目錄裏查找,若是未找到,會依次向上級目錄查找。

// /root/src/moduleA.ts

import { b } from 'moduleB'

/** * /root/src/node_modules/moduleB.ts * /root/src/node_modules/moduleB.d.ts * * /root/node_modules/moduleB.ts * /root/node_modules/moduleB.d.ts * * /node_modules/moduleB.ts * /node_modules/moduleB.d.ts */
複製代碼
  • node 模塊解析策略

使用相對方式導入

// /root/src/moduleA.ts

import { b } from './moduleB'

/** * /root/src/moduleB.ts * /root/src/moduleB.tsx * /root/src/moduleB.d.ts * /root/src/moduleB/package.json ( types 屬性) * /root/src/moduleB/index.ts * /root/src/moduleB/index.tsx * /root/src/moduleB/index.d.ts */
複製代碼

使用非相對方式導入

// /root/src/moduleA.ts

import { b } from 'moduleB'

/** * /root/src/node_modules/moduleB.ts * /root/src/node_modules/moduleB.tsx * /root/src/node_modules/moduleB.d.ts * /root/src/node_modules/package.json ( types 屬性) * /root/src/node_modules/index.ts * /root/src/node_modules/index.tsx * /root/src/node_modules/index.d.ts * * 依次向上目錄查找 */
複製代碼

baseUrl

解析非相對模塊的基地址,默認爲當前目錄

paths

路徑映射,相對於 baseUrl。好比示例中咱們想引入 jquery 精簡版本,能夠制定它的相對路徑。

rootDirs

將多個目錄放在一個虛擬目錄下,用於運行時。

好比 咱們建立量如下兩個文件。

// /util/a.ts
let a: string = 'A'
export = a
複製代碼
// /src/index.ts
import a from './a'
複製代碼

注意在引入 a 時,是引入的當前目錄。由於當 rootDirs 設置了 srcutil 目錄時,編譯器默認它們屬於同級目錄。

listEmittedFiles

打印輸出的文件。

listFiles

打印編譯的文件,包括引用的聲明文件。

結語

想要了解更多關於 TypeScript 相關知識,能夠點擊TypeScript開發教程收藏並閱讀.

相關文章
相關標籤/搜索