Webpack:如何同时以“正常方式”和原始字符串导入 TypeScript 模块

17

使用webpack ^v2.2.1,我想把一个TypeScript模块作为文本导入,除了正常导入同一模块之外。

我已经想到了可能要使用raw-loader。但是它无法正常工作。

以下是一些示例代码:

import DemoComponent from './demo'
import demoCode from 'raw-loader!./demo'

TypeScript 正告诉我像这样的

error TS2307: Cannot find module 'raw-loader!./demo'.

我正在使用ts-loader

这是我的webpack.config.js文件:

const { resolve } = require('path')
const fail = require('webpack-fail-plugin')

const config = {
  entry: './docs/index.ts',
  output: {
    filename: 'bundle.js',
    path: resolve(__dirname, 'docs-build')
  },
  resolve: {
    extensions: [ '.ts', '.js' ]
  },
  devtool: 'inline-source-map',
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        loader: 'source-map-loader'
      },
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          'sass-loader'
        ]
      }
    ]
  },
  plugins: [
    fail
  ]
}

module.exports = config

相关的 https://dev59.com/65Hea4cB1Zd3GeqPpHHa - Doug
6个回答

22

如果有人正在寻找解决方案,请注意:使用import是最佳选择-它将被类型化,并且在输出import vs require时,可以进行来自模块捆绑器(如Rollup和Webpack 3+)的优化:

您需要创建一个raw-loader.d.ts文件,并确保它被您的tsconfig.json文件包含。输入以下内容:

declare module '!!raw-loader!*' {
  const contents: string
  export = contents
}

tsconfig.json

{
    "compilerOptions": {
        "types": ["raw-loader.d.ts", "node"]
    }
}

8
即使在相同的文件夹中存在该文件,如果我们收到“无法找到raw-loader.d.ts类型定义文件”的消息,这意味着什么? - Andy
@Andy,不要在“tsconfig.json”文件中添加任何额外的内容。只需.d.ts文件即可。 - James Bond

3

看起来以下内容是有效的:

import DemoComponent from './demo'
const demoCode = require('!!raw-loader!./demo')

但我不确定这是否正确。我希望能找到一些关于加载器顺序和机制的文档。

此外,我更喜欢使用import语句保持一致性。但如果我进行直接转换,TypeScript会抱怨:

import DemoComponent from './demo'
import demoCode from '!!raw-loader!./demo'

错误很简单。
error TS2307: Cannot find module '!!raw-loader!./demo'.

我恰好正在享受require运行时的特性,因此我会坚持使用它。 - Shahar 'Dawn' Or

1
我已经在这里写了一个完整的解释: https://yonatankra.com/how-to-solve-ts2307-cannot-find-module-when-using-inline-webpack-loaders-with-typescript/ 简而言之:
你可以使用以下语法进行导入:import template from 'raw-loader!./component.template.html'; 为了使其适用于任何类型的文件,您需要执行以下操作:
1. 设置模块声明:raw-loader.d.ts
declare module '!!raw-loader!*' {
  const contents: string
  export default contents
}
  1. 在你的 tsConfig.json 中使用它,并添加 allowSyntheticDefaultImports 属性,以允许没有默认导出的模块以这种方式被导入:
{
  "compilerOptions": {
    "types": ["raw-loader.d.ts", "node"],
    "allowSyntheticDefaultImports": true
}

在这篇文章中,我还解释了如何使其工作(如果您因某种非常奇怪的原因想要使用template.default)。

0

针对您的错误:

raw-loader.d.ts:

declare module '!!raw-loader!*' {
  const contents: string
  export default contents
}

0
对我来说,从@Nicolas的回答中去掉"!!"是有效的。
declare module 'raw-loader!*' {
  const contents: string
  export default contents
}

我没时间深入研究,但以防万一有人需要。我正在使用typescript@4.9.5和next@13.4.7。

0

raw-loader 似乎在 Webpack 5 中已被废弃,他们推荐使用 配置内置的 asset/source。以下是对我有效的配置:

在 webpack 配置文件中:

module: {
  rules: [
    {
      resourceQuery: /raw/,
      type: 'asset/source'
    }
  ]
}

raw-asset-source.d.ts

declare module '*?raw' {
  const rawFileContent: string
  export default rawFileContent
}

然后你可以像这样进行导入
import demoCode from './demo?raw'

demoCode 应该是一个包含文件内容的字符串


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接