首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >导入用于TypeScript、Webpack和Jasmine的ES模块

导入用于TypeScript、Webpack和Jasmine的ES模块
EN

Stack Overflow用户
提问于 2021-09-01 05:56:21
回答 1查看 1K关注 0票数 1

背景

我有一组包,我使用类似的结构在整个个人项目中重用它们。

出于生产目的,它们是用TypeScript编写的,并在发布到npm之前通过tsc编译成JavaScript,这样我就可以将它们安装在其他项目中。我还使用Jasmine对它们进行了测试。

在开发中,我使用Webpack及其ts-loader编译TypeScript,使我可以在浏览器中运行的脚本中使用它。我通常也会在我的项目中使用Webpack,在我使用这些包时,虽然它们是在发布之前编译的,但是这些项目将只将它们视为JavaScript,而不需要使用ts-loader

我在任何地方都使用ES模块语法,这样我就可以在每个上下文中轻松地使用相同的语法,而不用担心在浏览器中切换CommonJS for Node和ES模块语法。为了在茉莉花中允许这样做,我在我的jasmine.json配置文件中设置了"jsLoader": "import"

关于如何编写import语句,我遇到了一个问题。特别是,如何以一种方式指定文件扩展名,以便在开发这些包时为每个用例工作。

无文件扩展名

打字记录节点模块解析对文件扩展名做了一些有用的假设:

TypeScript将模仿Node.js运行时解析策略,以便在编译时找到模块的定义文件。为此,TypeScript在节点的解析逻辑上覆盖TypeScript源文件扩展名(.ts、.tsx和.d.ts)。

这意味着,如果我使用诸如import { foo } from './foo';之类的代码,那么TypeScript将理解查找一个名为foo.ts的文件。

类似地,配置对象允许在extensions属性中指定一组文件扩展名,告诉Webpack如何尝试解析没有文件扩展名的导入。因此,使用我的extensions: ['.js', '.ts']配置,它将找到与TypeScript相同的foo.ts文件。

但是,当我试图使用没有文件扩展名的import 在茉莉花中运行测试时,它无法解析.。

代码语言:javascript
复制
C:\Users\mark.hanna\Documents\Code Playground\analyser>npm test

> analyser@0.1.0 test C:\Users\mark.hanna\Documents\Code Playground\analyser
> tsc && jasmine

Error: 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
    at C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\loader.js:22:30
    at async Jasmine._loadFiles (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:182:5)
    at async Jasmine.loadSpecs (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:173:3)
    at async Jasmine.execute (C:\Users\mark.hanna\Documents\Code Playground\analyser\node_modules\jasmine\lib\jasmine.js:479:3)
npm ERR! Test failed.  See above for more details.

.js扩展

另一个选项是在导入中指定.js文件扩展名,例如import { foo } from './foo.js

虽然我还没有找到清晰的文档,但类型记录的模块解析也清楚地理解了./foo.js可能实际上意味着./foo.ts。我发现对此的引用是支持自TypeScript 2

这意味着我可以指定.js文件扩展名,并且仍然可以使用tsc正确地编译代码。然后,我还能够正确地运行茉莉花测试,因为它了解如何在包含文件扩展名时进行模块解析。

然而,Webpack并不明白./foo.js ./foo.ts**. 实际上可能意味着./foo.ts**.。因此,使用这种方法,当将代码导入脚本以在浏览器中显示示例时,我无法在包中构建代码。

代码语言:javascript
复制
ERROR in ./src/file-processing.ts 2:0-49
Module not found: Error: Can't resolve './AnalyserRows.js' in 'C:\Users\mark.hanna\Documents\Code Playground\analyser\src'
resolve './AnalyserRows.js' in 'C:\Users\mark.hanna\Documents\Code Playground\analyser\src'
  using description file: C:\Users\mark.hanna\Documents\Code Playground\analyser\package.json (relative path: ./src)
    Field 'browser' doesn't contain a valid alias configuration
    using description file: C:\Users\mark.hanna\Documents\Code Playground\analyser\package.json (relative path: ./src/AnalyserRows.js)
      no extension
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js doesn't exist
      .js
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js.js doesn't exist
      .ts
        Field 'browser' doesn't contain a valid alias configuration
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js.ts doesn't exist
      as directory
        C:\Users\mark.hanna\Documents\Code Playground\analyser\src\AnalyserRows.js doesn't exist
 @ ./src/analyser.ts 4:0-48 69:0-50
 @ ./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

Webpack别名的.js扩展

到目前为止,我发现的唯一解决方案是我真正不喜欢的解决方案,就是使用Webpack的resolve.alias配置来明确地告诉它,当我说./foo.js时,我指的是./foo.ts

例如,我目前在我的@cipscis/csv项目中使用了这种方法:

代码语言:javascript
复制
    resolve: {
        extensions: ['.js', '.ts'],
        alias: {
            '@cipscis/csv': `${srcPath}/csv.ts`,
            './stringify.js': './stringify.ts',
            './parse.js': './parse.ts',
        },
    },

webpack.config.js

不过,这感觉很笨重,我必须为导入的每个文件指定这样的别名,这样它就不会有很大的可伸缩性。我觉得肯定有一种“正确”的方法来做这件事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-07 00:11:24

截至2022年的答复

Webpack诉5.74.0是在2022年7月发布的,它包含了一个新的resolve.extensionAlias选项,可以在不需要插件的情况下解决这个问题。

例如:

代码语言:javascript
复制
resolve: {
    extensionAlias: {
        '.js': ['.ts', '.js'],
    },
}

截至2021-09-07

多亏了阿莫斯克对我对一个相关问题的回答,我现在有了这个问题的答案。

茉莉花在这里有点像一只红鲱鱼,真正相关的只有ES模块的解析度,它试图做的是我的设置。这个问题的核心是Webpack的模块解决方案无法复制类型记录模块解析规则的功能,在该规则中,它将*.js路径视为指向*.ts文件的潜在指向。

感谢amosq的评论,我能够通过使用Webpack解析器插件:解决-类型记录-插件来解决这个问题。

它的说明只显示了如何在CommonJS语法中使用它,尽管正如我在问题中提到的,我正在尽可能地使用ES模块语法。为了在Webpack配置中使用它,我执行了以下操作:

代码语言:javascript
复制
import resolveTypeScriptPluginModule from 'resolve-typescript-plugin';
const ResolveTypeScriptPlugin = resolveTypeScriptPluginModule.default;

const config = {
    // ...
    resolve: {
        fullySpecified: true,
        plugins: [new ResolveTypeScriptPlugin()],
        // ...
    },
    // ...
};

这个设置允许我使用Webpack与ts-loader一起编译在导入语句中使用*.js的TypeScript文件,作为我也使用tsc编译这些文件的设置的一部分。我不再需要使用我在问题末尾提到的Webpack化名。

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

https://stackoverflow.com/questions/69008462

复制
相关文章

相似问题

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