日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Typescript学习笔记(五) 模块机制

發(fā)布時間:2025/3/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Typescript学习笔记(五) 模块机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

javascript從es5之前都缺少一種模塊機制,無法通過js引入文件,于是requirejs等等的加載器應(yīng)運而生。這些加載器的使用也并不統(tǒng)一,產(chǎn)生了amd,commonjs,umd等等的規(guī)范,各有所長,直到es6的發(fā)布,js自身引入的模塊機制,將會在以后逐漸被應(yīng)用起來。

Typescrit的模塊機制與es6的模塊基本類似,也提供了轉(zhuǎn)換為amd,es6,umd,commonjs,system的轉(zhuǎn)換,一會我們通過一個簡單的例子來運行一下ts的模塊。

ts特殊的內(nèi)聯(lián)標(biāo)簽。

/// <reference path="revence.ts" />

三個斜線,reference標(biāo)簽,path指向引入的文件,引入的文件呢,需要定義一個命名空間來引用定義的東西。

revence.ts

namespace Validation {const ac = "abc";export function a(){console.log("module be loaded");} }

定義一個名為Validation的命名空間,導(dǎo)出用export導(dǎo)出。這里Validation下的a函數(shù)被導(dǎo)出,引用的時候就可以用Validation.a()來引用它。

text.ts

/// <reference path="revence.ts" /> Validation.a();

main文件是這個text.ts,引用了revence文件。編譯器怎么編譯它呢?

兩種方法:一,把所有的輸入文件編譯為一個輸出文件,需要使用--outFile標(biāo)記:

tsc text.ts --outFile a.js

這樣輸出文件都會在a.js中,網(wǎng)頁script引入了。

    二,我們可以編譯每一個文件(默認方式),那么每個源文件都會對應(yīng)生成一個JavaScript文件。 然后,在頁面上通過<script>標(biāo)簽把所有生成的JavaScript文件按正確的順序引進來,比如:

tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts    <script src="Validation.js" type="text/javascript" /><script src="LettersOnlyValidator.js" type="text/javascript" /><script src="ZipCodeValidator.js" type="text/javascript" /><script src="Test.js" type="text/javascript" />

接下來就是ts的模塊機制,而非script加載機制了。

關(guān)鍵詞:import,export。同es6。

通過export關(guān)鍵詞導(dǎo)出,包括interface的任何東西都會被導(dǎo)出。比如

export const numberRegexp = /^[0-9]+$/; export interface StringValidator {isAcceptable(s: string): boolean; } export class ParseIntBasedZipCodeValidator {isAcceptable(s: string) {return s.length === 5 && parseInt(s).toString() === s;} }

不用關(guān)心導(dǎo)出內(nèi)容是什么,反正通過export已把這些東西都導(dǎo)出了。

1。重新導(dǎo)出。as相當(dāng)于重命名,from之后的是導(dǎo)入的地址,這相當(dāng)于從./ZipCodeValidator中把ZipCodeValidator導(dǎo)入,重命名為RegExpBasedZipCodeValidator再導(dǎo)出。記住用法即可。

// 導(dǎo)出原先的驗證器但做了重命名 export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";

2。整合導(dǎo)出。*相當(dāng)于全部導(dǎo)出。下面代碼整合了3個文件,并全部導(dǎo)出。

export * from "./StringValidator"; // exports interface StringValidator export * from "./LettersOnlyValidator"; // exports class LettersOnlyValidator export * from "./ZipCodeValidator"; // exports class ZipCodeValidator

導(dǎo)入關(guān)鍵字是import。

import基本用法

import { ZipCodeValidator } from "./ZipCodeValidator";let myValidator = new ZipCodeValidator();

這里./ZipCodeValidator導(dǎo)出的東西里面有個名字叫ZipCodeValidator的,用它的名字導(dǎo)入。這里{xxx}={123},就是這種形式,其實用到了es6的解構(gòu)賦值。不懂的轉(zhuǎn)戰(zhàn)es6。調(diào)用用其名字直接調(diào)用就可以了。

1。導(dǎo)入重命名?

import { ZipCodeValidator as ZCV } from "./ZipCodeValidator"; let myValidator = new ZCV();

?as語法,重命名為ZCV

2。導(dǎo)入全部

import * as validator from "./ZipCodeValidator"; let myValidator = new validator.ZipCodeValidator();

這里導(dǎo)入了./ZipCodeValidator文件的所有導(dǎo)出,而不是上個例子僅導(dǎo)入ZipCodeValidator。as validator相當(dāng)于給了所有導(dǎo)出一個名字,可以理解為所有導(dǎo)出的命名空間。

Tips:

盡管不推薦這么做,一些模塊會設(shè)置一些全局狀態(tài)供其它模塊使用。 這些模塊可能沒有任何的導(dǎo)出或用戶根本就不關(guān)注它的導(dǎo)出。 使用下面的方法來導(dǎo)入這類模塊:

import "./my-module.js";

3。默認導(dǎo)出。default

比如

declare let $: JQuery; export default $;

引用

import $ from "JQuery";$("button.continue").html( "Next Step..." );

default只能導(dǎo)出一項,僅導(dǎo)出一個函數(shù),或者一個接口,或者任何一個單項的東西,default是最佳實踐。因為在import的時候不指定導(dǎo)入的東西默認導(dǎo)入default。看下面這個例子

export default class ZipCodeValidator {static numberRegexp = /^[0-9]+$/;isAcceptable(s: string) {return s.length === 5 && ZipCodeValidator.numberRegexp.test(s);} } import validator from "./ZipCodeValidator";let validator = new validator();

?4。export =?和?import = require()

?TypeScript模塊支持export =語法,以配合傳統(tǒng)的CommonJS和AMD的工作流。

export =語法定義一個模塊的導(dǎo)出對象。 它可以是類,接口,命名空間,函數(shù)或枚舉。

若要導(dǎo)入一個使用了export =的模塊時,必須使用TypeScript提供的特定語法import let = require("module")。

let numberRegexp = /^[0-9]+$/; class ZipCodeValidator {isAcceptable(s: string) {return s.length === 5 && numberRegexp.test(s);} } export = ZipCodeValidator; import zip = require("./ZipCodeValidator");// Some samples to try let strings = ["Hello", "98052", "101"];// Validators to use let validator = new zip.ZipCodeValidator();// Show whether each string passed each validator strings.forEach(s => {console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`); });

5。編譯為其他模塊標(biāo)準(zhǔn)。

SimpleModule.ts
import m = require("mod"); export let t = m.something + 1;
AMD / RequireJS SimpleModule.js
define(["require", "exports", "./mod"], function (require, exports, mod_1) {exports.t = mod_1.something + 1; });

CommonJS / Node SimpleModule.js

let mod_1 = require("./mod"); exports.t = mod_1.something + 1;
UMD SimpleModule.js
(function (factory) {if (typeof module === "object" && typeof module.exports === "object") {let v = factory(require, exports); if (v !== undefined) module.exports = v;}else if (typeof define === "function" && define.amd) {define(["require", "exports", "./mod"], factory);} })(function (require, exports) {let mod_1 = require("./mod");exports.t = mod_1.something + 1; });

System SimpleModule.js

System.register(["./mod"], function(exports_1) {let mod_1;let t;return {setters:[function (mod_1_1) {mod_1 = mod_1_1;}],execute: function() {exports_1("t", t = mod_1.something + 1);}} });

Native ECMAScript 2015 modules SimpleModule.js

import { something } from "./mod"; export let t = something + 1;

命令行的命令就是加 --module或者-m加要編譯的規(guī)范名稱。比如編譯為amd

tsc text.ts -m amd

用tsc --help可以看到-m的各項參數(shù)。

高級加載

typescript的按需加載。也叫動態(tài)加載。看我博客前幾篇的webpack中,用的require.ensure做按需加載,感覺比較麻煩。然而ts的按需加載的簡單得益于它的省略引用。即:

編譯器會檢測是否每個模塊都會在生成的JavaScript中用到。 如果一個模塊標(biāo)識符只在類型注解部分使用,并且完全沒有在表達式中使用時,就不會生成require這個模塊的代碼。 省略掉沒有用到的引用對性能提升是很有益的,并同時提供了選擇性加載模塊的能力。

這種模式的核心是import id = require("...")語句可以讓我們訪問模塊導(dǎo)出的類型。 模塊加載器會被動態(tài)調(diào)用(通過require)

示例:Node.js里的動態(tài)模塊加載
declare function require(moduleName: string): any;import { ZipCodeValidator as Zip } from "./ZipCodeValidator";if (needZipValidation) {let ZipCodeValidator: typeof Zip = require("./ZipCodeValidator");let validator = new ZipCodeValidator();if (validator.isAcceptable("...")) { /* ... */ } }

示例:require.js里的動態(tài)模塊加載

declare function require(moduleNames: string[], onLoad: (...args: any[]) => void): void;import { ZipCodeValidator as Zip } from "./ZipCodeValidator";if (needZipValidation) {require(["./ZipCodeValidator"], (ZipCodeValidator: typeof Zip) => {let validator = new ZipCodeValidator();if (validator.isAcceptable("...")) { /* ... */ }}); }

只要if條件不成立,模塊是不加載的。出個簡單的例子:

text.ts

import m= require("revence"); export let t=1;;

revence.ts

export = {mod:1 }

編譯為amd模塊:根本沒有引入剛才的模塊。

define(["require", "exports"], function (require, exports) {exports.t = 1;; });

現(xiàn)在改為text.ts

import m= require("revence"); export let t=m.mod+1;;

編譯出來為

define(["require", "exports", "revence"], function (require, exports, m) {exports.t = m.mod + 1;; });

模塊加載的最佳實踐

1。盡可能地在頂層導(dǎo)出

用戶應(yīng)該更容易地使用你模塊導(dǎo)出的內(nèi)容。 嵌套層次過多會變得難以處理,因此仔細考慮一下如何組織你的代碼。

2。模塊里避免使用命名空間

模塊中使用命名空間是不必要的,在模塊中導(dǎo)出的東西肯定不能重名,而導(dǎo)入時使用者肯定會為其命名或者直接使用,也不存在重名,使用命名空間是多余的。

3。如果僅導(dǎo)出單個?class?或?function,使用?export default。

如剛才所說,default是比較好的實踐。

4。如果要導(dǎo)出多個對象,把它們放在頂層里導(dǎo)出

export class SomeType { /* ... */ } export function someFunc() { /* ... */ }

5。導(dǎo)入時明確地列出導(dǎo)入的名字

import { SomeType, SomeFunc } from "./MyThings"; let x = new SomeType(); let y = someFunc();

6。導(dǎo)入大量模塊時使用命名空間

注意是導(dǎo)入時。

export class Dog { ... } export class Cat { ... } export class Tree { ... } export class Flower { ... } import * as myLargeModule from "./MyLargeModule.ts"; let x = new myLargeModule.Dog();

7。使用重新導(dǎo)出進行擴展

你可能經(jīng)常需要去擴展一個模塊的功能。 JS里常用的一個模式是JQuery那樣去擴展原對象。 如我們之前提到的,模塊不會像全局命名空間對象那樣去合并。 推薦的方案是不要去改變原來的對象,而是導(dǎo)出一個新的實體來提供新的功能。

危險信號

以下均為模塊結(jié)構(gòu)上的危險信號。重新檢查以確保你沒有在對模塊使用命名空間:

  • 文件的頂層聲明是export namespace Foo { ... }?(刪除Foo并把所有內(nèi)容向上層移動一層)
  • 文件只有一個export class或export function?(考慮使用export default)
  • 多個文件的頂層具有同樣的export namespace Foo {?(不要以為這些會合并到一個Foo中!)

?

轉(zhuǎn)載于:https://www.cnblogs.com/dh-dh/p/5219629.html

總結(jié)

以上是生活随笔為你收集整理的Typescript学习笔记(五) 模块机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。