记一次JSON和ts-node的坑

2022-10-24 16:20:43 浏览数 (1)

首先列出目录结构:

代码语言:javascript复制
example/
 config.ts
 config.json
 app.ts

config.ts

代码语言:javascript复制
import fs from 'fs'

const conf = JSON.parse(fs.readFileSync('config.json', 'utf-8'))

export const foo = conf.foo

config.json

代码语言:javascript复制
{
    "foo": true
}

app.ts

代码语言:javascript复制
import { foo } from './config'

console.log('Foo is', foo)

此时运行ts-node app.ts不会有任何问题。

问题复现

现在我有一个新的需求,需要我第一次运行希望foo这个属性是true,然后把它修改成false,把foo这个字段当作初始化的标志。

于是把下面这段代码加到config.ts里面:

代码语言:javascript复制
export function resetFoo() {
    if (foo) {
        conf.foo = false
        fs.writeFileSync('config.json', JSON.stringify(conf))
    }
}

然后在app.ts里面加入下面这行代码:

代码语言:javascript复制
import { resetFoo } from './config'

resetFoo()
// TypeError: (0 , config_1.resetFoo) is not a function

那么我的第一反应是看一下resetFoo是个什么东西,就在app.ts出错的那句话上面加上了:

代码语言:javascript复制
console.log('ResetFoo is', resetFoo)
// ResetFoo is undefined

解决方案

我在Stack Overflow上面查到的是这里。

长话短说,这个问题的根本原因在于app.ts的第一行:

代码语言:javascript复制
import { foo, resetFoo } from './config'

它导入的其实是config.json,和我们写的ts没有半毛钱关系。

话是这样说,但是如何验证呢? 只需要把整个config.ts内容清空,只留下一句:

代码语言:javascript复制
export const foo = 'THIS IS NOT JSON FILE!'

然后把app.ts改成:

代码语言:javascript复制
import { foo } from './config'

console.log('Foo is', foo)
// Foo is true

所以说解决方案就很明显了:把config.ts改名。由于这个操作过于简单这里就不演示了。

后记

虽然它能给我出bug,但是如果没了config.ts我还不能直接导入JSON文件,需要在tsconfig.jsoncompilerOptions里面加上一句:

代码语言:javascript复制
"resolveJsonModule": true

然后引入的时候需要这样引:

代码语言:javascript复制
import config from './config.json'
// or
import { foo } from './config.json'

0 人点赞