注册文件以捆绑在加载程序中
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.scss
或 xyz.json
插入一个 require()
等., 取决于你的配置。
如果您查看源代码,它实际上非常简单——基本上,加载器只是将 require()
添加到它正在加载的代码和 returns 结果。如果您不想使用 baggage-loader
,您可以轻松编写自己的自定义加载程序来执行类似的操作,您需要做的就是将 require('whatever')
作为字符串添加到加载程序接收的代码中.
(免责声明:从技术上讲,我是 baggage-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.scss
或 xyz.json
插入一个 require()
等., 取决于你的配置。
如果您查看源代码,它实际上非常简单——基本上,加载器只是将 require()
添加到它正在加载的代码和 returns 结果。如果您不想使用 baggage-loader
,您可以轻松编写自己的自定义加载程序来执行类似的操作,您需要做的就是将 require('whatever')
作为字符串添加到加载程序接收的代码中.
(免责声明:从技术上讲,我是 baggage-loader
的维护者,我想我已经有一段时间没有从事它了)