'use strict';
|
|
const fs = require('fs');
|
const vueTemplateCompiler = require('vue-template-compiler');
|
require('upath');
|
require('globby');
|
require('scule');
|
|
async function extractTags(resourcePath) {
|
const tags = new Set();
|
const file = (await fs.readFileSync(resourcePath)).toString("utf8");
|
const component = vueTemplateCompiler.parseComponent(file);
|
if (component.template) {
|
if (component.template.lang === "pug") {
|
try {
|
const pug = require("pug");
|
component.template.content = pug.render(component.template.content, { filename: resourcePath });
|
} catch (err) {
|
}
|
}
|
vueTemplateCompiler.compile(component.template.content, {
|
modules: [{
|
postTransformNode: (el) => {
|
tags.add(el.tag);
|
}
|
}]
|
});
|
}
|
return [...tags];
|
}
|
|
function matcher(tags, components) {
|
return tags.reduce((matches, tag) => {
|
const match = components.find(({ pascalName, kebabName }) => [pascalName, kebabName].includes(tag));
|
match && matches.push(match);
|
return matches;
|
}, []);
|
}
|
|
function install(content, components) {
|
const imports = "{" + components.map((c) => `${c.pascalName}: ${c.isAsync ? c.asyncImport : c.import}`).join(",") + "}";
|
let newContent = "/* nuxt-component-imports */\n";
|
newContent += `installComponents(component, ${imports})
|
`;
|
const hotReload = content.indexOf("/* hot reload */");
|
if (hotReload > -1) {
|
content = content.slice(0, hotReload) + newContent + "\n\n" + content.slice(hotReload);
|
} else {
|
content += "\n\n" + newContent;
|
}
|
return content;
|
}
|
async function loader(content) {
|
this.async();
|
this.cacheable();
|
if (!this.resourceQuery) {
|
this.addDependency(this.resourcePath);
|
const { getComponents } = this.query;
|
const nonAsyncComponents = getComponents().filter((c) => c.isAsync !== true);
|
const tags = await extractTags(this.resourcePath);
|
const matchedComponents = matcher(tags, nonAsyncComponents);
|
if (matchedComponents.length) {
|
content = install.call(this, content, matchedComponents);
|
}
|
}
|
this.callback(null, content);
|
}
|
|
module.exports = loader;
|