21. TypeScript 命名空间-Namespace

目录
文章目录隐藏
  1. 搭建浏览器开发环境步骤
  2. 没有命名空间时的问题
  3. 命名空间的使用
  4. 用命名空间实现组件化
  5. 多文件编译成一个文件
  6. 子命名空间
  7. 总结

以前的教程都是通过Node来运行代码的,这节为了有更好的演示效果,我们要在浏览器中运行代码。这就要求我们重新创建一个项目,直接在桌面上建立一个文件夹TSWeb

搭建浏览器开发环境步骤

如何搭建一个最基础的 TS 开发环境了:

  1. 建立好文件夹后,打开 VSCode,把文件夹拉到编辑器当中,然后打开终端,运行npm init -y,创建package.json文件。
  2. 生成文件后,我们接着在终端中运行tsc -init,生成tsconfig.json文件。
  3. 新建srcbuild文件夹,再建一个index.html文件。
  4. src目录下,新建一个page.ts文件,这就是我们要编写的ts文件了。
  5. 配置tsconfig.json文件,设置outDirrootDir(在 15 行左右),也就是设置需要编译的文件目录,和编译好的文件目录。
  6. 然后编写index.html,引入<script src="./build/page.js"></script>,当让我们现在还没有page.js文件。
  7. 编写page.ts文件,加入一句输出console.log('mybj123.com'),再在控制台输入tsc,就会生成page.js文件
  8. 再到浏览器中查看index.html文件,如果按F12可以看到mybj123.com,说明我们的搭建正常了。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./build/page.js"></script>
    <title>Document</title>
  </head>
  <body></body>
</html>

这就是你开发最基础的前端项目时需要作的环境配置。我觉的学习这东西,学会了就要用,如果不用你很快就会忘记。所以以后你在做项目,请尽量使用TypeScript来进行编写。

没有命名空间时的问题

为了你更好的理解,先写一下这样代码,用类的形式在index.html中实现headercontentFooter部分,类似我们常说的模板。

page.ts文件里,写出下面的代码:

class Header {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Header";
    document.body.appendChild(elem);
  }
}

class Content {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Content";
    document.body.appendChild(elem);
  }
}

class Footer {
  constructor() {
    const elem = document.createElement("div");
    elem.innerText = "This is Footer";
    document.body.appendChild(elem);
  }
}

class Page {
  constructor() {
    new Header();
    new Content();
    new Footer();
  }
}

写完后我们用tsc进行编译一次,然后修改index.html文件,在<body>标签里引入<script>标签,并实例化Page,代码如下:

<body>
  <script>new Page();</script>
</body>

这时候再到浏览器进行预览,就可以看到对应的页面被展现出来了。看起来没有什么问题,但是有经验的程序员就会发现,这样写全部都是全局变量(通过查看./build/page.js文件可以看出全部都是var声明的变量)。过多的全局变量会让我们代码变的不可维护。

这时候你在浏览器的控制台(Console)中,分别输入HeaderContentFooterPage都时可以拿到对应的变量的,说明他们全都是全局变量。

其实你理想的是,只要有Page这个全局变量就足够了,剩下的可以模块化封装起来,不暴露到全局。

命名空间的使用

命名空间这个语法,很类似编程中常说的模块化思想,比如webpack打包时,每个模块有自己的环境,不会污染其他模块,不会有全局变量产生。命名空间就跟这个很类似,注意这里是类似,而不是相同。

命名空间声明的关键词是namespace ,比如声明一个namespace Home,需要暴露出去的类,可以使用export关键词,这样只有暴漏出去的类是全局的,其他的不会再生成全局污染了。修改后的代码如下:

namespace Home {
  class Header {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Header";
      document.body.appendChild(elem);
    }
  }

  class Content {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Content";
      document.body.appendChild(elem);
    }
  }

  class Footer {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Footer";
      document.body.appendChild(elem);
    }
  }

  export class Page {
    constructor() {
      new Header();
      new Content();
      new Footer();
    }
  }
}

TS 代码写完后,再到index.html文件中进行修改,用命名空间的形式进行调用,就可以正常了。 写完后,记得用tsc编译一下,当然你也可以使用tsc -w进行监视了,只要有改变就会进行重新编译。

new Home.Page();

现在再到浏览器中进行查看,可以看到现在就只有Home.Page是在控制台可以得到的,其他的Home.Header…这些都是得不到的,说明只有Home.Page是全局的,其他的都是模块化私有的。

这就是 TypeScript 给我们提供的类似模块化开发的语法,它的好处就是让全局变量减少了很多,实现了基本的封装,减少了全局变量的污染。

接下来我们再深入学习命名空间-Namespace。

用命名空间实现组件化

上节的代码虽实现了模块化和全局变量的污染,但是我们工作中分的要更细致一些,会单独写一个components的文件,然后进行组件化。

src目录下新建一个文件components.ts,编写代码如下:

namespace Components {
  export class Header {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Header";
      document.body.appendChild(elem);
    }
  }

  export class Content {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Content";
      document.body.appendChild(elem);
    }
  }

  export class Footer {
    constructor() {
      const elem = document.createElement("div");
      elem.innerText = "This is Footer";
      document.body.appendChild(elem);
    }
  }
}

这里需要注意的是,我每个类(class)都使用了export导出,导出后就可以在page.ts中使用这些组件了。比如这样使用,代码如下。

namespace Home {
  export class Page {
    constructor() {
      new Components.Header();
      new Components.Content();
      new Components.Footer();
    }
  }
}

这时候你可以使用tsc进行重新编译,但在预览时,你会发现还是会报错,找不到Components,想解决这个问题,我们必须要在index.html里进行引入components.js文件。

<script src="./build/page.js"></script>
<script src="./build/components.js"></script>

这样才可以正常的出现效果。但这样引入太麻烦了,可不可以像webpack一样,只生成一个文件呢?那答案是肯定的。

多文件编译成一个文件

直接打开tsconfig.json文件,然后找到outFile配置项,这个就是用来生成一个文件的设置,但是如果设置了它,就不再支持"module":"commonjs"设置了,我们需要把它改成"module":"amd",然后在去掉对应的outFile注释,设置成下面的样子。

{
  "outFile": "./build/page.js"
}

配置好后,删除掉build下的js文件,然后用tsc进行再次编译。

然后删掉index.html文件中的component.js,在浏览器里还是可以正常运行的。

子命名空间

也就是说在命名空间里,再写一个命名空间,比如在Components.ts文件下修改代码如下。

namespace Components {
  export namespace SubComponents {
    export class Test {}
  }

  //someting ...
}

写完后在控制台再次编辑tsc,然后你在浏览器中也是可以查到这个命名空间的Components.SubComponents.Test(需要刷新页面后才会显示)。

总结

以上就是今天我们要学的 TypeScript 命名空间的内容,基本讲完了,在工作中如果遇到,这些知识已经完全够用,所以这部分内容就先到这里了。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 21. TypeScript 命名空间-Namespace

发表回复