【问题标题】:Visual Studio Code incorreclty reporting error 'Cannot find module' when importing XML file, whilst this error doesn't appear on build导入 XML 文件时,Visual Studio Code incorreclty 报告错误“找不到模块”,而此错误不会出现在构建中
【发布时间】:2020-03-15 07:55:59
【问题描述】:

我正在编写一个 Typescript 测试用例,它需要一些静态 xml,从作为项目一部分的文件加载。我在 node/typescript 项目中使用 webpack,发现 VSC typescript 与项目的 typescript 不一致。

导致问题的行(从 VSC 角度来看)是这样的(测试用例和 xml 文件在同一目录中):

从'./app.config.xml'导入数据;

为了让导入工作(在项目中)我必须做以下事情(Importing Other Assets):

1) 确保我在 webpack 中使用 raw-loader 处理 xml 文件:

  module: {
    rules: [
      {
        test: /\.xml$/i,
        use: 'raw-loader'
      },

2) 在声明文件 (./lib/declarations.d.ts) 中声明模块

declare module '*.xml' {
  const content: string;
  export default content;
}

3) 将此声明文件包含在 tsconfig 的 types 属性中

"types": [
  "mocha", "node", "./lib/declarations"
],

在我的测试用例中,我尝试按如下方式导入:

从'./app.config.xml'导入数据;

但是,VSC 中的 Typescript 报告此错误:

找不到模块'./app.config.xml'.ts(2307)

但是,当我构建项目时,这不是问题。如果我从声明文件中删除模块声明,那么构建确实会失败并出现同样的错误。所以不知何故,VSC 中的 Typescript 与项目中安装的 Typescript 不同步。 VSC 中的 typescript 版本与项目相同(版本 3.7.2)。

由于构建工作正常,我不知道它是否“可以签入”​​。我不喜欢在 VSC 中看到错误,因为它与项目不同步。到目前为止,在我的 Typescript 旅程中,项目中的 typescript 和 VSC 中的 typescript 一直是同步的,所以我无法理解这里发生了什么。我试图清理我的回购并重建,但这没有任何区别。

在 VSC 中,我使用的是“Typescript extension Pack (0.2.0)”(其中包括 TSLine、TypeScript Hero、json2ts、Move TS、Path Intellisense、Tyescript Impoerter、Prettier、Debugger for Chrome)但是,我没有不相信这些插件中的任何一个都对 VSC 报告的错误负责。我认为错误来自直接内置于 VSC 中的 Typescript 支持。

为了完整起见,我的 tsconfig 是:

{
  "compilerOptions": {
    "allowJs": true,
    "alwaysStrict": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "Node",
    "noImplicitAny": true,
    "sourceMap": true,
    "strictNullChecks": true,
    "target": "es5",
    "types": [
      "mocha", "node", "./lib/declarations"
    ],
    "lib": [
      "es5",
      "es2015",
      "es6",
      "dom"
    ]
  },
  "include": [
    "lib/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

和 webpack 文件:

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  devtool: 'source-map',
  mode: 'development',
  entry: ['./tests/all-tests-entry.js', './lib'],
  target: 'node',
  externals: [nodeExternals()],
  module: {
    rules: [
      {
        test: /\.xml$/i,
        use: 'raw-loader'
      },
      { test: /\.ts(x?)$/, loader: 'ts-loader' },
      { test: /\.json$/, loader: 'json-loader' }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js', '.json']
  },
  watchOptions: {
    ignored: /node_modules/
  },
  output: {
    filename: 'test-bundle.js',
    sourceMapFilename: 'test-bundle.js.map',
    path: path.resolve(__dirname, 'dist'),
    libraryTarget: 'commonjs'
  }
};

和 ./tests/all-tests-entry.js:

var context = require.context('./', true, /.spec.ts$/);
context.keys().forEach(context);
module.exports = context;

及相关文件的目录结构:

/project-root/
tsconfig.json
webpack.config.test.ts

/project-root/lib/
declaration.d.ts

/project-root/tests/
widget.class.spec.ts
app.config.xml

这里是 VSC 的快照(禁用所有扩展)报告项目构建中不存在的错误:

【问题讨论】:

    标签: typescript webpack visual-studio-code


    【解决方案1】:

    存在不匹配是因为您从命令行使用 webpack 编译代码,但 VS Code 使用普通 TypeScript 为其 IntelliSense 提供动力。

    TypeScript 本身不知道如何导入任意数据文件(如 xml)。如果您尝试使用 tsc 而不是 webpack 编译代码,您会看到与在 VS Code 中看到的相同的错误。

    请参阅these answers 了解更多信息以及如何解决普通 TS 中的问题。基本上,你需要在你的项目中添加一个d.ts 文件,声明如下:

    declare module "*.xml" {
    const value: string;
      export default value;
    }
    

    【讨论】:

    • 嗨,马特,感谢您的评论。您提供的代码示例正是我已经做过的(作为我研究的一部分),正如我在我的帖子中早些时候所说的那样。我对此进行了广泛的研究,但我没有看到您发现的那个问题,所以我会看看。
    • 尝试在你的正常项目中包含声明(不在types下)。要进行测试,请将其粘贴到具有 xml 导入的文件的顶部
    • 抱歉,马特,我不清楚您所说的“尝试在正常项目中包含声明”是什么意思。正如你所说,我从 tsconfig.json 中的“类型”中删除了“声明”,但我不知道你所说的“普通项目”是什么意思
    • 基本上,我正在寻找的只是修复 VSC。该项目使用 webpack 构建正常,所以 VSC 有问题。
    • 你试过用tsc编译你的项目吗?要将声明添加到您的项目,只需创建一个d.ts 文件,粘贴该声明,然后运行TypeScript: Go To Project configuration。这应该打开您的普通 ts 文件所在的相同 tsconfig。如果没有,请确保您的 tsconfig 包含该 d.ts 文件(通过 include / exclude,而不是 types
    【解决方案2】:

    解决此问题的方法是在文件顶部添加一个三斜杠指令。由于 import 语句取决于 ./declarations.d.ts 中定义的模块声明,因此需要在前面加上一个三斜杠引用指令(在我的项目中):

    /// <reference types="../../lib/declarations" />
    

    另外,我发现解决此问题的另一个解决方案是将声明文件与导入文件放在同一文件夹中。这不需要三斜杠指令。

    唯一的问题是,为什么 VSC Typescript 和 webpack 构建的项目 Typescript 会有所不同?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 2020-09-13
      • 2022-07-11
      • 2018-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多