'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;