Как загрузить текстовый файл с помощью Webpack и React? - PullRequest
3 голосов
/ 09 мая 2020

Для настройки экземпляра редактора 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 вызов как сбой.

Я использую response-app-rewired, чтобы разрешить редактирование конфигурации моего веб-пакета без извлечения приложения на основе CRA. Теперь файл 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 работает нормально. Вызов require для загрузки файла. html дает мне все содержимое файла html (мне нужно это, чтобы загрузить <iframe> с моей настраиваемой средой выполнения).

Требуемый вызов для файла типизации, однако возвращает объект (вероятно, модуль, трудно сказать, поскольку он кажется пустым в отладчике в vscode).

Итак, вопрос: как изменить мою конфигурацию, чтобы загружать файлы типизации (.d.ts ) как текст?

1 Ответ

2 голосов
/ 25 мая 2020

Почему вы получаете {}? Я думаю, потому что правило загрузчика babel-loader (которое обрабатывает *.ts) из cra конфликтует с вашим правилом raw-loader (которое обрабатывает *.d.ts), и webpack решает использовать там babel-loader.

I нашел два способа решить эту проблему с помощью react-app-rewired, пожалуйста, взгляните на это репо .

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) Удалите ModuleScopePlugin из конфигурации cra по умолчанию и создавайте свои типы за пределами src.
По умолчанию вы можете ' t импортировать что-либо из-за пределов 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 файлов из среды выполнения, поэтому веб-пакет не генерирует их, и я не нашел способа предотвратить это.

...