首先学习识别已有的js库的类型
识别已有的js库的类型
UMD既能够做为全局库使用,也能够做为模块使用html
新建文件
接收一个title,改变页面title的值
这里用到 &&的特性,若是操做符两边的条件都为true,那他的返回值才是true
若是第一个为false了,因此它确定也不是true,后面的逻辑不会走,利用这个特性能够简化咱们的代码,就不用写if document是否为空的判断了
这句话的意思就是若是document为真才会执行后面的语句
若是document存在就返回document.title.若是不存在就返回为空字符串
而后再定义一个变量,调用getTitle()方法赋值
咱们在这里全局引用一下
运行起来是找不到这个文件的。
在终端执行npm run build看一下运行以后的效果,在dist文件夹下面只有一个index.html和main.js文件
index.ts内引入的js文件都打包到main.js文件夹内,并无把咱们的handle-title.js引进来,因此使用这种相对路径的方式是无法引入的
这里可使用一个webpack的插件,把这个handle-title.js文件直接拷贝过去,不须要编译
npm install -D copy-webpack-plugin:安装这个插件
webpack.config.js内把这个插件引进来
它接收一个对象,对象有两个属性
这里用到Node.js里的一个模块Path,在上面先引入一下
path.join拼接一个路径,__dirname表明当前js执行的一个绝对路径
由于webpack.config.js是在build的文件夹下,因此要想找到handle-title.js这个文件的路径就须要往上返一个目录
to:就是复制到哪一个文件夹下
npm run build再来从新编译一下,handle-t
引用的路径改为同级别的js文件
再次npm run build,生成的最终结果
咱们在js里面输出一句话,来证实咱们引用成功了
能够看到咱们引用成功了,打印出了123
ahndle-title.js里面定义的方法是全局的,那么咱们在咱们项目的每一天个ts文件内均可以引用到,
建立一个新的文件
而后在index.ts内引入
如今调用会报错,找不到名称,就是由于咱们须要给它写一个声明文件
咱们在src下新建index.d.ts文件
15分32秒
在tsconfig.json内增长include的选项
会引入src下面的全部.ts的文件
还须要引入src目录下的.d.ts的格式的文件
若是不写include的配置,会把全部的文件都引进来
下面在这个文件夹里面,编写声明
全局写生命苦的模板:
https://www.tslang.cn/docs/handbook/declaration-files/templates.html
global.d.ts 当你要为一个全局库写声明文件的模板
暴露在全局的函数重载,前面要用declar修饰符修饰,这是一个全局的
这里给myLib定义的接口,让这个库做为一种类型,定义一下只要是这种类型,必须有哪些字段
这个库还有这一些全局的属性,这里导出为命名空间了
handle-title.js里面写声明
用declare去修饰,设置传入的title的值必须是stirng或者是数字的,、由于它没有返回值,这里返回类型就写void
第二个getTitle方法和第三个全局的变量
这个地方仍是有报错
可是这里已经打出了ts-learn
是由于咱们这里的命名,不该该写成index.d.t和index.js重名,都叫作index因此只会引入index.ts
index.d.ts更名为:global.d.ts 这个里面用来放全部的全局的一些东西 声明
这个地方就不会报错了,npm start从新编译一下;修改完文件须要从新编译才会从新加载这些声明文件
再来调用setTitle的方法,能够看到咱们没有引入,可是可使用这个函数,还有正确的类型提示
页面的title已经改变了
打印出来咱们getTitle方法返回的值;
这就是一个简单的全局声明的书写,能够参考官方的模块node
也就是依赖了模块解析器的库
接下来看下,如何判断一个库是模块化库
在模块化中你通常会看到,impport引入语句,输出语句,或者无条件的调用一些require或者define方法,这些都是要依赖模块解析器的。
或者赋值给export点什么赋一个值,用来导出一个东西
或者module.expports导出一个默认的东西,这种他就是一个模块化的库
极少会在模块化库中看到对window、global的赋值,固然这也不是绝对的,有些库他就是要操做window的一些属性
https://www.tslang.cn/docs/handbook/declaration-files/templates.html
官方模板,module开头的有四个文件jquery
若是你要引入一个模块能够直接当作一个函数来调用,就能够参考:module-function.d.ts
若是这个模块引入以后,能够当作类来使用,可使用new关键字来建立实例,就能够参考module-class.d.ts
若是既不能作实例也不能作函数使用就参考:module.d.ts
实战的时候会讲webpack
将全局库和模块库的功能进行了合并,他会首先判断环境中有没有模块加载器以及特定的方法
好比去判断define,有没有这个方法 define 、typeof有没有结合
不等于undefined,说明是有define方法的
若是说判断下module等于这个object
module上面还有exports属性,说明他是有模块加载系统的。若是这两种都没有,就走全局的形式,通常有这些判断的在UMD库中会看到这些判断逻辑
如今不少都是UMD库,既能够在html中用script方式引入,也可使用模块系统来加载,好比jquery、moment这些库es6
基本上全部的库都有第三方给他们编写的声明文件
好比咱们如今想使用一个库,在node_modules/arr-diff这么一个库,能够看到这个库里面只有这四个文件,它没有一个声明文件,若是使用里面的方法就会报错
须要安装它的声明:npm install @types/arr-diff -D:做为开发依赖来安装 若是安装成功了说明有这个库的声明文件吗,若是没有安装成功,说明没有社区给他编写声明文件,那咱们就须要本身写了
看到这个带加号的说明有这个声明文件
node_modules/@types/arr-diff/index.d.ts声明文件
它的声明文件比较简单。就是导出了一主方法,能够在全局中使用也能够在模块中使用
再把它卸载掉:npm uninstall @types/arr-diffweb
处理库声明文件里面第一部分:模块插件或者UDM插件
一些模块或者拆件是支持插件机制的,好比咱们常见的jquery,它的插件就很是多,能够为这个库数写声明文件的为库的键?定义声明文件?(听不大清楚,多是这样的),能够参考:module-plugin.d.ts
https://www.tslang.cn/docs/handbook/declaration-files/templates.htmlnpm
有一些是影响全局的全局插件,有些库会在原生的js数据类型的原型对象上添加一些方法,使用原生的数据可以调用更为丰富的方法,
下面来举个例子,咱们要string的远行对象上加个方法
在string 的原型对象上,构造函数原型对象上添加一个getFirstLetter方法,会放回当这个值的第一个字符
在浏览器中查看效果
这种模块引进来之后会修改全局,对全局的string函数都会构成影响,
这个模块,咱们要为它写声明文件
它会给String作生命合并,定义一个接口String在里面定义个方法getFirstLetter它的返回值类型是string
那么咱们要引入这个模块
在写的时候已经有代码提示了name.getFirstLetter
若是把这个声明去掉
那么就会报错了
这就是修改全局的模块写声明文件json
库多数会依赖其余库,好比node.js的一些模块会依赖node原生的一些自带的内置的一些模块,好比fs或者刚才咱们用的那个Path,因此能够在定义库声明文件的时候,声明对其余库的依赖,从而加载其余库的声明,若是依赖全局的声明就用三个斜线referemce type这种形式来指定加载了某个全局库
moment是有的,他就会在这里引入全局库moment的声明文件
若是咱们依赖的是模块库,就可使用import语句。例如这里引入moment,这会把这个模块引进来。如今就能够在里面适应moment的一些东西
若是全局库依赖的是某个UMD模块,也可使用reference来引入,来指定对某个UDM模块的依赖
最后有三点要注意的地方:
1.防止命名冲突,在写全局声明的时候,在全局范围定义大量类型有时候会致使命名冲突,因此建议相关的命名放在命名空间里。命名空间很大的做用就是防止命名的污染,用的时候才用对象访问属性的方式
2.es6模块插件的影响,一些开发者为一些库开发了插件,用于在原有库的基础上,添加更多的功能,这每每须要修改原有库的导出的模块的。在讲模块的时候说过,es6模块标准中,导出的模块是不容许修改的,可是在CommenJS和其余一些加载器里是容许的。
因此要使用es6模块的话要注意这一点
3.es6模块的调用,咱们在使用一些苦的时候,导出的模块能够做为函数直接调用,在es6的模块顶层对象上是一个对象,他不能做为函数调用,好比直接用export导出几个内容,
以前在c.js里面导出了这些东西
在使用的时候,使用解构赋值的这种形式就
就能够直接打印出来引入的这个
假设要在c.js导出一个函数,在引入进来的地方呢要直接调用,就须要使用默认导出
浏览器
若是使用一个新模块,不想花时间精力为这各模块写声明,ts在2.0版本支持了快捷外部模块声明
在typings文件夹下建立moment文件夹,在下面建立index.d.ts
在这里面写声明,这样你再引入模块的时候,是没有问题的。当让咱们知道这个moment库它自身就带了声明文件,不须要再用@types去安装独立的声明文件
一些没有声明文件,又没有社区为它编写声明文件,咱们能够这样快速的导出这个模块,。这样咱们在引入的时候是没有问题的
为一些模块编写声明文件,会在后面的实战过程当中来看下实际的操做
模块化