将 Typescript 的 baseUrl 编译器选项与节点一起使用
Using Typescript's baseUrl compiler option with node
node
的模块加载器可以支持 TS 的 baseUrl
编译器选项吗?
TS 2 引入了 baseUrl
编译器选项,以有效启用项目相关 require()
和 import
请求。
然而,这需要模块加载器支持同样的事情,因为 TS 在转译过程中实际上并不重写请求。对于像 webpack 这样的工具,这是相当简单的。
不幸的是,当使用 TS 开发 node
应用程序(即后端服务、命令行工具、电子桌面应用程序)时,似乎没有办法改变节点的模块加载器行为。
有办法吗?
是的!
感谢 TS 的立场,对于我们这些使用 node
但希望方便地使用 baseUrl
相对 require()
调用的人来说,这里有一个简单的解决方案来解决 90% 的用例大惊小怪。
此解决方案挂钩 node
的 require()
调用,并使用“main”的 dirname
模拟 baseUrl
来解析请求。因此,它假定 baseUrl
编译器选项也设置为源“main.ts”所在的同一目录。
要使用,请将这一小段代码粘贴到“main.ts”的顶部。
import * as path from 'path'
import * as fs from 'fs'
(function() {
const CH_PERIOD = 46
const baseUrl = path.dirname(process['mainModule'].filename)
const existsCache = {d:0}; delete existsCache.d
const moduleProto = Object.getPrototypeOf(module)
const origRequire = moduleProto.require
moduleProto.require = function(request) {
let existsPath = existsCache[request]
if(existsPath === undefined) {
existsPath = ''
if(!path.isAbsolute(request) && request.charCodeAt(0) !== CH_PERIOD) {
const ext = path.extname(request)
const basedRequest = path.join(baseUrl, ext ? request : request + '.js')
if(fs.existsSync(basedRequest)) existsPath = basedRequest
else {
const basedIndexRequest = path.join(baseUrl, request, 'index.js')
existsPath = fs.existsSync(basedIndexRequest) ? basedIndexRequest : ''
}
}
existsCache[request] = existsPath
}
return origRequire.call(this, existsPath || request)
}
})()
node
的模块加载器可以支持 TS 的 baseUrl
编译器选项吗?
TS 2 引入了 baseUrl
编译器选项,以有效启用项目相关 require()
和 import
请求。
然而,这需要模块加载器支持同样的事情,因为 TS 在转译过程中实际上并不重写请求。对于像 webpack 这样的工具,这是相当简单的。
不幸的是,当使用 TS 开发 node
应用程序(即后端服务、命令行工具、电子桌面应用程序)时,似乎没有办法改变节点的模块加载器行为。
有办法吗?
是的!
感谢 TS 的立场,对于我们这些使用 node
但希望方便地使用 baseUrl
相对 require()
调用的人来说,这里有一个简单的解决方案来解决 90% 的用例大惊小怪。
此解决方案挂钩 node
的 require()
调用,并使用“main”的 dirname
模拟 baseUrl
来解析请求。因此,它假定 baseUrl
编译器选项也设置为源“main.ts”所在的同一目录。
要使用,请将这一小段代码粘贴到“main.ts”的顶部。
import * as path from 'path'
import * as fs from 'fs'
(function() {
const CH_PERIOD = 46
const baseUrl = path.dirname(process['mainModule'].filename)
const existsCache = {d:0}; delete existsCache.d
const moduleProto = Object.getPrototypeOf(module)
const origRequire = moduleProto.require
moduleProto.require = function(request) {
let existsPath = existsCache[request]
if(existsPath === undefined) {
existsPath = ''
if(!path.isAbsolute(request) && request.charCodeAt(0) !== CH_PERIOD) {
const ext = path.extname(request)
const basedRequest = path.join(baseUrl, ext ? request : request + '.js')
if(fs.existsSync(basedRequest)) existsPath = basedRequest
else {
const basedIndexRequest = path.join(baseUrl, request, 'index.js')
existsPath = fs.existsSync(basedIndexRequest) ? basedIndexRequest : ''
}
}
existsCache[request] = existsPath
}
return origRequire.call(this, existsPath || request)
}
})()