告诉typescript编译json文件

ahe*_*rve 11 json typescript

使用时导入json文件时,typescript编译器工作正常

const tasks = require('./tasks.json')
Run Code Online (Sandbox Code Playgroud)

但是,当我运行时tsc,输出目录不包含任何tasks.json文件,从而导致运行时错误.

有没有办法告诉编译器应该复制所有json文件,还是应该手动将所有json文件复制/粘贴到dist目录中?

我的tsc compilerOptions目前正在读取

  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "sourceMap": true,
    "noImplicitAny": true,
    "removeComments": false,
    "outDir": "./dist/",
    "sourceMap": true,
    "pretty": true,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "sourceMap": true
  },
Run Code Online (Sandbox Code Playgroud)

谢谢 !

joe*_*dle 41

问题

对于想要复制所有JSON 文件的人来说,在 TypeScript 中真的很难。即使有"resolveJsonModule": truetsc只会复制.json这些文件直接引用的一个import

下面是一些想要执行动态运行时的示例代码require()。这只有在所有 JSON 文件都已复制到dist/文件夹中时才有效,而文件夹tsc 拒绝这样做。

// Works
import * as config from './config.default.json';

const env = process.env.NODE_ENV || 'development';

const envConfigFile = `./config.${env}.json`;

if (fs.existsSync(envConfigFile)) {
  // Does not work
  const envConfig = require(envConfigFile);
  Object.assign(config, envConfig);
}
Run Code Online (Sandbox Code Playgroud)

解决方案 1:将 json 文件保留在 src 树之外(推荐)

假设您有/src//dist/文件夹,您可以将 JSON 文件保存在项目的/文件夹中。然后位于 的脚本/src/config/load-config.ts可以在运行时执行此操作:

const envConfig = require(`../../config.${env}.json`);

// Or you could read manually without using require
const envConfigFile = path.join(__dirname, '..', '..', `config.${env}.json`);
const envConfig = JSON.parse(fs.readFileSync(envConfigFile, 'utf-8'));
Run Code Online (Sandbox Code Playgroud)

这是最简单的解决方案。您只需要确保必要的配置文件在生产环境中就位。

其余的解决方案将处理您确实希望将配置文件保留在文件src/夹中并将它们显示在dist/文件夹中的情况。

解决方案 2:导入所有可能的文件

对于上面的例子,我们可以这样做:

import * as config from './config.default.json';
import * as testingConfig from './config.testing.json';
import * as stagingConfig from './config.staging.json';
import * as productionConfig from './config.production.json';
Run Code Online (Sandbox Code Playgroud)

这应该会导致指定的 json 文件被复制到dist/文件夹中,所以我们require()现在应该可以工作了。

缺点:如果有人想要添加一个新.json文件,那么他们还必须添加一个新的导入行。

方案三:单独复制json文件(推荐)

完成后,您可以在构建过程中添加cpy-clicopyfiles步骤将所有.json文件复制到dist/文件夹tsc中。

这假设您使用npm run build或类似的东西进行构建。

例如:

$ npm install --save-dev cpy-cli

// To copy just the json files, add this to package.json
"postbuild": "cpy --cwd=src --parents '**/*.json' ../dist/",

// Or to copy everything except TypeScript files
"postbuild": "cpy --cwd=src --parents '**/*' '!**/*.ts' ../dist/",
Run Code Online (Sandbox Code Playgroud)

现在npm run build应该运行tsc,然后运行cpy

缺点:它需要额外的devDependency. 您必须将这部分作为构建过程的一部分。

解决方案 4:使用 js 文件而不是 json 文件

或者,不要使用.json文件。.js改为将它们移动到文件中,并"allowJs": true在您的tsconfig.json. 然后tsc将为您复制文件。

您的新.js文件需要如下所示:module.exports = { ... };

我发现这里推荐的这个想法。

注意:为了启用"allowJs": true您可能需要添加"esModuleInterop": true"declaration": false,甚至可能需要添加"skipLibCheck": true。这取决于您现有的设置。

还有一个问题(抱歉我没有测试过):

  • tsc如果您的配置文件不是全部​​被其他文件静态引用,是否会转译您的配置文件?您的文件或文件夹,它们可能需要将在明确提到filesinclude您的选择tsconfig.json

解决方案 5:使用 ts 文件而不是 json 文件

听起来很简单,但仍有一些问题需要考虑:

  • 你的配置文件现在看起来像这样: const config = { ... }; export default config;

  • 请参阅上面关于files/include选项的说明。

  • 如果您在运行时动态加载配置文件,请不要忘记它们将被转换为.js文件。所以不要去尝试require() .ts文件,因为它们不会在那里!

  • 如果有人想更改配置文件,他们应该进行全新的tsc构建。他们可以破解.js文件dist夹中的转译文件,但应该避免这种情况,因为这些更改可能会被未来的构建覆盖。

测试

当这个实验,请一定要清楚你的dist/文件夹,并tsconfig.tsbuildinfo建立之间的文件,以正确测试的过程。

tsc并不总是清理dist/文件夹,有时它只是向其中添加新文件。因此,如果您不删除它们,早期实验留下的旧文件可能会产生误导性结果!)


Jer*_*Joy 25

在 tsconfig.json 中,添加

{
  "compilerOptions": {
     "resolveJsonModule": true,
   },
   "include": [
     "src/config/*.json"
  ]
}
Run Code Online (Sandbox Code Playgroud)

请注意,它不会复制那些d 的json文件require。如果您需要动态地要求某些json文件并需要将它们复制到dist,那么您需要从,例如,

return require("some.json") as YourType
Run Code Online (Sandbox Code Playgroud)

return (await import("some.json")) as YourType
Run Code Online (Sandbox Code Playgroud)

.


Fır*_*ÇÜK 8

在2.9以上的打字稿中,您可以直接使用JSON文件,并将其自动复制到dist目录。

这是tsconfig.json最少需要的配置:

{
    "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "esModuleInterop"             : true,
        "module"                      : "commonjs",
        "outDir"                      : "./dist",
        "resolveJsonModule"           : true,
        "target"                      : "es6"
    },
    "exclude"        : [
        "node_modules"
    ]
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建一个json文件。

{
    "address": "127.0.0.1",
    "port"   : 8080
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

import config from './config.json';

class Main {

    public someMethod(): void {
        console.log(config.port);
    }
}

new Main().someMethod();
Run Code Online (Sandbox Code Playgroud)

如果不使用esModuleInterop属性,则应访问封装在默认字段中的json属性。config.default.port

  • 请注意,`"resolveJsonModule": true`仅复制`导入`的json文件。它不会复制_所有_ json 文件或“必需”的 json 文件。 (3认同)