首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Jest测试中使用`import.meta`

如何在Jest测试中使用`import.meta`
EN

Stack Overflow用户
提问于 2020-11-23 01:10:33
回答 9查看 19.1K关注 0票数 44

我正在使用Node.js ( TypeScript)编写ESModules代码,我需要访问__dirname。为了在CommonJS中访问等效于CommonJS的ESM,我称之为dirname(fileURLToPath(import.meta.url))。我也在用TypeScript用Jest编写测试。使用指南,我设置了Babel。当我运行jest命令时,我得到

代码语言:javascript
复制
const DIRNAME = (0, _path.dirname)((0, _url.fileURLToPath)(import.meta.url));
                                                                      ^^^^
SyntaxError: Cannot use 'import.meta' outside a module

这是我写的文件

someCode.ts__:

代码语言:javascript
复制
import { dirname } from "path";
import { fileURLToPath } from "url";

const DIRNAME = dirname(fileURLToPath(import.meta.url));

export const x = 5;

someCode.test.ts__:

代码语言:javascript
复制
import { x } from "./someCode";

it("Returns 5 as the result", () => {
    expect(x).toEqual(5);
});

.babelrc.json__:

代码语言:javascript
复制
{
    "presets": [
        ["@babel/preset-env", { "targets": { "node": "current" } }],
        "@babel/preset-typescript"
    ]
}

tsconfig.json:

代码语言:javascript
复制
{
    "compilerOptions": {
        "target": "ES2020",
        "module": "ESNext",
        "moduleResolution": "node"
    },
    "include": ["./src/**/*.ts", "./src/**/*.js"]
}

package.json__:

代码语言:javascript
复制
{
    "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"
    }
}

Environment:

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

回答 9

Stack Overflow用户

发布于 2021-11-01 11:32:50

解决方案:模块化ESM代码并对其进行模拟。

我最近也遇到了这个问题,最后我不得不:

  1. 将ESM特定的问题(例如import.meta功能)导出到它自己的"utils“文件/函数中。
  2. 然后在模拟目录中创建一个不需要ESM特定功能的模拟函数。
  3. 在使用该功能的文件中,声明jest.mock("/path/to/that/file.ts")

这一过程将如下所示:

原始文件结构

代码语言:javascript
复制
src/
--/someCode.ts
--/__tests__/
/--/--/someCode.test.ts
代码语言:javascript
复制
// someCode.ts
...
const getApiUrl = () => { 
  ...
  const url = import.meta.env.SOME_ENV_VAR_HERE;
  ...
  return url;
};
...

新的文件结构

标题

代码语言:javascript
复制
src/
--/someCode.ts
--/utils.js
--/__mocks__/
--/--/utils.ts
--/__tests__/
--/--/someCome.test.ts

然后在档案中:

代码语言:javascript
复制
// someCode.ts
...
import { getApiUrl } from "./utils.ts";
...

// utils.js
export const getApiUrl = () => {...};

至于测试:

代码语言:javascript
复制
// __mocks__/utils.ts
export const getpiUrl = jest.fn(() => 'some.url');

// __tests__/utils.test.ts
...
jest.mock("src/util.ts");
...
describe(...);
票数 16
EN

Stack Overflow用户

发布于 2022-01-09 10:25:46

我们使用import.meta.url来使用web工作者,例如使用Webpack的本地工人支持5。这很好,但是在运行Jest测试时失败了。

据我所知,babel-vite-preset并没有处理这个问题。关于提取和模拟使用import.meta的代码的最高答案确实有效,但很难处理。

我发现目前最好的解决方案是使用巴比伦-插件-转换-导入-元。这个简单的插件将import.meta.url语法替换为Node.js代码,以检索当前文件的URL,因此它在测试中工作得很好。请注意,您只希望在运行测试时激活此插件。

票数 13
EN

Stack Overflow用户

发布于 2021-05-08 09:37:37

我也遇到了同样的问题,我用babel插件修复了它:搜索和替换

在我的代码中,我用import_meta_url更改了所有的import_meta_url

我将插件添加到babel配置中,通过开发和生产中的import.meta.urlresolve(__dirname, 'workers')来更改它。

我之所以能够这样做,是因为它符合我的所有情况,如果您的import_meta_url需要在不同的场景中被替换为不同的刺,那么您就需要使用import_meta_url_1 import_meta_url_2等等。

最后我的babel.config.js

代码语言:javascript
复制
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',
            },
          ],
        },
      ],
    ],
  };
};

总帐

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64961387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档