TypeScript 工程化的实践方案

简介: TypeScript 工程化的实践方案

一.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编译器会开始自动监听文件的变化。


3fe557b364c5473dbca582a3a9a4d9c7.png


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


enum Season {
  Spring,
  Summer,
  Autumn,
  Winter
}
let x:number=1


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


0ddc8d4083054d9d8bb4a2173ed30bad.png


编译选项 --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文件


5c3ce1920e1f4812831d6ce4219eabab.png


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


npm i -D webpack webpack-cli typescript ts-loader


6aa4bf281e1646f08e8f81108918cd8a.png


我们接下来要在根目录下手动创建一个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还有很多值得配置的东西,这里就不一 一写了。而且如果是前端开发的话,不同的前端框架都有相应的脚手架可以用,也不用这么麻烦的。

相关文章
|
2月前
|
JavaScript 前端开发 安全
TypeScript的优势与实践:提升JavaScript开发效率
【10月更文挑战第8天】TypeScript的优势与实践:提升JavaScript开发效率
|
1月前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
7月前
|
监控 JavaScript 安全
TypeScript在员工上网行为监控中的类型安全实践
本文演示了如何使用TypeScript在员工上网行为监控系统中实现类型安全。通过定义`Website`类型和`MonitoringData`接口,确保数据准确性和可靠性。示例展示了从监控设备获取数据和提交到网站的函数,强调了类型定义在防止错误、提升代码可维护性方面的作用。
133 7
|
7月前
|
数据采集 Web App开发 JavaScript
TypeScript 爬虫实践:选择最适合你的爬虫工具
TypeScript 爬虫实践:选择最适合你的爬虫工具
|
5月前
|
JavaScript 开发者 索引
TypeScript接口与类型别名:深入解析与应用实践
【7月更文挑战第10天】TypeScript的接口和类型别名是定义类型的关键工具。接口描述对象结构,用于类、对象和函数参数的形状约束,支持可选、只读属性及继承。类型别名则为复杂类型提供新名称,便于重用和简化。接口适合面向对象场景,类型别名在类型重用和复杂类型简化时更有优势。选择时要考虑场景和灵活性。
|
5月前
|
前端开发 JavaScript
【Vue3+TypeScript】CRM系统项目搭建之 — CSS样式方案
【Vue3+TypeScript】CRM系统项目搭建之 — CSS样式方案
37 0
|
7月前
|
JavaScript 前端开发 安全
【TypeScript技术专栏】TypeScript在Electron桌面应用中的实践
【4月更文挑战第30天】本文介绍了如何在Electron桌面应用中采用TypeScript以提升代码质量和可维护性。Electron利用Chromium和Node.js让前端开发者能创建桌面应用,而TypeScript的强类型系统和高级语言特性有助于管理复杂项目。通过初始化项目、安装依赖、配置TypeScript、编写主进程和渲染进程代码,开发者可以在Electron中实践TypeScript。一个简单的文本编辑器案例展示了TypeScript在确保类型安全方面的优势。尽管有学习成本,但TypeScript对大型Electron项目来说是值得的。
450 0
|
7月前
|
传感器 JavaScript 前端开发
【TypeScript技术专栏】TypeScript在大型项目中的实践与挑战
【4月更文挑战第30天】TypeScript在大型前端项目中日益流行,以其类型系统和ES6+支持提升代码安全与维护性。然而,采用 TypeScript 面临学习曲线、构建时间增加及类型推断挑战。通过最佳实践和成熟工具链(如 tsc、tslint 和 Visual Studio Code)可克服这些问题。案例如Angular、Basecamp和Slack已成功应用TypeScript。掌握TypeScript对提升开发者技能和市场竞争力至关重要。
114 0
|
7月前
|
JavaScript 前端开发
TypeScript中使用命名空间组织代码:原理与实践
【4月更文挑战第23天】了解TypeScript的命名空间用于组织代码,防止命名冲突,提升可读性。通过`namespace`关键字定义,如`namespace MyNamespace {...}`。访问元素时需指明命名空间,如`MyNamespace.myFunction()`。可嵌套命名空间,但应避免过度使用导致复杂。考虑使用模块代替,保持命名空间简洁。命名空间是代码组织的有效工具,但需结合实际情况灵活选择。
|
7月前
|
JavaScript 编译器 开发者
TypeScript中的类型推断机制:原理与实践
【4月更文挑战第23天】TypeScript的类型推断简化编码,提高代码可读性。编译器基于变量初始值或上下文推断类型,若新值不兼容则报错。文章深入探讨了类型推断原理和实践,包括基本类型、数组、函数参数与返回值、对象类型的推断,并提醒注意类型推断的限制,如非万能、类型兼容性和适度显式指定类型。了解这些能帮助更好地使用TypeScript。