TS+webpack配置

727 阅读4分钟

Typescript

Typescript入门

安装tsc npm i -g typescript

1.创建一个ts文件

2.使用tsc对ts文件进行编译

进入命令行

进入ts文件所在目录

执行命令 tsc xxx.ts

基础类型

数据类型关键字描述
任意类型any声明为 any 的变量可以赋予任意类型的值。
数字类型number双精度 64 位浮点值。它可以用来表示整数和分数。let binaryLiteral: number = 0b1010; // 二进制 let octalLiteral: number = 0o744; // 八进制 let decLiteral: number = 6; // 十进制 let hexLiteral: number = 0xf00d; // 十六进制
字符串类型string一个字符系列,使用单引号( ' )或双引号( " )来表示字符串类型。反引号(****)来定义多行文本和内嵌表达式。let name: string = "Runoob"; let years: number = 5; let words: string = 您好,今年是 ${ name } 发布 ${ years + 1} 周年;`
布尔类型boolean表示逻辑值:true 和 false。let flag: boolean = true;
数组类型声明变量为数组。// 在元素类型后面加上[] let arr: number[] = [1, 2]; // 或者使用数组泛型 let arr: Array<number> = [1, 2];
元组元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。let x: [string, number]; x = ['Runoob', 1]; // 运行正常 x = [1, 'Runoob']; // 报错 console.log(x[0]); // 输出 Runoob
枚举enum枚举类型用于定义数值集合。enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 输出 2
voidvoid用于标识方法返回值的类型,表示该方法没有返回值。function hello(): void { alert("Hello Runoob"); }
nullnull表示对象值缺失。
undefinedundefined用于初始化变量为一个未定义的值
nevernevernever 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

##### 类型断言

let m = n as string
let m = <string>n
对象
let a: object;
let b = {name: string, [propName: string]: any}
b = {name: 'lihua', gender: 'male', age: 18}
函数类型声明
let d : (a: number, b: number ) => number;
d = function(a, b):number {
    return a + b
}

编译选项

自动编译文件

编译文件时,使用-W指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译

tsc XXX.ts -W

创建tsconfig.json文件:ts编译器的配置文件

tsc --init // 自动生成tsconfig.json文件
{
    //include用来指定哪些文件需要被编译,exclude不被编译的文件
    "include": [
        "./src/**/*" //任意目录下的任意文件
    ],
    //extends表示被继承的配置文件,相当于引入其他的.json文件
    //files指出需要编译的文件
    //compilerOptions中包含多个子选项,完成编译相关的配置
    compilerOptions: {
        "target": "ES3", //用于指定TS被编译为ES的版本es3\es5\es6\es2015\es2016\es2017\es2020\esnext
        //module 指定要使用的模块化的规范
        "module": "ES2015",
        "lib": [], //用来指定项目中需要使用的库
        "outDir": "./dist/app.js", //指定编译后文件所在的目录,此处是合并到打包文件的app.js文件
        "allowJs": true, //是否对js文件进行编译,默认为false
        "checkJs": false, //是否对js文件语法进行编译,默认为false
        "removeComments": false, //是否移除注释,默认为false
        "noEmit": false, //不生成编译后的文件,默认为false
        "noEmitOnError": true, //当有错误时不生成编译后的文件,默认为false
        "alwaysStrict": true, //用来设置编译后的文件始终使用严格模式,默认为false
        //js文件有模块的导入导出将自动进入严格模式
        "noImplicitAny": true, //不允许隐式的any类型,默认为false
        "noImplicitThis": true, //不允许不明确类型的this,默认为false
        "strictNullChecks": true, //严格检查空值,默认为false
        "strict": true, //所有严格检查的总开关,默认为false
    }
}
使用webpack打包ts代码

npm init -y //生成package.json配置文件

创建并配置webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
    mode: "development",
    entry: './src/index.ts',
    output: {
        path:path.resolve(__dirname, './dist'),
        filename: "bundle.js",
        // 通知webpack不使用箭头函数
        environment: {
            arrowFunction: false // 用于兼容IE
        }
    },
    //配置webpack打包时的模块
    module: {
        //指定加载时的规则
        rules: [
            {
                //test指定规则生效的文件
                test: /.ts$/,
                use: [
                    //配置babel(相关知识点在后面)
                    {
                        //指定加载器
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    // 指定环境的插件
                                    "@babel/preset-env", 
                                    // 配置信息
                                    {
                                        // 要兼容的目标浏览器
                                        targets: {
                                            "chrome": "88"
                                        },
                                        //指定corejs的版本
                                        "corejs": "3",
                                        //使用corejs的方式 "usage"表示按需加载
                                        "useBuiltIns": "usage"
                                    }
                                ]
                            ]
                        }
                    },
                    'ts-loader'
                ], // 执行顺序是从后往前
                //排除的文件
                exclude: /node_modules/
            }
        ]
    },
    //配置webpack插件
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            //title: "",
            template: './src/index.html'
        })
    ],
}

package.json中添加以下代码,通过npm run build运行webpack

"build": "webpack"

\ webpack插件:

npm i -D webpack-dev-server

package.json中添加以下代码,通过npm run start运行webpack

"start": "webpack serve --open chrome.exe"

配置完成后开发实时更新

插件:clean-webpack-plugin 清理dist文件目录

npm i -D clean-webpack-plugin

在webpack.config.js文件中配置plugins对象数组中添加new CleanWebpackPlugin()

webpack.config.js文件中新的配置项,通过resolve设置引用模块

resolve: {
    extensions: ['.ts','.js']
}
Babel转换器

作用:新语法转换为旧语法,提高代码兼容性

npm i -D @babel/core @babel/preset-env babel-loader core-js

#### 面向对象

class Person {
    name: string = "孙悟空";
    static age: number = 18;
}
const p = new Person();

在属性前使用static关键字可以定义类属性(静态属性),通过Person.age进行访问

在属性前使用readonly可以将属性设置为只读属性

构造函数和this
class dog(){
    // 构造函数会在对象创建时调用
    constructor(name: string, age: number){
        // 在实例方法中this表示当前的实例
        // 在构造方法中当前对象就是当前新建的那个对象
        // 可以通过this像新建的对象中添加属性
        this.name = name;
        this.age = age;
    }
}
继承
class Animal(){
    // 构造函数会在对象创建时调用
    constructor(name: string, age: number){
        // 在实例方法中this表示当前的实例
        // 在构造方法中当前对象就是当前新建的那个对象
        // 可以通过this像新建的对象中添加属性
        this.name = name;
        this.age = age;
        sayHello() {
            console.log("叫");
        }
    }
}
class dog extends Animal{}

重写:在子类中添加父类的同名方法,会覆盖掉继承过来的方法

super关键字

在类的方法中表示当前类的父类

如果在子类中写了构造函数,则必须在其中对父类构造函数进行调用

class Animal(){
    // 构造函数会在对象创建时调用
    constructor(name: string, age: number){
        // 在实例方法中this表示当前的实例
        // 在构造方法中当前对象就是当前新建的那个对象
        // 可以通过this像新建的对象中添加属性
        this.name = name;
        this.age = age;
        sayHello() {
            console.log("叫");
        }
    }
}
class dog extends Animal{
    age: number;
    constructor(name: string, age: number) {
        // 表示对父类构造函数的调用
        super(name);
        this.age = age;
    }
}
抽象类

以abstract开头的类是抽象类,抽象类与其他类区别不大,只是不能创建对象。

抽象类是专门被继承的类。

抽象类中可以添加抽象方法

abstract class Animal(){
    // 构造函数会在对象创建时调用
    constructor(name: string, age: number){
        // 在实例方法中this表示当前的实例
        // 在构造方法中当前对象就是当前新建的那个对象
        // 可以通过this像新建的对象中添加属性
        this.name = name;
        this.age = age;
        // 定义抽象方法,抽象方法只能定义在抽象类中,没有方法体
        //继承该抽象类的子类必须声明该抽象类的方法体
        abstract sayHello(): void;
        }
    }
}
接口

接口可以在定义类的时候限制类的结构

接口中的所有属性都不能有实际的值

接口只定义对象的结构,而不考虑实际的值,接口中的所有方法都是抽象方法

interface myInter{
    name: string;
    sayHello(): void;
}
// 实现接口就是使类满足接口的要求
class MyClass implements myInter {
    name: string;
    
    constructor (name: string) {
        this.name = name
    }
    
    sayHello() {
        console.log("hello!!!");
    }
}
属性的封装

目前属性是在对象中设置的,属性可以被任意修改,会导致一些列问题

作用:对属性进行封装,使属性更加安全,避免随意修改带来的问题

ts可以在属性前添加属性的修饰符

public修饰的属性可以在任意位置修改默认值

private私有属性只能在类内部进行访问修改

可以通过在类内部添加方法使私有属性可以被外部访问修改

class Animal(){
    private name: string;
    private age: number;
    
    // 构造函数会在对象创建(new)时调用
    constructor(name: string, age: number){
        // 在实例方法中this表示当前的实例
        // 在构造方法中当前对象就是当前新建的那个对象
        // 可以通过this像新建的对象中添加属性
        this.name = name;
        this.age = age;
    }
    get name() {
        return this.name;
    }
    set name(value: string) {
        this.name = value;
    }
}

protected修饰符:受保护的属性,只能在当前类和当前类的子类中访问(修改)

class test{
    constructor(public name: string, public age: number) {}
}

泛型

在定义函数或者类时,遇到类型不明确就可以使用泛型

function fn<T>(a: T): T{
    return a;
}

优点:不像any一样会将ts的类型检查关闭

// 可以直接调用具有泛型的函数
let result = fn(a:10);// 不指定泛型,ts可以自动对类型进行判断
let result2 =  fn<string>(a: 'hello');// 指定泛型类型为string
// 泛型可以同时指定多个
function fn2<T, K>(a: T, b: K): T{
    console.log(b);
    return a;
}
fn2<number, string>(a: 123, b: "hello")
​
interface Inter{
    length: number;
}
// 泛型T必须是Inter实现类(子类)
function fn3<T extends Inter>(a: T): number{
    return a.length;
}
fn3(a: '123');// 可行class MyClass<T>{
    name: T;
    construcotor(name: T){
        this.name = name;
    }
}
const mc = new MyClass<string>(name: '孙悟空');

## 练习

项目搭建

package.json、tsconfig.json、webpack.config.js三个配置文件

tsc --init // 自动生成tsconfig.json文件

npm init -y //生成package.json配置文件

webpack.config.js文件需要自行创建并行相关配置

运行指令安装相关loader:

npm i -D less less-loader css-loader style-loader
npm i -D postcss postcss-loader postcss-preset-env

postcss使预处理语言的新语法兼容旧语法

// 在webpack.config.js文件中设置less相关配置
{
test: /.less$/,
use: [ // 这部分加载规则是从后向前加载的
  "style-loader",
  "css-loader",
  // 引入postcss
  {
    loader: "postcss-loader",
    options: {
      postcssOptions: {
        plugins: [
          [
            "postcss-preset-env",
            {
              browsers: "last 2 versions"
            }
          ]
        ]
      }
    }
  },
  "less-loader"
  ]
}

\