模块(外部模块)

  1. 全局模块:在默认情况下,当开始一个新的 ts 文件中写下代码时,它处于全局命名空间中,使用全局变量空间是危险的,会有命名冲突;

    // foo.ts
    const foo = 123;
    
    // bar.ts
    const bar = foo;
    
  2. 文件模块

    1. 文件模块也被称为外部模块,如果在 ts 文件的根级别位置含有 import 或者 export ,那么它会在这个文件中创建一个本地的作用域;
    2. 模块是 TS 中外部模块的简称,侧重于代码和复用;
    3. 模块在其自身的作用域里执行,而不是在全局作用域里;
    4. 一个模块里的变量、函数、类等在外部是不可见的,除非你把它导出;
    5. 如果想要使用一个模块里导出的变量,则需要导入;
  3. 模块规范:推荐使用 CommonJSES 模块;

编译结果中的模块化对比

编译结果中的模块化是可配置的

  1. ts 里面的代码使用的 es6 的导入和导出,编译的模块化是 es6 对比如下(没有区别):

    1. 导出
    2. 导入
  2. ts 里面的代码使用的 es6 的导入和导出,编译的模块化是 commonjs 对比如下:

    1. 导出
    2. 导入

解决默认导入的错误

  1. 默认导入报错

    import fs from "fs"; 
    // 当导入 nodejs 的模块时,由于模块不是基于 ts 开发的,导出使用的是 module.export = {} ,所以会报错模块没有默认导出
    
    fs.readFileSync("./");
    
  2. 配置文件 方式解决: 配置 “esModuleInterop”: true,启用 es 的模块化标准交互非 es 模块导出;

    {
      "compilerOptions": {
        //编译选项
        "target": "es2016", // 配置编译目标代码的版本标准
        "module": "commonjs", // 配置编译目标使用的模块化标准
        "lib": ["es2016"],
        "outDir": "./dist",
        "strictNullChecks": true,
        "removeComments": true,
        "noImplicitUseStrict": true,
        "esModuleInterop": true, // 启用 es 模块化交互非 es 模块导出
        "noEmitOnError": true,
        "moduleResolution": "node"
      },
      "include": ["./src"]
    }
    
  3. 按需导入 方式解决

    import { readFileSync } from 'fs';
    readFileSync('./');
    
  4. 重命名的导入 方式解决

    import * as fs from 'fs';
    fs.readFileSync('./');
    

在 TS 中使用 commonjs 模块化

  1. 方法一:使用这种方式获取不到类型检查

  2. 方法二:这里可以获取到类型检查

  3. 方法三:方法二中使用 require,也可以获取到类型检查

TS 的模块解析

  1. 模块解析:应该从什么位置寻找模块;

  2. TS 中,有两种模块解析策略:

    1. classic:经典,已经成为过去
    2. nodenode 解析策略 (唯一的变化,是将 js 替换为 ts
      1. 相对路径 require("./xxx")
      2. 非相对模块 require("xxx")
  3. tsconfig.json 中配置 “moduleResolution”: “node” 来配置模块化标准的解析方式为 node

涉及 config.json 相关配置

{
  "compilerOptions": {
    //编译选项
    "target": "es2016", //配置编译目标代码的版本标准
    "module": "commonjs", //配置编译目标使用的模块化标准
    "lib": ["es2016"],
    "outDir": "./dist",
    "strictNullChecks": true,
    "removeComments": true, // 编译结果移除注释
    "noImplicitUseStrict": true, // 编译结果中不包含 "use strict"
    "esModuleInterop": true, // 启用es模块化交互非 es 模块导出
    "noEmitOnError": true, // 错误时不生成编译结果
    "moduleResolution": "node", // 设置解析模块的模式
  },
  "include": ["./src"]
}

案例:模块化优化扑克牌程序

TypeScript
TypeScript
TypeScript
TypeScript
// enums.ts
export enum Color {
  heart = "♥",
  spade = "♠",
  club = "♣",
  diamond = "♦"
}

export enum Mark {
  A = "A",
  two = "2",
  three = "3",
  four = "4",
  five = "5",
  six = "6",
  seven = "7",
  eight = "8",
  nine = "9",
  ten = "10",
  eleven = "J",
  twelve = "Q",
  king = "K"
}
// types.ts
import { Color, Mark } from "./enums";

export type NormalCard = {
    color: Color
    mark: Mark
};

export type Deck = NormalCard[];
// funcs.ts
import { Deck } from "./types";
import { Mark, Color } from "./enums";

export function createDeck(): Deck {
    const deck: Deck = [];
    const marks = Object.values(Mark)
    const colors = Object.values(Color)
    for (const m of marks) {
        for (const c of colors) {
            deck.push({ color: c, mark: m })
        }
    }
    return deck;
}

export function printDeck(deck: Deck) {
    let result = "\n";
    deck.forEach((card, i) => {
        let str = card.color + card.mark;
        result += str + "\t";
        if ((i + 1) % 4 === 0) {
            result += "\n";
        }
    })
    console.log(result);
}
// index.ts
import { createDeck, printDeck } from "./funcs";

const deck = createDeck();
printDeck(deck);
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 模块(外部模块)
  2. 2. 编译结果中的模块化对比
  3. 3. 解决默认导入的错误
  4. 4. 在 TS 中使用 commonjs 模块化
  5. 5. TS 的模块解析
  6. 6. 涉及 config.json 相关配置
  7. 7. 案例:模块化优化扑克牌程序