简体   繁体   English

如何使用 ts-node 加载环境变量?

[英]How can I load environment variables with ts-node?

I've tried a few implementations which none have been successful.我已经尝试了一些没有成功的实现。

First Attempt第一次尝试

Using eval in package.json script "fetch:data": "eval $(cat.env) ts-node -O '{\"module\":\"commonjs\"}'./bin/build-api-data.ts" .在 package.json 脚本中使用eval "fetch:data": "eval $(cat.env) ts-node -O '{\"module\":\"commonjs\"}'./bin/build-api-data.ts"

This results in a JSON parsing error because eval is removing my quotes for some reason.这会导致 JSON 解析错误,因为 eval 出于某种原因正在删除我的引号。

undefined:1
{module:commonjs}
 ^

SyntaxError: Unexpected token m in JSON at position 1

Second Attempt第二次尝试

Using dotenv, the problem I encountered here was it was a race condition resulting in errors like this:使用 dotenv,我在这里遇到的问题是它是一个竞争条件,导致如下错误:

$ CANDID_ENV=local ts-node -O '{"module":"commonjs"}' ./bin/build-api-data.ts

/Users/lassiter.gregg/code/candidco-web/node_modules/contentful/dist/webpack:/contentful/contentful.js:49
    throw new TypeError('Expected parameter accessToken')
          ^
TypeError: Expected parameter accessToken

Code Sample代码示例

import fs from 'fs';
import path from 'path';
import fetchApiData from '../lib/apiData';
import dotEnv from 'dotenv-safe';

const { CANDID_ENV } = process.env;

const isLocalBuild = CANDID_ENV === 'local';

console.log(dotEnv);

const API_DATA_FILENAME = 'api_data.json';

const ensureDirectoryExistence = filePath => {
  var dirname = path.dirname(filePath);
  if (fs.existsSync(dirname)) {
    return true;
  }
  ensureDirectoryExistence(dirname);
  fs.mkdirSync(dirname);
};

const writeData = (filename, data) => {
  const filePath = path.join(__dirname, '..', '.data', filename);
  ensureDirectoryExistence(filePath);
  fs.writeFileSync(filePath, JSON.stringify(data));

  console.log('API data stored', filePath);
};

const fetchAndStoreApiData = async () => {
  console.log('Fetching all API data');
  await dotEnv.config({
    path: isLocalBuild ? './.env' : `./.env.${CANDID_ENV}`,
  });

  const newData = await fetchApiData();
  writeData(API_DATA_FILENAME, newData);
};

const init = async () => {
  fetchAndStoreApiData();
};

if (require.main === module) {
  init();
}

In the case above, I've tried doing dotenv.config at the top of the file, in the init, in the function as you see.在上述情况下,我尝试在文件顶部、init 中、function 中执行dotenv.config ,如您所见。 It always throws the same error about contentful not getting the env variable it needs.它总是抛出关于内容没有获得它需要的环境变量的相同错误。 That said, if I log process.env and comment out the code relevant to fetchApiData then I see all my environment variables.也就是说,如果我记录process.env并注释掉与fetchApiData相关的代码,那么我会看到我所有的环境变量。 That's why I think it's a race-time condition but haven't been able to find anything similar to my own issue.这就是为什么我认为这是一个比赛时间条件,但无法找到与我自己的问题类似的任何东西。

Additionally, what makes this even more thorny is that this is a custom script that has to work in a node and esnext environment.此外,更棘手的是,这是一个必须在 node 和 esnext 环境中工作的自定义脚本。 So, I've had my fair share of thorny import/export issues using syntax I don't really prefer but haven't found away around it (eg export = someFunction ).因此,使用我不太喜欢但还没有解决的语法(例如export = someFunction ),我遇到了相当多棘手的导入/导出问题。

Do I see it correctly, that you are trying to configure dotenv with a variable that you initialize with an env variable?我是否正确地看到它,您正在尝试使用您使用 env 变量初始化的变量配置 dotenv? I don't think that's going to work out.我认为这不会成功。 Dotenv's work is to load the env variables to process.env. Dotenv 的工作是将 env 变量加载到 process.env。 You have to config it as early as possible in your app.您必须尽早在您的应用程序中配置它。

More about it here: https://www.npmjs.com/package/dotenv更多信息在这里: https://www.npmjs.com/package/dotenv

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM