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.

150 lines (120 loc) 3.82 kB
const path = require('path'); const { readDirRecursiveSync } = require('../Common/FileUtils'); const PluginService = require('../Plugin/PluginService'); /** * Dependencies in code for watching a changes. */ class Dependency { /** The file system used by Webpack */ fileSystem = null; files = new Set(); directories = new Set(); watchFiles = {}; entryFiles = new Set(); excludeDirs = []; loaderContext = null; pluginCompiler = null; constructor(compiler) { // create instance only to avoid cycle dependencies by initialisation this.pluginCompiler = compiler; } init({ loaderContext, loaderOption }) { this.loaderContext = loaderContext; this.loaderOption = loaderOption; if (!PluginService.isWatchMode(this.pluginCompiler)) return; let watchFile = this.loaderContext.resourcePath; PluginService.setDependencyInstance(this.pluginCompiler, this); this.fileSystem = this.loaderContext.fs.fileSystem; this.watchFiles = this.loaderOption.getWatchFiles(); this.entryFiles = PluginService.getPluginContext(this.pluginCompiler).assetEntry.getEntryFiles(); this.excludeDirs = []; this.entryFiles.forEach((entryFile) => { let entryDir = path.dirname(entryFile) + path.sep; if (!watchFile.startsWith(entryDir)) this.excludeDirs.push(entryDir); }); this.addFileToWatch = this.addFileToWatch.bind(this); const fs = this.fileSystem; const { includes, excludes, paths = [] } = this.watchFiles; for (const watchDir of paths) { const files = readDirRecursiveSync(watchDir, { fs, includes, excludes }); files.forEach(this.addFileToWatch); } const customWatchFiles = this.loaderOption.getCustomWatchFiles(); if (customWatchFiles.length > 0) customWatchFiles.forEach(this.addFileToWatch); } /** * Check whether the adding file is watchable. * * @param {string} watchFile * @return boolean */ isFileWatchable(watchFile) { if (!PluginService.isWatchMode(this.pluginCompiler)) return false; let { includes, excludes } = this.watchFiles; let isIncluded = includes ? includes.some((item) => item.test(watchFile)) : true; let isExcluded = excludes ? excludes.some((item) => item.test(watchFile)) : false; return isIncluded && !isExcluded; } /** * @param {string} dir */ addDir(dir) { this.directories.add(dir); } /** * @return {Set<any>} */ getFiles() { return this.files; } /** * Add file using include & exclude filter. * * @param {string} file */ addFile(file) { if (this.isFileWatchable(file)) { this.addFileToWatch(file); } } /** * @param {string} file */ addFileToWatch(file) { this.files.add(file); // delete the file from require.cache to reload cached file after change if (file in require.cache) { delete require.cache[file]; } } /** * @param {string} file */ removeFile(file) { this.files.delete(file); } /** * Enable Webpack watching for dependencies. */ watch() { if (!PluginService.isWatchMode(this.pluginCompiler)) return; const { loaderContext, excludeDirs } = this; this.directories.forEach(loaderContext.addContextDependency); for (let file of this.files) { let isExcluded = excludeDirs.findIndex((dirname) => file.startsWith(dirname)) > -1; if (isExcluded || this.entryFiles.has(file)) { // ignore all files from other entry directory or the current entry file, because it is already in the list continue; } loaderContext.addDependency(file); } } /** * Called when the compiler is closing or a watching compilation has stopped. */ shutdown() { this.files.clear(); this.directories.clear(); } } module.exports = Dependency;