Зарегистрируйте файл для загрузки внутри загрузчика - PullRequest
0 голосов
/ 10 октября 2019

Можно ли зарегистрировать файл для связывания внутри загрузчика?

Допустим, у меня есть собственный загрузчик для .cmp.html файлов, и мне требуются такие файлы:

require("component/index.cmp.html");

, тогда яХотелось бы, чтобы мой загрузчик требовал также "component / index.cmp.js" для связывания, поэтому он будет проанализирован всеми применяемыми загрузчиками и появится в итоговом выводе bundle.js

Возможно ли это с загрузчиками?

// Пока код, он ищет теги <StaticComponent name="xyz"> в html-файле, а затем заменяет его html-содержимым xyz, последнее, что нужно сделать, это также связать xyz.js

компоненты / статические / header / index.cmp.html

<div class="some-html-of-this-component">
</div>

компоненты / статические / header / index.cmp.js

// this file has to be required to whole bundle

loaders / static-component-loader.js - этот загрузчик нуждается в html-строке в качестве ввода, пожалуйста, прочитайте снизу вверх

const fs = require("fs");
const JSDOM = require("jsdom").JSDOM;

const readFile = function(path) {
    this.addDependency(path);

    return fs.readFileSync(path, 'utf8');    
}

const getNodeAttrs = function(node) {
    const attributes = {};

    for ( const attr of node.attributes )
        attributes[attr.nodeName] = attr.nodeValue;

    return attributes;
}

const setNodeAttrs = function(node, attributes) {
    node.setAttribute("data-cmpid", attributes.id);
    node.setAttribute("data-cmpname", attributes.name);
    node.setAttribute("class", `cmp cmpstatic cmpid-${attributes.id} ${attributes.class || ""}`.trim());

    if ( attributes.style )
        node.setAttribute("style", attributes.style);
}

const replaceNode = function(node) {
    const nodeParent = node.parentElement;

    const nodeAttributes = getNodeAttrs(node);

    const componentPath = `${__dirname}/../src/components/static/${nodeAttributes.name}`;
    const componentPathHtml = `${componentPath}/index.cmp.html`;
    const componentPathJs = `${componentPath}/index.cmp.js`;
    const componentContentHtml = readFile.call(this, componentPathHtml);

    node.innerHTML = `<div>${componentContentHtml}</div>`;

    const nNode = node.children[0];

    nodeParent.replaceChild(nNode, node);

    setNodeAttrs(nNode, nodeAttributes);

    return nNode;
}

const processNode = function(targetNode) {
    const nodes = targetNode.querySelectorAll("static-component");

    for ( const node of nodes ) {
        const newNode = replaceNode.call(this, node);

        processNode.call(this, newNode);
    }
}

module.exports = function StaticComponentLoader(content) {
    const jsdom = new JSDOM(content);

    processNode.call(this, jsdom.window.document.body);

    return jsdom.serialize();
}

как-то мне нужновключить файл из пути componentPathJs во весь пакет, а затем найти способ требовать его во время выполнения

1 Ответ

1 голос
/ 10 октября 2019

Да, есть загрузчик, который делает это (когда он анализирует файл, он также require добавляет дополнительные файлы). Он называется baggage-loader: https://github.com/deepsweet/baggage-loader. Он предлагает заполнители имен файлов для использования в его конфигурации, так что, например, при загрузке xyz.js он будет вставлять require() для xyz.scss или xyz.json и т. Д., В зависимости от вашей конфигурации.

Если вы посмотрите на исходный код, он на самом деле довольно прост - в основном, загрузчик просто добавляет require() к коду, который он загружает, ивозвращает результат. Если вы не хотите использовать baggage-loader, вы можете легко написать свой собственный загрузчик, который делает нечто подобное, все, что вам нужно сделать, это добавить require('whatever') в виде строки к коду, который получает загрузчик.

(заявление об отказе: технически я поддерживаю baggage-loader, думал, что прошло много времени с тех пор, как я над ним работал)

...