一般我们在模块化编码时,总会导入其它模块,通常我们使用如下语法:

import { A } from './a'; // ES6语法
import { A } from 'a';
var A = require('./a'); // commonjs规范

不论使用哪种语法,导入的文件一般有两种:内部文件(自己开发的)和外部(node_modules)中两种,其中导入内部模块称之为相对导入,导入node_modules中,称之为非相对导入,它们在语法上的区别就是导入的路径是否是相对的

接下来我们看看typescript和node中它们是如何解析模块的

Typescript模块解析策略

相对导入

假如b.ts路径是:/root/src/b.ts

import { A } from './a';

typescript编译器在查找a模块时会依次按照如下顺序查找,如果仍然找不到则会模块找不到的错误。

/root/src/a.ts
/root/src/a.tsx
/root/src/a.d.ts
/root/src/a/package.json (如果指定了"types"属性,则使用types中)
/root/src/a/index.ts
/root/src/a/index.tsx
/root/src/a/index.d.ts

非相对导入

假如b.ts路径是:/root/src/b.ts

import { A } from 'a';

typescript编译器在查找a模块时会按照如下顺序查找:

/root/src/node_modules/a.ts
/root/src/node_modules/a.tsx
/root/src/node_modules/a.d.ts
/root/src/node_modules/a/package.json
/root/src/node_modules/a/index.ts
/root/src/node_modules/a/index.tsx
/root/src/node_modules/a/index.d.ts /root/node_modules/a.ts
/root/node_modules/a.tsx
/root/node_modules/a.d.ts
/root/node_modules/a/package.json
/root/node_modules/a/index.ts
/root/node_modules/a/index.tsx
/root/node_modules/a/index.d.ts /node_modules/a.ts
/node_modules/a.tsx
/node_modules/a.d.ts
/node_modules/a/package.json
/node_modules/a/index.ts
/node_modules/a/index.tsx
/node_modules/a/index.d.ts

其中在上面两处空白行处,编译器会跳到上一级目录查找,直到到工程根目录

注意:有时候我们在导入外部模块(没有ts文件,只有),编译器会报模块找不到,但是我们node_modules确实有,这种方式不是编译器bug而需要我们在配置文件tsconfig.json中修改模块解析策略:

 "moduleResolution": "node"

说到这里我们看看Nodejs时如何解析模块的,NodeJs使用了commonjs模块规范,typescript编译和其大同小异。

Nodejs相对导入

假如b.ts路径是:/root/src/b.js

var A = require('./a')

typescript编译器在查找a模块时会按照如下顺序查找:

/root/src/a
/root/src/a.js
/root/src/a.json
/root/src/a/package.json (如果指定了"main"属性,则使用main中的)
/root/src/a/index.js
/root/src/a/index.json

上述第二步中,假如main:"./core/main.js",则最终模块路径:

/root/src/a/core/main.js

Nodejs非相对导入

var A = require('a')

typescript编译器在查找a模块时会按照如下顺序查找:

/root/src/node_modules/a.js
/root/src/node_modules/a/package.json (如果指定了"main"属性,则使用main中的)
/root/src/node_modules/a/index.js /root/node_modules/a.js
/root/node_modules/a/package.json (如果指定了"main"属性,则使用main中的)
/root/node_modules/a/index.js /node_modules/a.js
/node_modules/a/package.json (如果指定了"main"属性,则使用main中的)
/node_modules/a/index.js

TypeScript和Node模块解析策略的更多相关文章

  1. 使用vscode写typescript(node.js环境)起手式

    动机 一直想把typescript在服务端开发中用起来,主要原因有: javascript很灵活,但记忆力不好的话,的确会让你头疼,看着一月前自己写的代码,一脸茫然. 类型检查有利有敝,但在团队开发中 ...

  2. TypeScript 中非代码模块的导入

    需要理解的是,TypeScript 作为语言,他只处理代码模块.其他类型的文件这种非代码模块的导入,讲道理是通过另外的打包工具来完成的,比如 Web 应用中的图片,样式,JSON 还有 HTML 模板 ...

  3. TypeScript 素描 - 模块解析、声明合并

    模块解析 模块解析有两种方式 相对方式  也就是以/或 ./或-/开头的,比如import jq  from "/jq" 非相对方式  比如 import model  from ...

  4. webpack模块解析

    前面的话 在web存在多种支持JavaScript模块化的工具(如requirejs和r.js),这些工具各有优势和限制.webpack基于从这些系统获得的经验教训,并将模块的概念应用于项目中的任何文 ...

  5. node.js 解析xml BOM问题(xmlreader sax.js)

    Email:longsu2010 at yeah dot net 之前写了两篇文章关于node.js解析xml,说的是xmlreader,文章如下 node.js解析xml(xmlreader) no ...

  6. Commonjs规范及Node模块实现

    前面的话 Node在实现中并非完全按照CommonJS规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性.本文将详细介绍NodeJS的模块实现 引入 nodejs是区别于java ...

  7. 模块机制 之commonJs、node模块 、AMD、CMD

    在其他高级语言中,都有模块中这个概念,比如java的类文件,PHP有include何require机制,JS一开始就没有模块这个概念,起初,js通过<script>标签引入代码的方式显得杂 ...

  8. Python命令行选项參数解析策略

    概述 在Python的项目开发过程中,我们有时须要为程序提供一些能够通过命令行进行调用的接口.只是,并非直接使用 command + 当前文件 就ok的,我们须要对其设置可选的各种各样的操作类型.所以 ...

  9. 【转】Commonjs规范及Node模块实现

    前言: Node在实现中并非完全按照CommonJS规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性.本文将详细介绍NodeJS的模块实现 引入 nodejs是区别于javas ...

随机推荐

  1. layer遮罩层 简单的遮罩层

    在这里提供一个简单layer遮罩层,想深入了解可以进入 layer官网 多多学习哦. 先看下HTML页面代码 <!DOCTYPE html> <html lang="en& ...

  2. Apache Avro# 1.8.2 Specification (Avro 1.8.2规范)二

    h5 { text-indent: 0.71cm; margin-top: 0.49cm; margin-bottom: 0.51cm; direction: ltr; color: #000000; ...

  3. K:java中枚举的常见用法

    用法一:常量   在JDK1.5 之前,我们定义常量都是: public static fianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. ...

  4. linux shadowsocket 安装和启动

    http://blog.csdn.net/hanshileiai/article/details/49302865

  5. react看这篇就够了(react+webpack+redux+reactRouter+sass)

    本帖将对一下内容进行分享: 1.webpack环境搭建: 2.如何使用react-router: 3.引入sass预编译: 4.react 性能优化方案: 5.redux结合react使用: 6.fe ...

  6. thinkphp 中的钩子应用

    1 创建钩子行为: 我们自己定义的标签位可以直接放在Think\Behaviors中,也可以放在应用目录中,比如说Home模块下,新建一个Behaviors的文件夹,在文件夹内新建 标签名+Behav ...

  7. 面向对象 初级版 (Preview) 未完

    概述: 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数里,日后使用无需重复编写,直接调用韩顺即可. 面向对象: 对函数进行分类和封装,让开发'更快更强' 面向对象和面向过程的通 ...

  8. Ruby学习之深入类

    在讨论对象模型时,对类做了初步了解,关于类本身,还有许多知识需要学习. 类定义 Ruby中,可以用class关键字或者Class.new方法来定义一个类,在Ruby中,类定义的同时就是在运行代码,类和 ...

  9. ASP.NET MVC框架开发系列教程

    本系列教程是自己在工作中使用到而记录的,如有错误之处,请给与指正 文章目录 MVC4 开篇 第一章 初识MVC4 第二章 下山遇虎(@helper) 第三章 Models模块属性详解 第四章 在MVC ...

  10. node.js 之 Hello,World in Node !

    创建一个js文件,把下面的内容粘贴进去,命名为helloworld.js. //加载 http 模块 var http = require("http"); //创建 http 服 ...