尝试通过 --experimental-loader 选项使用 mocha、ES6 模块和 ts-node
Posted
技术标签:
【中文标题】尝试通过 --experimental-loader 选项使用 mocha、ES6 模块和 ts-node【英文标题】:Trying to use mocha, ES6 modules, and ts-node with the --experimental-loader option 【发布时间】:2021-03-30 06:01:59 【问题描述】:我正在尝试让 ts-node 选项 --experimental-loader
与 mocha 一起工作,但没有运气。在我开始尝试编译 ES6 模块之前,我曾经能够以这种方式运行 mocha 测试:
"test": "nyc --reporter=html mocha --require ts-node/register src/**/*.spec.ts"
这在生成 ES6 模块时不再起作用了。
我会使用TS_NODE_COMPILER_OPTIONS='\"module\": \"commonjs\" '
解决方案进行测试,但这对我来说不起作用,因为还有一个复杂的问题:我正在生成 ES6 模块作为构建的第一步,但也是 使用 webpack 和 babel 生成 ES5/CommonJS 模块。除非我将 .js
添加到本地 TypeScript import
语句的末尾,否则最后一步不起作用。
但是添加那些.js
扩展会破坏TS_NODE_COMPILER_OPTIONS='\"module\": \"commonjs\" '
解决方案,但是,如果我返回并删除所有.js
扩展,这将起作用。我显然不想要一个测试和构建过程,我必须在添加和删除这些扩展之间来回切换。
为了简化现在,我已经去掉了 nyc,我正在尝试运行这样的测试:
mocha -r ts-node/register --experimental-loader ./ts-loader.mjs src/**/*.spec.ts
这样我没有收到任何错误,但也没有任何反应。就像src/**/*.spec.ts
不存在一样。
我的无所事事(目前)虚拟加载程序如下所示:
console.log('ts-loader loaded');
export async function resolve(specifier, context, defaultResolve)
console.log('resolve');
return defaultResolve(specifier, context, defaultResolve);
export async function getFormat(url, context, defaultGetFormat)
console.log('getFormat');
return defaultGetFormat(url, context, defaultGetFormat);
export async function getSource(url, context, defaultGetSource)
console.log('getSource');
return defaultGetSource(url, context, defaultGetSource);
export async function transformSource(source, context, defaultTransformSource)
console.log('transformSource');
return defaultTransformSource(source, context, defaultTransformSource);
export function getGlobalPreloadCode()
console.log('getGlobalPreloadCode');
return '';
我可以说它已加载,因为出现了 'ts-loader loaded'
消息,但没有调用任何函数。
我尝试了其他排列,但只是得到了诸如 src/**/*.spec.ts
被视为文字文件名而不是 glob 之类的错误,或者有关未找到模块的错误。
我希望看到每处理一个import
都会调用我的加载程序,然后弄清楚如何操作文件扩展名,但我还没有做到这一点。有什么建议吗?
我正在使用节点 v14.15.1。可以在此处找到我的项目的完整代码,其中包含有效的构建,但测试失败:https://github.com/kshetline/tubular_math
【问题讨论】:
【参考方案1】:我终于找到了一个解决方案,尽管它与我最初寻找的方式不同。我放弃了让 mocha 对额外的 .js
扩展感到满意的尝试,并找到了一种让 webpack 在没有它们的情况下满意的方法。所以...
import Angle, Mode, Unit from './angle.js';
...回到...
import Angle, Mode, Unit from './angle';
我的测试脚本如下所示:
"scripts":
"build": "rimraf dist/ && tsc && webpack && webpack --env target=umd",
"prepublishOnly": "npm run build",
"lint": "eslint 'src/**/*.ts'",
"test": "TS_NODE_COMPILER_OPTIONS='\"module\":\"commonjs\"' nyc --reporter=html mocha --require ts-node/register src/**/*.spec.ts"
,
最后,最重要的是,我想出了如何让 webpack 5.x(4.x 没有这个问题)对没有 .js
扩展名的本地 javascript 导入感到满意,而 webpack 现在则不然坚持如果你的package.json
说"type": "module"
:
module:
rules: [
test: /\.js$/, use: 'babel-loader', resolve: fullySpecified: false
]
...将fullySpecified
设置为false 是解决问题的关键。
更新:上面的示例是在一个特意简单的项目上完成的,对于初学者来说很容易生成带有 ESM 模块的 npm 包。现在我正在尝试一些更高级的东西,我再次遇到了运行单元测试的障碍。一旦 *.spec.ts 文件直接或间接导入外部代码,模块加载就会失败。在弄清楚如何解决该问题之前,我只能测试没有外部依赖项的代码。显然,使用"TS_NODE_COMPILER_OPTIONS='\"module\":\"commonjs\"'
只会让我更深入地解决与 ts-node 一起运行 mocha 的基本问题。
【讨论】:
以上是关于尝试通过 --experimental-loader 选项使用 mocha、ES6 模块和 ts-node的主要内容,如果未能解决你的问题,请参考以下文章
尝试通过Subprocess发送命令以使用ffmpeg进行操作
尝试通过电子邮件发送多个附件时出现 ActivityNotFoundException