CLIPlugin.js (3807B)
1 class CLIPlugin { 2 constructor(options) { 3 this.options = options; 4 } 5 6 setupHotPlugin(compiler) { 7 const { HotModuleReplacementPlugin } = compiler.webpack || require("webpack"); 8 const hotModuleReplacementPlugin = Boolean( 9 compiler.options.plugins.find((plugin) => plugin instanceof HotModuleReplacementPlugin), 10 ); 11 12 if (!hotModuleReplacementPlugin) { 13 new HotModuleReplacementPlugin().apply(compiler); 14 } 15 } 16 17 setupPrefetchPlugin(compiler) { 18 const { PrefetchPlugin } = compiler.webpack || require("webpack"); 19 20 new PrefetchPlugin(null, this.options.prefetch).apply(compiler); 21 } 22 23 async setupBundleAnalyzerPlugin(compiler) { 24 // eslint-disable-next-line node/no-extraneous-require 25 const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); 26 const bundleAnalyzerPlugin = Boolean( 27 compiler.options.plugins.find((plugin) => plugin instanceof BundleAnalyzerPlugin), 28 ); 29 30 if (!bundleAnalyzerPlugin) { 31 new BundleAnalyzerPlugin().apply(compiler); 32 } 33 } 34 35 setupProgressPlugin(compiler) { 36 const { ProgressPlugin } = compiler.webpack || require("webpack"); 37 const progressPlugin = Boolean( 38 compiler.options.plugins.find((plugin) => plugin instanceof ProgressPlugin), 39 ); 40 41 if (!progressPlugin) { 42 new ProgressPlugin({ 43 profile: this.options.progress === "profile", 44 }).apply(compiler); 45 } 46 } 47 48 setupHelpfulOutput(compiler) { 49 const pluginName = "webpack-cli"; 50 const getCompilationName = () => (compiler.name ? `'${compiler.name}'` : ""); 51 const logCompilation = (message) => { 52 if (process.env.WEBPACK_CLI_START_FINISH_FORCE_LOG) { 53 process.stderr.write(message); 54 } else { 55 this.logger.log(message); 56 } 57 }; 58 59 const { configPath } = this.options; 60 61 compiler.hooks.run.tap(pluginName, () => { 62 const name = getCompilationName(); 63 64 logCompilation(`Compiler${name ? ` ${name}` : ""} starting... `); 65 66 if (configPath) { 67 this.logger.log(`Compiler${name ? ` ${name}` : ""} is using config: '${configPath}'`); 68 } 69 }); 70 71 compiler.hooks.watchRun.tap(pluginName, (compiler) => { 72 const { bail, watch } = compiler.options; 73 74 if (bail && watch) { 75 this.logger.warn( 76 'You are using "bail" with "watch". "bail" will still exit webpack when the first error is found.', 77 ); 78 } 79 80 const name = getCompilationName(); 81 82 logCompilation(`Compiler${name ? ` ${name}` : ""} starting... `); 83 84 if (configPath) { 85 this.logger.log(`Compiler${name ? ` ${name}` : ""} is using config: '${configPath}'`); 86 } 87 }); 88 89 compiler.hooks.invalid.tap(pluginName, (filename, changeTime) => { 90 const date = new Date(changeTime * 1000); 91 92 this.logger.log(`File '${filename}' was modified`); 93 this.logger.log(`Changed time is ${date} (timestamp is ${changeTime})`); 94 }); 95 96 (compiler.webpack ? compiler.hooks.afterDone : compiler.hooks.done).tap(pluginName, () => { 97 const name = getCompilationName(); 98 99 logCompilation(`Compiler${name ? ` ${name}` : ""} finished`); 100 101 process.nextTick(() => { 102 if (compiler.watchMode) { 103 this.logger.log(`Compiler${name ? `${name}` : ""} is watching files for updates...`); 104 } 105 }); 106 }); 107 } 108 109 apply(compiler) { 110 this.logger = compiler.getInfrastructureLogger("webpack-cli"); 111 112 if (this.options.progress) { 113 this.setupProgressPlugin(compiler); 114 } 115 116 if (this.options.hot) { 117 this.setupHotPlugin(compiler); 118 } 119 120 if (this.options.prefetch) { 121 this.setupPrefetchPlugin(compiler); 122 } 123 124 if (this.options.analyze) { 125 this.setupBundleAnalyzerPlugin(compiler); 126 } 127 128 this.setupHelpfulOutput(compiler); 129 } 130 } 131 132 module.exports = CLIPlugin;