如何使用 Webpack 和 React 将类型文件作为文本加载?

How to load a typings file as text with Webpack and React?

为了设置 Monaco 编辑器实例,我想为自定义库添加类型文件。安装编辑器时,我调用:

    public componentDidMount(): void {
        languages.typescript.javascriptDefaults.addExtraLib(
            typings,
        );
    }

变量typings被加载:

// eslint-disable-next-line @typescript-eslint/no-var-requires
const typings = require("../../../modules/scripting/typings/my-runtime.d.ts");

旁注:eslint 注释是必要的,否则会将 require 调用标记为失败。

我使用 react-app-rewired 允许在不弹出基于 CRA 的应用程序的情况下编辑我的 webpack 配置。现在 config-overrides.js 文件包含:

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');

module.exports = function override(config, env) {
    config.plugins.push(new MonacoWebpackPlugin({
        languages: ["typescript", "javascript", "mysql", "json", "markdown"]
    }));

    config.module.rules.push(
        {
            test: /\.(html|d\.ts)$/i,
            use: [
                {
                    loader: 'raw-loader',
                    options: {
                        esModule: false,
                    },
                },
            ],
        },
    );

    return config;
}

如您所见,我实际上处理了 2 种文件类型:html 和 d.ts。 html 部分效果很好。加载 .html 文件的 require 调用为我提供了整个 html 文件内容(我需要用我的自定义运行时加载 <iframe>)。

需要调用类型文件,但是,returns 一个对象(可能是一个模块,很难说,因为它在 vscode 的调试器中显示为空)。

所以问题是:如何更改我的配置以使加载类型文件 (.d.ts) 成为可能的文本?

为什么会得到 {}?我认为是因为来自 crababel-loader 加载器规则(处理 *.ts)与你的 raw-loader 规则(处理 *.d.ts)冲突并且 webpack 决定使用 babel-loader那里。

我找到了两种使用 react-app-rewired 来处理这个问题的方法,请看看这个 repo

1) 以更积极的内联方式使用 raw-loader

// eslint-disable-next-line import/no-webpack-loader-syntax
const dogTypings = require('!!raw-loader?esModule=false!./dog.d.ts');

说明:!! 含义 - 禁用该文件配置中的所有其他规则。 import/no-webpack-loader-syntax 限制使用内联语法,所以我们需要在那里禁用它。

2) 从 cra 默认配置中删除 ModuleScopePlugin 并在 src.
之外创建您的类型 默认情况下,您无法从 src 之外导入任何内容。但是 react-app-rewired - 当然可以。这是配置示例:

const { resolve } = require('path');
const { removeModuleScopePlugin } = require('customize-cra')

module.exports = function override(config, env) {
    const newConfig = removeModuleScopePlugin()(config, env);

    newConfig.module.rules.push(
        {
            test: /\.(d\.ts)$/i,
            include: resolve(__dirname, 'typings'),
            use: [
                {
                    loader: 'raw-loader',
                    options: {
                        esModule: false,
                    },
                },
            ],
        },
    );

    return newConfig;
}

注意:这两种方式都有一个缺点 - 它们禁用了 babel 加载器规则(实际上在 cra 应用程序中编译打字稿).d.ts文件和类型检查可能会因为它们的实例而被破坏,但我没有检查过。你的代码的问题是打字稿编译器的行为,它从运行时删除了 .d.ts 文件,所以 webpack 没有发出它们,我没有找到任何方法来阻止它。