Как загрузить текстовый файл с помощью Webpack и React?
Для настройки экземпляра редактора Monaco я хочу добавить файл типизации для пользовательской библиотеки lib. При установке редактора вызываю:
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;
}
Как видите, здесь я обрабатываю файлы двух типов: html и d.ts. HTML-часть работает хорошо. Требование вызова для загрузки файла.html дает мне все содержимое файла html (мне нужно, чтобы загрузить<iframe>
с моей пользовательской средой выполнения).
Однако вызов require для файла типизации возвращает объект (вероятно, модуль, трудно сказать, поскольку он выглядит пустым в отладчике в vscode).
Возникает вопрос: как изменить мою конфигурацию, чтобы можно было загружать файлы типизации (.d.ts) как текст?
1 ответ
Почему ты получаешь {}
? Я думаю потому чтоbabel-loader
правило загрузчика (которое обрабатывает *.ts
) из cra
конфликтует с вашим raw-loader
правило (которое обрабатывает *.d.ts
) и webpack решает использовать babel-loader
там.
Я нашел два способа решить эту проблему, используя 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
.
По умолчанию вы не можете ничего импортировать извне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 не испускал их, и я не нашел способа предотвратить это.