You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
7.8 KiB

4 years ago
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const Compiler = require("./Compiler");
  7. const MultiCompiler = require("./MultiCompiler");
  8. const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin");
  9. const WebpackOptionsApply = require("./WebpackOptionsApply");
  10. const WebpackOptionsDefaulter = require("./WebpackOptionsDefaulter");
  11. const validateSchema = require("./validateSchema");
  12. const WebpackOptionsValidationError = require("./WebpackOptionsValidationError");
  13. const webpackOptionsSchema = require("../schemas/WebpackOptions.json");
  14. const RemovedPluginError = require("./RemovedPluginError");
  15. const version = require("../package.json").version;
  16. /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
  17. /**
  18. * @param {WebpackOptions} options options object
  19. * @param {function(Error=, Stats=): void=} callback callback
  20. * @returns {Compiler | MultiCompiler} the compiler object
  21. */
  22. const webpack = (options, callback) => {
  23. const webpackOptionsValidationErrors = validateSchema(
  24. webpackOptionsSchema,
  25. options
  26. );
  27. if (webpackOptionsValidationErrors.length) {
  28. throw new WebpackOptionsValidationError(webpackOptionsValidationErrors);
  29. }
  30. let compiler;
  31. if (Array.isArray(options)) {
  32. compiler = new MultiCompiler(
  33. Array.from(options).map(options => webpack(options))
  34. );
  35. } else if (typeof options === "object") {
  36. options = new WebpackOptionsDefaulter().process(options);
  37. compiler = new Compiler(options.context);
  38. compiler.options = options;
  39. new NodeEnvironmentPlugin({
  40. infrastructureLogging: options.infrastructureLogging
  41. }).apply(compiler);
  42. if (options.plugins && Array.isArray(options.plugins)) {
  43. for (const plugin of options.plugins) {
  44. if (typeof plugin === "function") {
  45. plugin.call(compiler, compiler);
  46. } else {
  47. plugin.apply(compiler);
  48. }
  49. }
  50. }
  51. compiler.hooks.environment.call();
  52. compiler.hooks.afterEnvironment.call();
  53. compiler.options = new WebpackOptionsApply().process(options, compiler);
  54. } else {
  55. throw new Error("Invalid argument: options");
  56. }
  57. if (callback) {
  58. if (typeof callback !== "function") {
  59. throw new Error("Invalid argument: callback");
  60. }
  61. if (
  62. options.watch === true ||
  63. (Array.isArray(options) && options.some(o => o.watch))
  64. ) {
  65. const watchOptions = Array.isArray(options)
  66. ? options.map(o => o.watchOptions || {})
  67. : options.watchOptions || {};
  68. return compiler.watch(watchOptions, callback);
  69. }
  70. compiler.run(callback);
  71. }
  72. return compiler;
  73. };
  74. exports = module.exports = webpack;
  75. exports.version = version;
  76. webpack.WebpackOptionsDefaulter = WebpackOptionsDefaulter;
  77. webpack.WebpackOptionsApply = WebpackOptionsApply;
  78. webpack.Compiler = Compiler;
  79. webpack.MultiCompiler = MultiCompiler;
  80. webpack.NodeEnvironmentPlugin = NodeEnvironmentPlugin;
  81. // @ts-ignore Global @this directive is not supported
  82. webpack.validate = validateSchema.bind(this, webpackOptionsSchema);
  83. webpack.validateSchema = validateSchema;
  84. webpack.WebpackOptionsValidationError = WebpackOptionsValidationError;
  85. const exportPlugins = (obj, mappings) => {
  86. for (const name of Object.keys(mappings)) {
  87. Object.defineProperty(obj, name, {
  88. configurable: false,
  89. enumerable: true,
  90. get: mappings[name]
  91. });
  92. }
  93. };
  94. exportPlugins(exports, {
  95. AutomaticPrefetchPlugin: () => require("./AutomaticPrefetchPlugin"),
  96. BannerPlugin: () => require("./BannerPlugin"),
  97. CachePlugin: () => require("./CachePlugin"),
  98. ContextExclusionPlugin: () => require("./ContextExclusionPlugin"),
  99. ContextReplacementPlugin: () => require("./ContextReplacementPlugin"),
  100. DefinePlugin: () => require("./DefinePlugin"),
  101. Dependency: () => require("./Dependency"),
  102. DllPlugin: () => require("./DllPlugin"),
  103. DllReferencePlugin: () => require("./DllReferencePlugin"),
  104. EnvironmentPlugin: () => require("./EnvironmentPlugin"),
  105. EvalDevToolModulePlugin: () => require("./EvalDevToolModulePlugin"),
  106. EvalSourceMapDevToolPlugin: () => require("./EvalSourceMapDevToolPlugin"),
  107. ExtendedAPIPlugin: () => require("./ExtendedAPIPlugin"),
  108. ExternalsPlugin: () => require("./ExternalsPlugin"),
  109. HashedModuleIdsPlugin: () => require("./HashedModuleIdsPlugin"),
  110. HotModuleReplacementPlugin: () => require("./HotModuleReplacementPlugin"),
  111. IgnorePlugin: () => require("./IgnorePlugin"),
  112. LibraryTemplatePlugin: () => require("./LibraryTemplatePlugin"),
  113. LoaderOptionsPlugin: () => require("./LoaderOptionsPlugin"),
  114. LoaderTargetPlugin: () => require("./LoaderTargetPlugin"),
  115. MemoryOutputFileSystem: () => require("./MemoryOutputFileSystem"),
  116. Module: () => require("./Module"),
  117. ModuleFilenameHelpers: () => require("./ModuleFilenameHelpers"),
  118. NamedChunksPlugin: () => require("./NamedChunksPlugin"),
  119. NamedModulesPlugin: () => require("./NamedModulesPlugin"),
  120. NoEmitOnErrorsPlugin: () => require("./NoEmitOnErrorsPlugin"),
  121. NormalModuleReplacementPlugin: () =>
  122. require("./NormalModuleReplacementPlugin"),
  123. PrefetchPlugin: () => require("./PrefetchPlugin"),
  124. ProgressPlugin: () => require("./ProgressPlugin"),
  125. ProvidePlugin: () => require("./ProvidePlugin"),
  126. SetVarMainTemplatePlugin: () => require("./SetVarMainTemplatePlugin"),
  127. SingleEntryPlugin: () => require("./SingleEntryPlugin"),
  128. SourceMapDevToolPlugin: () => require("./SourceMapDevToolPlugin"),
  129. Stats: () => require("./Stats"),
  130. Template: () => require("./Template"),
  131. UmdMainTemplatePlugin: () => require("./UmdMainTemplatePlugin"),
  132. WatchIgnorePlugin: () => require("./WatchIgnorePlugin")
  133. });
  134. exportPlugins((exports.dependencies = {}), {
  135. DependencyReference: () => require("./dependencies/DependencyReference")
  136. });
  137. exportPlugins((exports.optimize = {}), {
  138. AggressiveMergingPlugin: () => require("./optimize/AggressiveMergingPlugin"),
  139. AggressiveSplittingPlugin: () =>
  140. require("./optimize/AggressiveSplittingPlugin"),
  141. ChunkModuleIdRangePlugin: () =>
  142. require("./optimize/ChunkModuleIdRangePlugin"),
  143. LimitChunkCountPlugin: () => require("./optimize/LimitChunkCountPlugin"),
  144. MinChunkSizePlugin: () => require("./optimize/MinChunkSizePlugin"),
  145. ModuleConcatenationPlugin: () =>
  146. require("./optimize/ModuleConcatenationPlugin"),
  147. OccurrenceOrderPlugin: () => require("./optimize/OccurrenceOrderPlugin"),
  148. OccurrenceModuleOrderPlugin: () =>
  149. require("./optimize/OccurrenceModuleOrderPlugin"),
  150. OccurrenceChunkOrderPlugin: () =>
  151. require("./optimize/OccurrenceChunkOrderPlugin"),
  152. RuntimeChunkPlugin: () => require("./optimize/RuntimeChunkPlugin"),
  153. SideEffectsFlagPlugin: () => require("./optimize/SideEffectsFlagPlugin"),
  154. SplitChunksPlugin: () => require("./optimize/SplitChunksPlugin")
  155. });
  156. exportPlugins((exports.web = {}), {
  157. FetchCompileWasmTemplatePlugin: () =>
  158. require("./web/FetchCompileWasmTemplatePlugin"),
  159. JsonpTemplatePlugin: () => require("./web/JsonpTemplatePlugin")
  160. });
  161. exportPlugins((exports.webworker = {}), {
  162. WebWorkerTemplatePlugin: () => require("./webworker/WebWorkerTemplatePlugin")
  163. });
  164. exportPlugins((exports.node = {}), {
  165. NodeTemplatePlugin: () => require("./node/NodeTemplatePlugin"),
  166. ReadFileCompileWasmTemplatePlugin: () =>
  167. require("./node/ReadFileCompileWasmTemplatePlugin")
  168. });
  169. exportPlugins((exports.debug = {}), {
  170. ProfilingPlugin: () => require("./debug/ProfilingPlugin")
  171. });
  172. exportPlugins((exports.util = {}), {
  173. createHash: () => require("./util/createHash")
  174. });
  175. const defineMissingPluginError = (namespace, pluginName, errorMessage) => {
  176. Object.defineProperty(namespace, pluginName, {
  177. configurable: false,
  178. enumerable: true,
  179. get() {
  180. throw new RemovedPluginError(errorMessage);
  181. }
  182. });
  183. };
  184. // TODO remove in webpack 5
  185. defineMissingPluginError(
  186. exports.optimize,
  187. "UglifyJsPlugin",
  188. "webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead."
  189. );
  190. // TODO remove in webpack 5
  191. defineMissingPluginError(
  192. exports.optimize,
  193. "CommonsChunkPlugin",
  194. "webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead."
  195. );