Wsh's blog Wsh's blog
首页
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)

wsh

热爱前端的程序媛
首页
  • 基础知识
  • ArkUI
  • UIAbility
  • 组件通信方式
  • 前端缓存
  • React
  • typescript
  • javascript
  • flutter
  • node
  • webpack
web3D😉
宝库📰
  • 分类
  • 标签
  • 归档
龙哥的大🐂之路 (opens new window)
GitHub (opens new window)
  • 基础类型
  • 类型断言、类型声明
  • 枚举、函数、类、装饰器
  • 联合类型&交叉类型、泛型、类型保护、类型推断
  • 模块、命名空间
    • tsc 指令,ts配置
    • typescript
    2022-04-14
    目录

    模块、命名空间

    几种模块方式:

    • ES模块:ES模块是ECMAScript2015(ES6)语言规范的一部分,每一个(包含export/import的)JavaScript文件都是一个模块,在模块中定义的变量的作用域被限制在了文件中。

    babel 转 ES Module 例子:

    import Select from './Select';
    import Option from './Option';
    import OptGroup from './OptGroup';
    export { Option, OptGroup };
    

    转换后:

    var _Select = _interopRequireDefault(require("./Select"));
    var _Option = _interopRequireDefault(require("./Option"));
    var _OptGroup = _interopRequireDefault(require("./OptGroup"));
    var _default = _Select.default;
    exports.default = _default;
    
    • CommonJS:在JavaScript只能编写网页应用的时候,CommonJS提供了一些API,能够让JavaScript编写不同的JavaScript解释器和主机运行环境的程序。CommonJS一般用于服务端(Node.js)。CommonJS的一个模块就是一个脚本文件。require 命令第一次加载该脚本时,就会执行整个脚本,然后在内存中生成一个对象。
    {
      id: '...', // 模块名
      exports: { ... }, // 该模块导出的接口
      loaded: true, // 表示模块是否加载完毕
      ...
    }
    // 需要用到这个模块时,就会到exports属性上取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存中取值
    

    CommonJS是同步加载模块,所有的模块都放在本地硬盘。等待模块时间就是硬盘读取文件时间,很小。对于浏览器而言,它需要从服务器加载模块,涉及到网速,代理等原因,一旦等待时间过长,浏览器处于”假死”状态,所以不适合浏览器使用。

    exports.add = function(a, b) {
      return a + b;
    }
    
    var math = require('math');
    math.add(2, 3); // 5
    
    • AMD:全称:Asynchronous Module Definition,即“异步模块定义”,采用异步方式加载模块,模块的加载不影响它后面语句的运行。这里异步指的是不堵塞浏览器其他任务(dom构建,css渲染等),而加载内部是同步的(加载完模块后立即执行回调)。AMD采用require命令加载模块,但是不同于CommonJS,它要求两个参数:
    require([module], callback);
    
    • callback: 回调函数中参数对应数组中的成员(模块)
    require(['math'], function(math) {
      math.add(2, 3);
    })
    

    模块书写必须使用特定的define()函数来定义

    define(function() {
      var add = function(x, y) {
        return x + y;
      }
    
      return  {
        add: add
      }
    })
    
    加载方式: 
    
    

    require(['math'], function(math) { alert(math.add(1, 1)); })

    • UMD:(Universal Module Definition 通用模块定义)是一种模式,提供对当今最流行的脚本加载器的兼容。UMD主要支持的是AMD和CommonJS
    (function (root, factory) {
        if (typeof define === 'function' && define.amd) {
            // AMD
            define(['jquery', 'underscore'], factory);
        } else if (typeof exports === 'object') {
            // Node, CommonJS之类的
            module.exports = factory(require('jquery'), require('underscore'));
        } else {
            // 浏览器全局变量(root 即 window)
            root.returnExports = factory(root.jQuery, root._);
        }
    
    }(this, function ($, _) {
        // 方法
        function a(){}; // 私有方法,因为它没被返回 (见下面)
        function b(){}; // 公共方法,因为被返回了
        function c(){}; // 公共方法,因为被返回了
        // 暴露公共方法
        return {
            b: b,
            c: c
        }
    }));
    
    • SystemJS:

    SystemJS是可配置的模块加载器。使用System.register方法注册模块,使用System.import方法导入模块。

    System.register(["./mod"], function (exports_1) {
      var mod_1;
      var t;
      return {
        setters: [
          function (mod_1_1) {
            mod_1 = mod_1_1;
          },
        ],
        execute: function () {
          exports_1("t", (t = mod_1.something + 1));
        },
      };
    });
    
    declare const System: any;
    import { ZipCodeValidator as Zip } from "./ZipCodeValidator";
    if (needZipValidation) {
      System.import("./ZipCodeValidator").then((ZipCodeValidator: typeof Zip) => {
        var x = new ZipCodeValidator();
        if (x.isAcceptable("...")) {
          /* ... */
        }
      });
    }
    

    # 普通模块

    TypeScript模块和ES模块基本一样,只是它可以导出ES模块中没有的一些东西,比如类型别名和接口

    # 环境模块

    环境模块和普通模块不同,环境模块中声明的内容是全局的,环境模块(以及环境命名空间)的声明都不能使用export导出,也不能使用任何import ...语句,否则环境模块就会失效。根据这个问答,可以使用import()方法动态地在环境模块中导入其他模块。

    declare一般用于声明外部模块

    # 通配符模块声明

    在TS中没有办法使用非代码资源,例如图片、视频等

    declare moudle "*.png";
    

    # 命名空间

    • 直接使用时,注意会报错:命名空间没有被标记为仅声明类型。 非声明性命名空间仅在Babel中实验支持。所以我们需要安装一个插件:@babel/plugin-transform-typescript。

    在.babelrc.js 加上

    module.exports = {
      plugins: [
        ["@babel/plugin-transform-typescript", {"allowNamespaces": true}] // allowNamespaces表示允许使用命名空间。
      ],
    };
    
    • eslint 报错: ES2015 module syntax is preferred over custom TypeScript modules and namespaces @typescript-eslint/no-namespace

    在.eslintrc.js 关掉类型检查

    rules: {
      '@typescript-eslint/no-namespace': 'off'
    },
    

    # 三斜杠指令

    • 三斜杠指令是包含单个 XML 标记的单行注释。注释的内容用作编译器指令
    • 三斜杠指令仅在其包含文件的顶部有效。三斜杠指令前只能有单行或多行注释,包括其他三斜杠指令。如果在语句或声明之后遇到它们,它们将被视为常规单行注释,并且没有特殊含义
    • 作用:用作文件之间依赖关系的声明,跨文件进行分割
    • 注意:需要关掉检查'@typescript-eslint/triple-slash-reference': 'off'
    /// <reference path="..." />
    
    #typescript
    联合类型&交叉类型、泛型、类型保护、类型推断
    tsc 指令,ts配置

    ← 联合类型&交叉类型、泛型、类型保护、类型推断 tsc 指令,ts配置→

    最近更新
    01
    组件通信方式
    01-07
    02
    UIAbility
    01-07
    03
    ATKTS
    01-06
    更多文章>
    Theme by Vdoing | Copyright © 2022-2025 Wsh | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式