注册文件以捆绑在加载程序中

Register file to bundle inside loader

是否可以在加载程序中注册文件以进行捆绑?

假设我有一个自己的 .cmp.html 文件加载器,我需要这样的文件:

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

然后我希望我的装载机也需要 "component/index.cmp.js" 来捆绑,所以它将被所有应用的装载机解析并出现在最终的 bundle.js 输出中

加载器可以吗?

// 到目前为止的代码,它在 html 文件中搜索 <StaticComponent name="xyz"> 标签,然后将其替换为 xyz 的 html 内容,最后要做的也是捆绑 xyz.js

components/static/header/index.cmp.html

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

components/static/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 中的文件包含到整个包中,然后找到一种在运行时需要它的方法

是的,有一个加载程序就是这样做的(当它解析一个文件时,它还会 require 个额外的文件)。它被称为行李装载机:https://github.com/deepsweet/baggage-loader。它提供了在其配置中使用的文件名占位符,因此,例如,每当加载 xyz.js 时,它都会为 xyz.scssxyz.json 插入一个 require() 等., 取决于你的配置。

如果您查看源代码,它实际上非常简单——基本上,加载器只是将 require() 添加到它正在加载的代码和 returns 结果。如果您不想使用 baggage-loader,您可以轻松编写自己的自定义加载程序来执行类似的操作,您需要做的就是将 require('whatever') 作为字符串添加到加载程序接收的代码中.

(免责声明:从技术上讲,我是 baggage-loader 的维护者,我想我已经有一段时间没有从事它了)