相对导入是以/,./或../开头的。 下面是一些例子:
- import Entry from "./components/Entry";
- import { DefaultHeaders } from "../constants/http";
- import "/mod";
所有其它形式的导入被当作非相对的。 下面是一些例子:
- import * as $ from "jQuery";
- import { Component } from "@angular/core";
也就是说我的问题是想把import 'jquery'
编译后成为import jquery from './xxx/xxx/jquery'
配置文件
{
"compilerOptions": {
"module": "commonjs",
"target": "ES6",
"outDir": "../dist",
"sourceMap": true,
"lib": [
"dom",
"es2015",
],
"typeRoots": [
"../node_modules/@types"
],
"baseUrl": "../",
"paths": {
"request":["node_modules/request/request.js"]
}
},
"files": [
"../test/test.ts"
]
}
目录结构
-
config 保存tsconfig.json的文件夹
- tsconfig.json
- dist 输出编译结果的目录
-
node_modules node模块文件夹
-
@types TypeScript声明文件
- request 保存request的声明文件夹
- request request本体文件夹
-
-
test 测试使用的文件
- test.ts 等待编译的文件
问题说明
假设我当前的项目路径在/
下.
在/test/test.ts
中有如下的内容.
import * as request from 'request'
console.log(request);
在/
路径下我使用如下命令编译:
tsc -p ./config/tsconfig.json
在/dist
下输出:
- test.js
- test.js.map
我们看一下test.js的内容:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const request = require("request");
console.log(request);
//# sourceMappingURL=test.js.map
那么问题来了如果我们是在Node中运行,根据node的加载规则,实际上是可以被加载的.
但是我希望编译的时候最终的路径是相对路径require('../node_modules/request/request.js')
,而不是一个request
.
在上面的tsconfig.json
中,我尝试使用了baseUrl
和paths
属性,但是他们没有预期的工作,是我理解错误,还是操作的方式错误.
问题核心
完整的相对导入在typescript编译后的路径不会随着
outDir
输出的目录而修改.编译成javascript:
这本身没有问题,但是考虑如下的目录结构,我们这句引入放到了index.js中:
但是我们设置了输出目录在dist文件夹中,最后输出的结果:
但是index.js在执行的时候就会报错
const abc = require('./node_modules/xxx/dist/xxx.min.js');
无法解析到指定的文件,因为dist目录下没有node_modules
目录.解决方式
实际上非常简单,是我们忘记了node的和typescript的解析规则.
我们编写的ts代码无非两种:
在node中第三方模块统统放到了
node_modules
目录下,而node在运行的时候会根据名称来进行匹配node_modules
目录,会从当前路径一直向上查找node_modules
目录然后进入进行匹配.而typescript是可以解析node模块的,解析规则和node一致.
所以我们根本不需要写完整的引入,写相对的就可以了.
对于我们的问题,例如我们要引入多个jquery中的压缩版本,我们完全可以不以当前的路径为起点:
typescript会自动进行查找,在node执行的时候也会正确的解析到模块.
拓展
我们自己编写的第三方模块该如何处理.
最方便的就是直接上传到npm了,但是你还有其他选择.
利用package.json文件就可以了在package.json中存在的依赖会向当前的
node_modules
目录中进行查找,npm可以从git仓库中安装模块,例如我编写了一个myjquery的模块上传到github,在安装这个模块后在package.json中就可能如下显示:使用npm安装模块的时候执行:
最后:
你甚至可以直接在
node_modules
文件夹中填入你的模块,然后在package.json中写入对应的目录名称,然后给他一个假的版本号,这也可以运行.直接名称和填入对应的是可以运行并且解析的,但是npm在每次安装包或者更新的时候都会进行检查,此时就会移除我们手动填入的模块.