Я пытаюсь написать собственный загрузчик веб-пакетов, который загружает демонстрационные файлы javascript вместе с их исходным кодом для целей документирования.Следует
- Загрузить указанный файл javascript (например,
Simple.demo.js
) - Присоединить необработанный источник файла к экспорту по умолчанию в качестве нового поля
Когда это будет сделано, я смогу настроить загрузчик в моей конфигурации веб-пакета:
{
test: /\.demo.js$/,
exclude: /node_modules/,
use: [{
loader: "babel-loader",
}, {
loader: resolve("./demo-loader.js"),
}]
}
… затем получить доступ к исходному коду для моей демонстрации после импорта:
import SimpleDemo from 'demo-loader!./Simple.demo.js';
console.log(SimpleDemo.__source__);
SimpleDemo(); //run the demo code
Попытка 1
Я успешно загрузил исходный код и выполнил именованный экспорт, используя следующий загрузчик:
const { readFile } = require("fs");
const escapeSource = require("js-string-escape");
module.exports = function withSourceLoader(content, map, meta) {
const onComplete = this.async();
const fileName = this.resource;
readFile(fileName, (error, fileContents) => {
if ( error ) {
return onComplete(error);
}
const exportSource = `export const rawSource = "${ escapeSource(fileContents)}";`;
const newContent = `${ content }\n\n${ exportSource }`;
onComplete(null, newContent, map, meta);
});
};
Это позволяет мне сделать
import SimpleDemo, { rawSource } from 'demo-loader!./Simple.demo.js`;
console.log(rawSource);
SimpleDemo(); //run the demo code
… ноЯ хочу передать весь SimpleDemo
как объект другой функции, поэтому я хотел бы импортировать их как один блок (будет много демонстраций).
Попытка 2
Поскольку я не знаю имя внутренней переменной, используемой для экспорта по умолчанию в демонстрационном файле (без выполнения полного анализа AST), я не могу просто добавить дополнительную строку в файл, чтобы изменить его.Вместо этого я попытался написать файл-обертку, который импортирует и повторно экспортирует значение по умолчанию, например:
const { readFile } = require("fs");
const { basename } = require("path");
const escapeSource = require("js-string-escape");
module.exports = function withSourceLoader(content, map, meta) {
const onComplete = this.async();
const fileName = this.resource;
readFile(fileName, (error, fileContents) => {
if ( error ) {
return onComplete(error);
}
const newContent = `
const rawSource = "${ escapeSource(fileContents) }";
import DemoDefault from './${ basename(fileName) }';
DemoDefault.__source__ = rawSource;
export default DemoDefault;
`;
onComplete(null, newContent, map, meta);
});
};
Я надеялся, что эта новая директива import
будет решена с помощью веб-пакета (я знаю, чтоэто может привести к бесконечной регрессии, потому что это должно просто вызвать тот же загрузчик снова на основе имени файла).Однако этого, похоже, не происходит - я просто получаю
TypeError: _Simple_demo_js__WEBPACK_IMPORTED_MODULE_0__.default is undefined
, что, по-видимому, связано с тем, что webpack уже создал свое дерево зависимостей и не хочет добавлять к нему что-либо еще.Я также попытался использовать require()
вместо import
, это не улучшило ситуацию.
Я поступаю неправильно?Я хотел использовать что-то простое с цепочкой, объединяя выходные данные других загрузчиков, но API, похоже, не имеет возможности сделать это.