尝试将一些旧的 TypeScript 代码从 CRA 迁移到 Vite,并陷入 Vitest 的问题。该项目具有这样的依赖关系:
my-project (ESM)
depends on: lib1 (CJS)
depends on: lib2 (ESM)
代码乍一看似乎不错,
lib1
在 TypeScript 中做了一些看似无害的事情:
import * as lib2 from 'lib2'
哪个转译为...
const lib2_1 = require('lib2');
由于
lib2
是 ESM,原则上这解释了 Vitest 错误的原因:
Error: require() of ES Module /path/to/lib2/dist/esm/index.js from /path/to/lib1/dist/whatever.js not supported.
Instead change the require of index.js in /path/to/lib1/dist/whatever.js to a dynamic import() which is available in all CommonJS modules.
然而,这只是现在才浮出水面,因为之前的 Vite 和 Webpack 都会像捆绑器那样做正确的事情,因为当然
require()
甚至不存在于浏览器中。 Jest 需要一点帮助,配置 transformIgnorePatterns
以排除 lib2
(即允许将 lib2
转译为 CJS,尽管它很丑陋,但允许一切正常运行)。
现在,动态
import()
会破坏非 async
呼叫者,所以最终我想将所有内容迁移到 ESM,但这必须是未来的努力。同时,我应该能够让Vite和Vitest按原样使用代码......对吗?
作为参考,我的
vite.config.cjs
,简化以演示问题,非常简单:
const { defineConfig } = require('vitest/config');
const react = require('@vitejs/plugin-react').default;
module.exports = defineConfig({
plugins: [react()],
server: { /* ... */ },
test: {
environment: 'happy-dom',
globals: true,
},
});
所以,问题是:既然 Vite 正在做开箱即用的事情来支持 ESM
require
,我该如何配置 Vitest 来效仿呢?
我发现似乎有效(至少在某种程度上)的方法是配置:
test: {
server: {
deps: {
inline: ['lib1'],
},
},
},