UNPKG

html-bundler-webpack-plugin

Version:

Generates complete single-page or multi-page website from source assets. Built-in support for Markdown, Eta, EJS, Handlebars, Nunjucks, Pug. Alternative to html-webpack-plugin.

239 lines (197 loc) 7.21 kB
const path = require('path'); const { red, green, cyan, cyanBright, magenta, black, yellow, yellowBright, fg, bg, white } = require('ansis'); const Config = require('../../Common/Config'); const { isWin, pathToPosix, outToConsole } = require('../../Common/Helpers'); const PluginService = require('../PluginService'); const Collection = require('../Collection'); const gray = fg(244); const padLevel1 = 16; const padLevel2 = padLevel1 + 10; const padLevel3 = padLevel2 + 8; const padChunks = padLevel1 + 4; const { pluginName, pluginLabel } = Config.get(); /** * Return the path of the file relative to a directory. * * Note: this is not a true relative path, this path is for verbose only. * * @param {string} file * @param {string} dir * @return {string} */ const relativePathVerbose = (file, dir = process.cwd()) => { const nodeModuleDirname = path.sep + 'node_modules' + path.sep; const testDirname = path.sep + path.join(pluginName, 'test') + path.sep; const srcDirname = path.sep + path.join(pluginName, 'src') + path.sep; const isTest = 'NODE_ENV_TEST' in process.env; let relFile = file; if (!path.isAbsolute(file)) { file = path.join(dir, file); } if (file.startsWith(dir)) { relFile = path.relative(dir, file); } else if (isTest) { // for test only: // get the relative path to the test directory, because on another machine the absolute path is different, // e.g. test by CI on GitHub, const testDirnamePos = file.indexOf(testDirname); const srcDirnamePos = file.indexOf(srcDirname); if (testDirnamePos > 0) { return '~' + file.slice(testDirnamePos + testDirname.length); } else if (srcDirnamePos > 0) { return '~' + file.slice(srcDirnamePos + 1); } } // extract the node module path const nodeModulePos = relFile.indexOf(nodeModuleDirname); if (nodeModulePos > 0) { relFile = relFile.slice(nodeModulePos + nodeModuleDirname.length); } if (!path.extname(file)) relFile = path.join(relFile, path.sep); return isWin ? pathToPosix(relFile) : relFile; }; /** * Get the compilation name styled based on the presence of an error. * * The compilation name is displayed in the console output when compilation is finished. * * @param {string|undefined} name * @param {boolean} error * @return {string} */ const compilationName = (name, error) => { let configName = ''; if (name != null) { configName = white` config ${magenta`[${name}]`}`; } return error ? bg(196).whiteBright` ${pluginLabel} ` + red` ${configName} ▶▶▶` : bg(118).black` ${pluginLabel} ` + green` ${configName} ▶▶▶`; }; const colorType = (item, pad) => { let { type, inline } = item; const color = inline ? yellowBright : fg(112); if (type === Collection.type.style && item.imported) { type = inline ? `inline styles` : `import styles`; } else if (inline) { type = `inline`; } return color(`${type}:`.padStart(pad)); }; const renderAssets = (item, pad = padLevel2) => { const { type } = item; let str = ''; // style can contain assets such as images, fonts const assets = item.assets; if (Array.isArray(assets)) { assets.forEach((assetItem) => { const { inline, resource, assetFile } = assetItem; const sourceFile = relativePathVerbose(resource); str += colorType(assetItem, pad) + ` ${cyan(sourceFile)}\n`; if (!inline && assetFile) { str += `${'->'.padStart(pad)} ${assetFile}\n`; } }); } if (type === Collection.type.script) { const chunks = item.chunks || []; const children = item.children || []; const files = [...chunks, ...children]; const isSingleChunk = files.length === 1; let li; let padLen; if (isSingleChunk) { padLen = padLevel1; } else { padLen = padChunks; str += `${'->'.padStart(padLevel1)} ${fg(120)`chunks:`}` + '\n'; } for (let { inline, chunkFile, assetFile } of files) { li = isSingleChunk ? '->' : ''; if (inline) { str += `${li.padStart(padLen)} ${gray(path.basename(chunkFile))} ${yellow`(inline)`}\n`; } else { str += `${li.padStart(padLen)} ${assetFile}\n`; } } } return str; }; /** * Display all processed assets in entry points. * @param {Compiler} pluginCompiler */ const verbose = (pluginCompiler) => { const pluginContext = PluginService.getPluginContext(pluginCompiler); const collection = pluginContext.collection; const collectionData = collection.getData(); const dependency = PluginService.getLoaderDependency(pluginCompiler); let str = '\n' + black.bgGreen` ${pluginLabel} ` + bg(193).black` Entry processing ` + '\n'; // display loader watch dependencies // TODO: fix verbose of dependency after start/stop in serve/watch mode when used cache filesystem if (dependency && PluginService.isWatchMode(pluginCompiler)) { const watchFiles = dependency.getFiles(); if (watchFiles && watchFiles.size > 0) { str += '\n'; str += fg(134)`watch files:` + `\n`; // TODO: correct sort paths const files = Array.from(watchFiles).sort(); for (let file of files) { file = relativePathVerbose(file); str += `${'-'.padStart(3)} ${fg(147)(file)}` + '\n'; } } } // display assets for (let [entryAsset, { entry, assets, preloads }] of collectionData) { const entrySource = relativePathVerbose(entry.resource); const outputPath = relativePathVerbose(entry.outputPath); str += '\n'; str += bg(27).whiteBright` ENTRY ` + bg(195).black` ${entryAsset} ` + '\n'; // str += `${magenta`output:`} ${cyanBright(entry.outputPath)}\n`; // for debugging only str += `${magenta`source:`} ${cyanBright(entrySource)}\n`; str += `${magenta`output:`} ${cyanBright(outputPath)}\n`; // preload if (preloads?.length > 0) { str += fg(202)(`preloads:`) + `\n`; for (const item of preloads) { str += fg(209)(`${item.type}:`.padStart(padLevel1)) + ` ${yellowBright(item.tag)}\n`; } } // assets if (assets.length > 0) { str += green`assets:` + `\n`; } for (const item of assets) { let resource = item.resource; let resourceColor = cyan; if (item.imported) { resource = item.issuer.resource; resourceColor = gray; } let sourceFile = relativePathVerbose(resource); str += colorType(item, padLevel1) + ` ${resourceColor(sourceFile)}\n`; if (!item.inline && item.assetFile) { str += `${'->'.padStart(padLevel1)} ${item.assetFile}\n`; } // styles imported in JS if (item.imported) { str += `${''.padStart(padLevel1)} ${fg(214)`imports:`}\n`; // note: if a style is imported, then resource is an array for (let importItem of item.imports) { sourceFile = relativePathVerbose(importItem.resource); str += `${''.padStart(padChunks)} ${fg(143)(sourceFile)}\n`; str += renderAssets(importItem, padLevel3); } } else { str += renderAssets(item); } } } outToConsole(str); }; module.exports = { relativePathVerbose, compilationName, verbose, };