Typescript 使用Jest测试时如何使用'import.meta'

Typescript 使用Jest测试时如何使用'import.meta',typescript,jestjs,babeljs,Typescript,Jestjs,Babeljs,我正在使用ESModules编写Node.js代码(在TypeScript中),我需要访问\uu dirname。为了访问CommonJS中与\uu dirname等效的ESM,我调用dirname(fileURLToPath(import.meta.url))。我也在用TypeScript开玩笑地写测试。使用指南,我建立了巴贝尔。当我运行jest命令时,我得到 const DIRNAME = (0, _path.dirname)((0, _url.fileURLToPath)(import.m

我正在使用ESModules编写Node.js代码(在TypeScript中),我需要访问
\uu dirname
。为了访问CommonJS中与
\uu dirname
等效的ESM,我调用
dirname(fileURLToPath(import.meta.url))
。我也在用TypeScript开玩笑地写测试。使用指南,我建立了巴贝尔。当我运行
jest
命令时,我得到

const DIRNAME = (0, _path.dirname)((0, _url.fileURLToPath)(import.meta.url));
                                                                      ^^^^
SyntaxError: Cannot use 'import.meta' outside a module
这是我写的文件

someCode.ts

someCode.test.ts

.babelrc.json

tsconfig.json:

package.json

环境:

  • 节点:14.1.0
  • 有关模块版本,请参见
    package.json

我也遇到了同样的问题,我用巴别塔插件解决了这个问题:

在我的代码中,我用
import\u meta\u url

我将插件添加到babel配置中,通过开发和生产中的
import.meta.url
resolve(\uu dirname,'workers')

我之所以能够这样做,是因为它匹配了我的所有案例,例如,如果在不同的场景中,您的
import\u meta\u url
需要用不同的Sting替换,那么您需要使用
import\u meta\u url\u 1
import\u meta\u url\u 2

最后,我的
babel.config.js

const { resolve } = require('path');

module.exports = (api) => {
  api.cache.using(() => process.env.NODE_ENV);

  if (process.env.NODE_ENV === 'test') {
    return {
      presets: ['next/babel'],
      plugins: [
        [
          'search-and-replace',
          {
            rules: [
              {
                searchTemplateStrings: true,
                search: 'import_meta_url',
                replace: resolve(__dirname, 'workers'),
              },
            ],
          },
        ],
      ],
    };
  }

  return {
    presets: ['next/babel'],
    plugins: [
      [
        'search-and-replace',
        {
          rules: [
            {
              searchTemplateStrings: true,
              search: 'import_meta_url',
              replace: 'import.meta.url',
            },
          ],
        },
      ],
    ],
  };
};


GL

我也遇到了这个问题。我能够通过在babel处理过程中动态插入正确的值来解决这个问题。我没有使用建议的
search and replace
babel插件,而是使用了


您正在遵循使用CommonJS模块的通用指南。对于本地ESM,请参阅我正在寻找相同问题的答案。将Jest移到ESM模块似乎太过分了。我在babel.config.js中使用了相同的配置,但它不起作用。我收到以下错误
TypeError:构造“URL”失败:基URL无效
import { x } from "./someCode";

it("Returns 5 as the result", () => {
    expect(x).toEqual(5);
});
{
    "presets": [
        ["@babel/preset-env", { "targets": { "node": "current" } }],
        "@babel/preset-typescript"
    ]
}
{
    "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "moduleResolution": "node"
    },
    "include": ["./src/**/*.ts", "./src/**/*.js"]
}
{
    "name": "test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "type": "module",
    "scripts": {
        "test": "jest"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@babel/core": "^7.12.7",
        "@babel/preset-env": "^7.12.7",
        "@babel/preset-typescript": "^7.12.7",
        "jest": "^26.6.3",
        "typescript": "^4.1.2"
    }
}
const { resolve } = require('path');

module.exports = (api) => {
  api.cache.using(() => process.env.NODE_ENV);

  if (process.env.NODE_ENV === 'test') {
    return {
      presets: ['next/babel'],
      plugins: [
        [
          'search-and-replace',
          {
            rules: [
              {
                searchTemplateStrings: true,
                search: 'import_meta_url',
                replace: resolve(__dirname, 'workers'),
              },
            ],
          },
        ],
      ],
    };
  }

  return {
    presets: ['next/babel'],
    plugins: [
      [
        'search-and-replace',
        {
          rules: [
            {
              searchTemplateStrings: true,
              search: 'import_meta_url',
              replace: 'import.meta.url',
            },
          ],
        },
      ],
    ],
  };
};

// someCode.ts
import { dirname } from "path";
import { fileURLToPath } from "url";
import codegen from 'codegen.macro';

const DIRNAME = dirname(fileURLToPath(codegen`module.exports = process.env.NODE_ENV === "test" ? "{ADD VALID VALUE FOR TESTS}" : "import.meta.url"`));

export const x = 5;