一.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里随便编写一些代码:
enum Season { Spring, Summer, Autumn, Winter }
在命令行执行:
tsc main.ts --watch
我们运行这个命令以后,ts编译器会开始自动监听文件的变化。
当我们更改main.ts文件的内容时,比如我们加入一行新的代码:
enum Season { Spring, Summer, Autumn, Winter } let x:number=1
命令行会显示文件发生改变了,自动执行编译。
编译选项 --watch 使编译器在监视模式下运行,会监视输出文件,在它们改变时重新编译。这样的好处就是我们以后不用再手动编译main.ts这个文件了。
但是,这还有一个问题就来了,如果我还有一个ts文件,比如我再创建一个index.ts。我们也想要监视这个文件的改变,就得再开一个命令行运行监听命令。如果要监视多个文件,那这种方式其实也不够优雅,不适合我们日常的开发。我们想要只运行一个命令就可以把目录下所有的ts文件全部编译成js文件。
很简单,我们需要先在当前的目录下执行如下命令:
tsc --init
--init这个选项可以初始化 TypeScript 项目并生成一个 tsconfig.json 的配置文件。我们会发现里面的内容非常乱,我们可以把大括号内的所有内容都删掉,只留一个大括号。
然后,我们运行如下命令就可以监视所有ts文件了:
tsc --watch 或 tsc -w
OK,到这里,我终于引出了tsconfig.json这个文件。这个文件和普通json文件还真不一样,普通的json文件不能在里面写注释,而这个tsconfig.json这个文件,我们可以在里面任意写js注释。
{ //可以写注释 /* 可以写注释哦 */ }
tsconfig.json是ts编译器的配置文件,如果一个目录下存在一个 tsconfig.json 文件,那么就意味着这个目录是 TypeScript 项目的根目录。ts编译器可以根据这个配置文件里的信息对代码进行编译。这个配置文件里可以写很多的配置,接下来我们要研究的就是它的配置选项。
tsconfig.json 的主要配置项
一个 tsconfig.json 文件主要有以下配置项:
{ "compilerOptions": {}, "files": [], "include": [], "exclude": [], "extends": "", "compileOnSave": false, "typeAcquisition": {} }
compilerOptions配置项
下面是一份梳理的常用 compilerOptions 属性配置:
{ "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 文件也属于编译器包含范围。
举例如下:
{ "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:字符串类型,指向另一个要继承文件的路径。例如:
{ "extends": "config/base.json" }
这个配置项的意思就是我们可以借助 “extends” 属性引入路径为 “config/base.json” 的配置文件中的配置选项。
二.使用webpack打包ts代码
实际开发中直接去使用ts编译器去编译代码的情况其实非常少,因为我们一般在开发一些大型项目的时侯,ts一般是结合打包工具去使用的,我们用得比较多的就是webpack。下面就来学习总结一下把ts和webpack整合到一起,使用webpack来打包ts代码。
我们先创建一个目录 study ,然后运行如下命令生成package.json文件:
npm init -y
运行完命令后会在当前命令下生成package.json文件
然后运行如下命令安装webpack和webpack-cli命令行工具等开发依赖:
npm i -D webpack webpack-cli typescript ts-loader
我们接下来要在根目录下手动创建一个webpack.config.js的配置文件,并在根目录下面创建src目录,src目录里创建index.ts文件:
webpack.config.js代码:
//引入一个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文件,编写如下配置:
{ "compilerOptions": { "module": "ES2015", "target": "ES2015", "strict": true } }
我们使用webpack打包,还要再package.json里面的script配置节点里添加如下的配置:
"scripts": { "build": "webpack" }
到这里,我们就可以通过npm run build命令来打包项目了。当然,webpack还有很多值得配置的东西,这里就不一 一写了。而且如果是前端开发的话,不同的前端框架都有相应的脚手架可以用,也不用这么麻烦的。