【问题标题】:`import username from './username.txt'` with typescript+webpack gives `undefined``import username from './username.txt'` with typescript+webpack 给出 `undefined`
【发布时间】:2019-02-27 17:08:56
【问题描述】:

我正在做一个使用 typescript + webpack 将 .txt 文件作为字符串导入的演示,几乎完成了,但是有这个问题:

hello.ts

import username from './username.txt'

console.log(`Hello, ${username.trim()}!`)

报告:

TypeError: Cannot read property 'trim' of undefined

我的其他文件:

txt.d.ts

declare module '*.txt' {
    const value: string
    export default value;
}

webpack.config.js

module.exports = {
    mode: 'development',
    entry: './hello.ts',
    devtool: 'inline-source-map',
    output: {
        path: __dirname,
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['.ts', '.js']
    },
    module: {
        rules: [{
            test: /\.ts?$/,
            loader: 'ts-loader'
        }, {
            test: /\.txt$/,
            loader: 'raw-loader'
        }]
    }
}

tsconfig.json

{
  "compilerOptions": {
    "strict": true,
    "target": "es6",
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true,
    "types": [
      "node"
    ]
  }
}

package.json

{
  "scripts": {
    "demo": "webpack && node bundle.js"
  },
  "devDependencies": {
    "@types/jquery": "^3.3.9",
    "@types/node": "^10.10.3",
    "raw-loader": "^0.5.1",
    "ts-loader": "^5.1.0",
    "ts-node": "7.0.0",
    "typescript": "^3.0.3",
    "webpack": "^4.18.0",
    "webpack-cli": "^3.1.0"
  }
}

如果我将hello.ts 中的导入代码更改为:

import * as username from './username.txt'

console.log(`Hello, ${username.trim()}!`)

会有另一个类型错误:

console.log(`Hello, ${username.trim()}!`)
                               ^^^^^^
TS2339: Property 'trim' does not exist on type 'typeof import("*.txt")'

虽然我可以找到一种方法让它发挥作用:

const username = require('./username.txt')

但我仍然想知道如何使用import 样式修复它。

这个的演示项目:https://github.com/freewind-demos/typescript-import-txt-file-as-string-issue-demo,你可以克隆并运行它

【问题讨论】:

  • 作为调试步骤,你试过console.log(typeof username)
  • 过程全部正确,问题可能出在.d.ts,因为打字稿不知道username是一个字符串。您可以通过执行(使用 import * as)来解决问题:console.log(`Hello, ${(username as any).trim()}!`)。否则,您需要填写类型定义,但我不知道如何执行此操作。但是,使用 username as any 将起作用:prntscr.com/kxz7ps(并且不会引发任何与编译相关的问题)。你有什么理由为 .txt 文件做模块声明吗?
  • @briosheje,感谢您的回答。是的,username as any 工作但不优雅,也失去了类型检查。我这样做是因为我的测试应该在浏览器中运行,并且我需要从文件中导入一些数据作为测试的输入。我认为应该有问题,但不确定是哪里。
  • @Freewind 您是否有任何理由使用 txt 文件进行输入?另外,有什么理由需要声明类型吗?使用 JSON 并解析它不是更容易吗?
  • @briosheje 我要测试的功能是将一些文本转换成另一种格式,它们一直不是JSON,可以是纯文本

标签: javascript typescript webpack import


【解决方案1】:

看起来raw-loader 正在生成一个模块,该模块将文本字符串作为 CommonJS 样式的导出分配,而不是作为默认导出。您应该更新类型声明和代码以使用它:

declare module '*.txt' {
    const value: string
    export = value;
}

import username = require('./username.txt')

或启用tsconfig.json 中的esModuleInterop 编译器选项以使默认导出可与导出分配互操作。您可以阅读更多关于该问题的信息here

【讨论】:

  • 有了新的declare module '*.txt',我现在可以写import * as username from './username.txt了!谢谢
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 2016-10-05
  • 2017-09-10
  • 1970-01-01
  • 2021-11-22
  • 2017-02-27
  • 2019-12-12
  • 1970-01-01
相关资源
最近更新 更多