Освоение tsconfig.json

JavaScript TypeScript
Освоение tsconfig.json

В разработке TypeScript незаменимым файлом конфигурации является tsconfig.json. Это самый распространенный файл конфигурации в проектах TS. Вы действительно знаете этот файл? Какие в нем отличные комплектации? Как настроить разумный файл tsconfig.json? Эта статья поможет вам подробно разобраться в различных конфигурациях tsconfig.json.

В этой статье будет подробно представлен файл tsconfig.json со следующих аспектов:了不起的 tsconfig.json 指南.png

Уровень ограничен, приглашаем всех подсказать~~

1. Введение в tsconfig.json

1. Что такое tsconfig.json

TypeScript использует файл tsconfig.json в качестве файла конфигурации.Если файл tsconfig.json существует в каталоге, этот каталог считается корневым каталогом проекта TypeScript.

Обычно файл tsconfig.json в основном состоит из двух частей:Укажите файл для компиляцииа такжеопределить параметры компиляции.

от"Схема JSON для файла конфигурации компилятора TypeScript》Видно, что текущий файл tsconfig.json имеет следующие свойства верхнего уровня:

  • compileOnSave
  • compilerOptions
  • exclude
  • extends
  • files
  • include
  • references
  • typeAcquisition

Некоторые распространенные конфигурации свойств будут подробно описаны далее в статье.

2. Зачем использовать tsconfig.json

Обычно мы можем использоватьtscкоманда для компиляции нескольких файлов TypeScript:

/*
  参数介绍:
  --outFile // 编译后生成的文件名称
  --target  // 指定ECMAScript目标版本
  --module  // 指定生成哪个模块系统代码
  index.ts  // 源文件
*/
$ tsc --outFile leo.js --target es3 --module amd index.ts

Но если фактический проект разработки редко представляет собой один файл, когда нам нужно скомпилировать весь проект, мы можем использовать файл tsconfig.json и записать все конфигурации, которые нам нужно использовать, в файл tsconfig.json,Это устраняет необходимость вручную вводить конфигурацию каждый раз при компиляции, а также облегчает командную работу и разработку..

2. Используйте tsconfig.json

В настоящее время есть 2 операции с использованием tsconfig.json:

1. Инициализируйте tsconfig.json

В операции инициализации тоже есть 2 пути:

  1. Вручную создайте файл tsconfig.json в корневом каталоге проекта (или другом) и заполните конфигурацию;
  2. пройти черезtsc --initИнициализируйте файл tsconfig.json.

2. Укажите директорию для компиляции

без указания входного файлавоплощать в жизньtscКоманда по умолчанию запускается из текущего каталога и компилирует все.tsфайл и начните искать файл tsconfig.json из текущего каталога и выполните поиск в каталоге верхнего уровня.

$ tsc

В качестве альтернативы вы можете какtscпараметры команды--projectили-pУкажите необходимость компиляции каталога, который должен содержать файл tsconfig.json, например:

/*
  文件目录:
  ├─src/
  │  ├─index.ts
  │  └─tsconfig.json
  ├─package.json
*/
$ tsc --project src

Обратите внимание, что параметры командной строки для tsc имеют приоритет и переопределяют параметры с тем же именем в tsconfig.json..

Дополнительные параметры компиляции tsc см.«Параметры компиляции»глава.

3. Пример использования

В этой главе мы рассмотрим небольшой локальный проектlearnTsconfigДавайте научимся реализовывать простую конфигурацию.

Текущая среда разработки: windows/node 10.15.1/TypeScript3.9

1. Инициализируйте проект LearnTsconfig.

Выполните следующую команду:

$ mkdir learnTsconfig
$ cd .\learnTsconfig\
$ mkdir src
$ new-item index.ts

И мы пишем простой код для файла index.ts:

// 返回当前版本号
function getVersion(version:string = "1.0.0"): string{
    return version;
}

console.log(getVersion("1.0.1"))

Мы получим такую ​​структуру каталогов:

  └─src/
     └─index.ts

2. Инициализируйте файл tsconfig.json

Выполните в корневом каталоге LearnTsconfig:

$ tsc --init

3. Измените файл tsconfig.json.

Мы устанавливаем несколько общих элементов конфигурации:

{
  "compilerOptions": {
    "target": "ES5",             // 目标语言的版本
    "module": "commonjs",        // 指定生成代码的模板标准
    "noImplicitAny": true,       // 不允许隐式的 any 类型
    "removeComments": true,      // 删除注释 
    "preserveConstEnums": true,  // 保留 const 和 enum 声明
    "sourceMap": true            // 生成目标文件的sourceMap文件
  },
  "files": [   // 指定待编译文件
    "./src/index.ts"  
  ]
}

Одно замечание:filesЗначение элемента конфигурациимножество, используемый для указания файла для компиляции, т.е.входной файл.
Когда входной файл зависит от других файлов, нет необходимости указывать зависимые файлы дляfilesв, потому чтоКомпилятор автоматически суммирует все зависимые файлы в объекты компиляции.,Прямо сейчасindex.tsзависит отuser.ts, не надоfilesуказано вuser.ts,user.tsОн будет автоматически включен для компиляции.

4. Выполните компиляцию

После завершения настройки мы можем выполнить в командной строкеtscкоманда, после завершения компиляции мы можем получитьindex.jsфайл иindex.js.mapфайл, который доказывает, что мы скомпилировали успешно, среди которыхindex.jsСодержимое файла следующее:

function getVersion(version) {
    if (version === void 0) { version = "1.0.0"; }
    return version;
}
console.log(getVersion("1.0.1"));
//# sourceMappingURL=index.js.map

Видно, что tsconfig.json вremoveCommentsКонфигурация вступает в силу, а добавленный нами код комментария удаляется.

На этом простой пример завершен. Далее, на основе кода этого примера, я объясню «Семь общих примеров конфигурации».

Четыре, введение в файловую структуру tsconfig.json

1. Сортировка по атрибуту верхнего уровня

В файле tsconfig.json следуйтесвойства верхнего уровня, разделенных на следующие категории:tsconfig.json 文件结构(顶层属性).png

了不起的 tsconfig.json 指南.png

2. Классификация по функциям

tsconfig.json 文件结构(功能).png

Пять, введение в конфигурацию tsconfig.json

1. compileOnSave

compileOnSaveФункция атрибутаУстановите автоматическую компиляцию при сохранении файлов, но требуется поддержка компилятора.

{
	// ...
  "compileOnSave": false,
}

2. compilerOptions

compilerOptionsФункция атрибутаНастроить параметры компиляции.

подобноcompilerOptionsатрибут игнорируется, компилятор будет использовать значение по умолчанию, вы можете просмотреть«Официальный полный список параметров компиляции».

Конфигурация опций компиляции очень сложная, конфигураций много, здесь перечислены только часто используемые конфигурации.

{
  // ...
  "compilerOptions": {
    "incremental": true, // TS编译器在第一次编译之后会生成一个存储编译信息的文件,第二次编译会在第一次的基础上进行增量编译,可以提高编译的速度
    "tsBuildInfoFile": "./buildFile", // 增量编译文件的存储位置
    "diagnostics": true, // 打印诊断信息 
    "target": "ES5", // 目标语言的版本
    "module": "CommonJS", // 生成代码的模板标准
    "outFile": "./app.js", // 将多个相互依赖的文件生成一个文件,可以用在AMD模块中,即开启时应设置"module": "AMD",
    "lib": ["DOM", "ES2015", "ScriptHost", "ES2019.Array"], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array",
    "allowJS": true, // 允许编译器编译JS,JSX文件
    "checkJs": true, // 允许在JS文件中报错,通常与allowJS一起使用
    "outDir": "./dist", // 指定输出目录
    "rootDir": "./", // 指定输出文件目录(用于输出),用于控制输出目录结构
    "declaration": true, // 生成声明文件,开启后会自动生成声明文件
    "declarationDir": "./file", // 指定生成声明文件存放目录
    "emitDeclarationOnly": true, // 只生成声明文件,而不会生成js文件
    "sourceMap": true, // 生成目标文件的sourceMap文件
    "inlineSourceMap": true, // 生成目标文件的inline SourceMap,inline SourceMap会包含在生成的js文件中
    "declarationMap": true, // 为声明文件生成sourceMap
    "typeRoots": [], // 声明文件目录,默认时node_modules/@types
    "types": [], // 加载的声明文件包
    "removeComments":true, // 删除注释 
    "noEmit": true, // 不输出文件,即编译后不会生成任何js文件
    "noEmitOnError": true, // 发送错误时不输出任何文件
    "noEmitHelpers": true, // 不生成helper函数,减小体积,需要额外安装,常配合importHelpers一起使用
    "importHelpers": true, // 通过tslib引入helper函数,文件必须是模块
    "downlevelIteration": true, // 降级遍历器实现,如果目标源是es3/5,那么遍历器会有降级的实现
    "strict": true, // 开启所有严格的类型检查
    "alwaysStrict": true, // 在代码中注入'use strict'
    "noImplicitAny": true, // 不允许隐式的any类型
    "strictNullChecks": true, // 不允许把null、undefined赋值给其他类型的变量
    "strictFunctionTypes": true, // 不允许函数参数双向协变
    "strictPropertyInitialization": true, // 类的实例属性必须初始化
    "strictBindCallApply": true, // 严格的bind/call/apply检查
    "noImplicitThis": true, // 不允许this有隐式的any类型
    "noUnusedLocals": true, // 检查只声明、未使用的局部变量(只提示不报错)
    "noUnusedParameters": true, // 检查未使用的函数参数(只提示不报错)
    "noFallthroughCasesInSwitch": true, // 防止switch语句贯穿(即如果没有break语句后面不会执行)
    "noImplicitReturns": true, //每个分支都会有返回值
    "esModuleInterop": true, // 允许export=导出,由import from 导入
    "allowUmdGlobalAccess": true, // 允许在模块中全局变量的方式访问umd模块
    "moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
    "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
    "paths": { // 路径映射,相对于baseUrl
      // 如使用jq时不想使用默认版本,而需要手动指定版本,可进行如下配置
      "jquery": ["node_modules/jquery/dist/jquery.min.js"]
    },
    "rootDirs": ["src","out"], // 将多个目录放在一个虚拟目录下,用于运行时,即编译后引入文件的位置可能发生变化,这也设置可以虚拟src和out在同一个目录下,不用再去改变路径也不会报错
    "listEmittedFiles": true, // 打印输出文件
    "listFiles": true// 打印编译的文件(包括引用的声明文件)
  }
}

3. exclude

excludeФункция атрибутаУказывает файлы или папки, которые компилятор должен исключить..

Исключено по умолчаниюnode_modulesфайлы в папке.

{
	// ...
  "exclude": [
    "src/lib" // 排除src目录下的lib文件夹下的文件不会编译
  ]
}

а такжеincludeКак и свойства, подстановочные знаки glob поддерживаются:

  • *Совпадение с 0 или более символами (исключая разделители каталогов)
  • ?соответствует произвольному символу (исключая разделители каталогов)
  • **/рекурсивно соответствует любому подкаталогу

4. extends

extendsФункция атрибутаВнедрить другие файлы конфигурации, наследовать конфигурацию.

По умолчанию включаются все файлы TypeScript в текущем каталоге и подкаталогах.

{
	// ...
  // 把基础配置抽离成tsconfig.base.json文件,然后引入
	"extends": "./tsconfig.base.json"
}

5. files

filesФункция атрибутаЗадает список отдельных файлов, которые необходимо скомпилировать..

По умолчанию включаются все файлы TypeScript в текущем каталоге и подкаталогах.

{
	// ...
  "files": [
    // 指定编译文件是src目录下的leo.ts文件
    "scr/leo.ts"
  ]
}

6. include

includeФункция атрибутаУкажите файл или каталог, который необходимо скомпилировать для компиляции.

{
	// ...
  "include": [
    // "scr" // 会编译src目录下的所有文件,包括子目录
    // "scr/*" // 只会编译scr一级目录下的文件
    "scr/*/*" // 只会编译scr二级目录下的文件
  ]
}

7. references

referencesФункция атрибутаЗадает зависимости ссылок проекта.При разработке проектов иногда для удобства мы совмещаем front-end проекты и back-end.nodeРазмещены в том же каталоге проекта разработки проекта, два проекта полагаются на тот же профиль и общие файлы, но мы надеемся, что передние и задние концы гибких элементов упаковки соответственно мы можем сделать следующие конфигурации:

{
	// ...
  "references": [ // 指定依赖的工程
     {"path": "./common"}
  ]
}

8. typeAcquisition

typeAcquisitionФункция атрибутаУстановите для автоматического импорта связанных файлов определения типа библиотеки (.d.ts).Содержит 3 податрибута:

  • enable: логический тип, следует ли включить автоматический импорт файлов определения типа библиотеки (.d.ts), значение по умолчанию — false;
  • include: тип массива, позволяющий автоматически импортировать имена библиотек, например: ["jquery", "lodash"];
  • exculde: Тип массива, исключая имя библиотеки.
{
	// ...
  "typeAcquisition": {
    "enable": false,
    "exclude": ["jquery"],
    "include": ["jest"]
  }
}

6. Общие примеры конфигурации

В этой части мы нашли некоторые общие конфигурации в реальной разработке.Конечно, есть еще много конфигураций, которые нужно изучить самим~~

1. Удалите комментарии из кода

tsconfig.json:

{
  "compilerOptions": {
    "removeComments": true,
  }
}

Перед компиляцией:

// 返回当前版本号
function getVersion(version:string = "1.0.0"): string{
    return version;
}
console.log(getVersion("1.0.1"))

Результат компиляции:

function getVersion(version) {
    if (version === void 0) { version = "1.0.0"; }
    return version;
}
console.log(getVersion("1.0.1"));

2. Включить нулевое и неопределенное обнаружение

tsconfig.json:

{
    "compilerOptions": {
        "strictNullChecks": true
    },
}

Исправлятьindex.tsсодержание документа:

const leo;
leo = new Pingan('leo','hello');

В это время редактор также предложит сообщение об ошибке, выполнитеtscПосле этого консоль сообщает об ошибке:

src/index.ts:9:11 - error TS2304: Cannot find name 'Pingan'.

9 leo = new Pingan('leo','hello');

Found 1 error.

3. Повторное использование конфигурации

пройти через extendsСвойства реализуют повторное использование конфигурации, то есть файл конфигурации может наследовать свойства конфигурации другого файла.

Например, создайте базовый файл конфигурацииconfigs/base.json:

{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true
  }
}

существуетtsconfig.jsonВы можете обратиться к конфигурации этого файла:

{
  "extends": "./configs/base",
  "files": [
    "main.ts",
    "supplemental.ts"
  ]
}

4. Сгенерируйте код сопоставления для перечисления

По умолчанию используйтеconstПосле модификатора перечисление не генерирует код сопоставления.

Таким образом, мы можем видеть, что: используяconstПосле модификатора компилятор не генерирует никакихRequestMethodЛюбой код сопоставления для перечисления, когда он используется в другом месте, встраивает значение каждого члена, экономя много накладных расходов.

const enum RequestMethod {
  Get,
  Post,
  Put,
  Delete
}

let methods = [
  RequestMethod.Get,
  RequestMethod.Post
]

Результат компиляции:

"use strict";
let methods = [
    0 /* Get */,
    1 /* Post */
];

Конечно, когда мы хотим сгенерировать код отображения, мы также можем установитьtsconfig.jsonконфигурация, настройкиpreserveConstEnumsПараметры компилятораtrue:

{
  "compilerOptions": {
    "target": "es5",
    "preserveConstEnums": true
  }
}

Конечным результатом компиляции становится:

"use strict";
var RequestMethod;
(function (RequestMethod) {
    RequestMethod[RequestMethod["Get"] = 0] = "Get";
    RequestMethod[RequestMethod["Post"] = 1] = "Post";
    RequestMethod[RequestMethod["Put"] = 2] = "Put";
    RequestMethod[RequestMethod["Delete"] = 3] = "Delete";
})(RequestMethod || (RequestMethod = {}));
let methods = [
    0 /* Get */,
    1 /* Post */
];

5. Отключите подсказку аннотации этого типа.

После компиляции со следующим кодом будет сообщено об ошибке:

const button = document.querySelector("button");
button?.addEventListener("click", handleClick);
function handleClick(this) {
 console.log("Clicked!");
 this.removeEventListener("click", handleClick);
}

Содержание ошибки:

src/index.ts:10:22 - error TS7006: Parameter 'this' implicitly has an 'any' type.
10 function handleClick(this) {
Found 1 error.

Это потому что thisнеявно имеетanytype, если аннотация типа не указана, компилятор подскажет, что «этот» неявно имеет тип «любой», поскольку у него нет аннотации типа.».

Есть 2 решения:

  1. Укажите этот тип, как в этом кодеHTMLElement Типы:

HTMLElementИнтерфейсы представляют все элементы HTML. Некоторые элементы HTML напрямую реализуютHTMLElementинтерфейс, другая косвенная реализацияHTMLElementинтерфейс. о HTMLElement Подробности можно посмотреть.

  1. использовать --noImplicitThisЭлемент конфигурации:

В TS2.0 также добавлена ​​новая опция компиляции:--noImplicitThis, указывая на то, что когдаthisЗначение выраженияanyтип генерирует сообщение об ошибке. мы настроены наtrueТогда его можно нормально скомпилировать.

{
  "compilerOptions": {
    "noImplicitThis": true
  }
}

7. Примеры использования в Webpack/React

1. Настроить для компиляции кода ES6, файлов JSX

Создайте тестовый проект webpack-demo со следующей структурой:

webpack-demo/
  |- package.json
  |- tsconfig.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
    |- index.js
    |- index.ts
  |- /node_modules

Установите TypeScript и ts-loader:

$ npm install --save-dev typescript ts-loader

Настройте tsconfig.json для поддержки JSX и скомпилируйте TypeScript в ES5:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
+   "module": "es6",
+   "target": "es5",
+   "jsx": "react",
    "allowJs": true
  }
}

Вам также необходимо настроить webpack.config.js, чтобы он мог обрабатывать код TypeScript, в основном вrulesдобавлено вts-loader:

const path = require('path');

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

2. Настройте исходную карту

Чтобы включить исходные карты, мы должны настроить TypeScript для вывода встроенных исходных карт в скомпилированные файлы JavaScript.

Просто настройте свойство sourceMap в tsconfig.json:

  {
    "compilerOptions": {
      "outDir": "./dist/",
+     "sourceMap": true,
      "noImplicitAny": true,
      "module": "commonjs",
      "target": "es5",
      "jsx": "react",
      "allowJs": true
    }
  }

Затем настройте файл webpack.config.js, чтобы webpack извлек исходную карту и встроил ее в окончательный пакет:

  const path = require('path');

  module.exports = {
    entry: './src/index.ts',
+   devtool: 'inline-source-map',
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: 'ts-loader',
          exclude: /node_modules/
        }
      ]
    },
    resolve: {
      extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };

8. Резюме

Эта статья знакомит вас с файлом tsconfig.json более полным образом, начиная с вопроса «что такое файл tsconfig.js», и шаг за шагом приводит вас к всестороннему пониманию файла tsconfig.json. В этой статье используется простой проект LearnTsconfig, чтобы все знали, как использовать файл tsconfig.json в проекте. В последующих статьях мы классифицируем и изучим очень многие элементы конфигурации. Наконец, с помощью нескольких общих примеров конфигурации мы решаем несколько общих проблем, возникающих в нашей разработке.

Конечно, эта статья ограничена по объему и не может дать подробное представление о каждом атрибуте, поэтому каждый должен попробовать и использовать больше в реальной разработке~

Девять, изучение и справочные материалы

1.«Введение в справочник по TSConfig»  2."tsconfig.json"  3.«Схема JSON файла конфигурации компилятора TypeScript» 4.«Подробное объяснение конфигурации tsconfig.json в проекте TypeScript»  5.«Официальный полный список параметров компиляции»