Mar*_*nna 2 jasmine typescript webpack ts-loader
我有一组使用类似结构在我的个人项目中重复使用的包。
\n出于生产目的,它们是用TypeScripttsc编写的,并在发布到 npm 之前编译成 JavaScript ,以便我可以将它们安装在我的其他项目中。我还使用Jasmine对它们进行测试。
在开发中,我使用Webpack及其ts-loader来编译 TypeScript,这样我就可以在浏览器中运行的示例脚本中使用它。我通常还在我使用这些包的项目中使用 Webpack,尽管它们是在发布之前编译的,这些项目将仅将它们视为 JavaScript 并且不需要使用ts-loader.
我在任何地方都使用ES 模块语法,因此我可以在每个上下文中轻松地使用相同的语法,而不必担心在 Node 的 CommonJS 和浏览器的 ES 模块语法之间切换。为了在 Jasmine 中允许这样做,jasmine.json我在我的配置文件中设置了"jsLoader": "import".
我在如何撰写陈述方面遇到了问题import。特别是,如何以适用于我开发这些包时出现的每个用例的方式指定文件扩展名。
TypeScript 的 Node 模块解析对文件扩展名做出了一些有用的假设:
\n\n\nTypeScript 将模仿 Node.js 运行时解析策略,以便在编译时找到模块的定义文件。为了实现这一点,TypeScript 将 TypeScript 源文件扩展名(.ts、.tsx 和 .d.ts)覆盖在 Node\xe2\x80\x99s 解析逻辑上。
\n
这意味着如果我使用诸如 TypeScript 之类的代码,import { foo } from \'./foo\';TypeScript 将理解查找名为foo.ts.
类似地,Webpack 的resolve配置对象允许在属性中指定一组文件扩展名extensions,以告诉 Webpack 如何尝试解析没有文件扩展名的导入。所以根据我的配置,extensions: [\'.js\', \'.ts\']它会找到foo.ts与 TypeScript 相同的文件。
但是,当我尝试使用import不带文件扩展名的 Jasmine 运行测试时,它无法解析。
C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser>npm test\n\n> analyser@0.1.0 test C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\n> tsc && jasmine\n\nError: While loading C:/Users/mark.hanna/Documents/Code Playground/analyser/spec/analyser.spec.js: NodeError: Cannot find module \'C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\dist\\file-processing\' imported from C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\dist\\analyser.js\n at C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\node_modules\\jasmine\\lib\\loader.js:22:30\n at async Jasmine._loadFiles (C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\node_modules\\jasmine\\lib\\jasmine.js:182:5)\n at async Jasmine.loadSpecs (C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\node_modules\\jasmine\\lib\\jasmine.js:173:3)\n at async Jasmine.execute (C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\node_modules\\jasmine\\lib\\jasmine.js:479:3)\nnpm ERR! Test failed. See above for more details.\nRun Code Online (Sandbox Code Playgroud)\n我的另一个选项是.js在导入中指定文件扩展名,例如import { foo } from \'./foo.js.
虽然我还没有找到明确的记录,但 TypeScript 的模块解析也清楚地理解了这./foo.js实际上可能意味着./foo.ts. 我发现自 TypeScript 2 以来就支持对此的引用
这意味着我可以指定.js文件扩展名并仍然使用tsc. 然后我还能够正确运行我的 Jasmine 测试,因为它了解包含文件扩展名时如何进行模块解析。
然而,Webpack 并不理解这./foo.js实际上可能意味着./foo.ts. 因此,使用这种方法,当我将代码导入到脚本中以在浏览器中显示示例时,我无法在包中构建代码。
ERROR in ./src/file-processing.ts 2:0-49\nModule not found: Error: Can\'t resolve \'./AnalyserRows.js\' in \'C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\'\nresolve \'./AnalyserRows.js\' in \'C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\'\n using description file: C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\package.json (relative path: ./src)\n Field \'browser\' doesn\'t contain a valid alias configuration\n using description file: C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\package.json (relative path: ./src/AnalyserRows.js)\n no extension\n Field \'browser\' doesn\'t contain a valid alias configuration\n C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\\AnalyserRows.js doesn\'t exist\n .js\n Field \'browser\' doesn\'t contain a valid alias configuration\n C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\\AnalyserRows.js.js doesn\'t exist\n .ts\n Field \'browser\' doesn\'t contain a valid alias configuration\n C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\\AnalyserRows.js.ts doesn\'t exist\n as directory\n C:\\Users\\mark.hanna\\Documents\\Code Playground\\analyser\\src\\AnalyserRows.js doesn\'t exist\n @ ./src/analyser.ts 4:0-48 69:0-50\n @ ./docs/assets/js/src/docs-script.ts 2:0-53 7:14-36 34:14-36 43:14-36 48:51-68 49:28-45\nRun Code Online (Sandbox Code Playgroud)\n到目前为止,我找到的唯一解决方案是我真的不喜欢的一个,即使用 Webpack 的resolve.alias配置来明确告诉它,当我说./foo.js我的意思是./foo.ts.
例如,我目前在我的@cipscis/csv项目中使用了这种方法:
\n resolve: {\n extensions: [\'.js\', \'.ts\'],\n alias: {\n \'@cipscis/csv\': `${srcPath}/csv.ts`,\n \'./stringify.js\': \'./stringify.ts\',\n \'./parse.js\': \'./parse.ts\',\n },\n },\nRun Code Online (Sandbox Code Playgroud)\n\n不过,这感觉非常笨重,而且我必须为导入的每个文件指定一个类似的别名,因此它根本感觉不太可扩展。感觉肯定有一个“正确”的方法来做到这一点?
\nWebpack v5.74.0于 2022 年 7 月发布,它包含一个新resolve.extensionAlias选项,无需插件即可解决此问题。
例如:
resolve: {
extensionAlias: {
'.js': ['.ts', '.js'],
},
}
Run Code Online (Sandbox Code Playgroud)
感谢amosq 对我对相关问题的回答的回复,我现在有了这个问题的答案。
Jasmine 在这里有点转移注意力,真正的相关性只是它试图与我的设置进行的 ES 模块分辨率。问题的核心是 Webpack 的模块解析无法重现 TypeScript 模块解析规则的功能,它将*.js路径视为可能指向*.ts文件。
感谢 amosq 的评论,我已经能够使用 Webpack 解析器插件解决此问题:resolve-typescript-plugin
它的说明仅显示如何在 CommonJS 语法中使用它,尽管正如我在问题中提到的,我在任何可以使用 ES 模块语法的地方。为了在我的 Webpack 配置中使用它,我这样做了:
import resolveTypeScriptPluginModule from 'resolve-typescript-plugin';
const ResolveTypeScriptPlugin = resolveTypeScriptPluginModule.default;
const config = {
// ...
resolve: {
fullySpecified: true,
plugins: [new ResolveTypeScriptPlugin()],
// ...
},
// ...
};
Run Code Online (Sandbox Code Playgroud)
此设置允许我使用 Webpack 来ts-loader编译在导入语句中使用的 TypeScript 文件,作为我也用于编译这些文件的*.js同一设置的一部分。tsc我不再需要使用我在问题末尾提到的 Webpack 别名。
| 归档时间: |
|
| 查看次数: |
1676 次 |
| 最近记录: |