123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const util = require("util");
- const webpackOptionsSchemaCheck = require("../schemas/WebpackOptions.check.js");
- const webpackOptionsSchema = require("../schemas/WebpackOptions.json");
- const Compiler = require("./Compiler");
- const MultiCompiler = require("./MultiCompiler");
- const WebpackOptionsApply = require("./WebpackOptionsApply");
- const {
- applyWebpackOptionsDefaults,
- applyWebpackOptionsBaseDefaults
- } = require("./config/defaults");
- const { getNormalizedWebpackOptions } = require("./config/normalization");
- const NodeEnvironmentPlugin = require("./node/NodeEnvironmentPlugin");
- const memoize = require("./util/memoize");
- /** @typedef {import("../declarations/WebpackOptions").WebpackOptions} WebpackOptions */
- /** @typedef {import("../declarations/WebpackOptions").WebpackPluginFunction} WebpackPluginFunction */
- /** @typedef {import("./Compiler").WatchOptions} WatchOptions */
- /** @typedef {import("./MultiCompiler").MultiCompilerOptions} MultiCompilerOptions */
- /** @typedef {import("./MultiStats")} MultiStats */
- /** @typedef {import("./Stats")} Stats */
- const getValidateSchema = memoize(() => require("./validateSchema"));
- /**
- * @template T
- * @callback Callback
- * @param {Error | null} err
- * @param {T=} stats
- * @returns {void}
- */
- /**
- * @param {ReadonlyArray<WebpackOptions>} childOptions options array
- * @param {MultiCompilerOptions} options options
- * @returns {MultiCompiler} a multi-compiler
- */
- const createMultiCompiler = (childOptions, options) => {
- const compilers = childOptions.map((options, index) =>
- createCompiler(options, index)
- );
- const compiler = new MultiCompiler(compilers, options);
- for (const childCompiler of compilers) {
- if (childCompiler.options.dependencies) {
- compiler.setDependencies(
- childCompiler,
- childCompiler.options.dependencies
- );
- }
- }
- return compiler;
- };
- /**
- * @param {WebpackOptions} rawOptions options object
- * @param {number} [compilerIndex] index of compiler
- * @returns {Compiler} a compiler
- */
- const createCompiler = (rawOptions, compilerIndex) => {
- const options = getNormalizedWebpackOptions(rawOptions);
- applyWebpackOptionsBaseDefaults(options);
- const compiler = new Compiler(
- /** @type {string} */ (options.context),
- options
- );
- new NodeEnvironmentPlugin({
- infrastructureLogging: options.infrastructureLogging
- }).apply(compiler);
- if (Array.isArray(options.plugins)) {
- for (const plugin of options.plugins) {
- if (typeof plugin === "function") {
- /** @type {WebpackPluginFunction} */
- (plugin).call(compiler, compiler);
- } else if (plugin) {
- plugin.apply(compiler);
- }
- }
- }
- const resolvedDefaultOptions = applyWebpackOptionsDefaults(
- options,
- compilerIndex
- );
- if (resolvedDefaultOptions.platform) {
- compiler.platform = resolvedDefaultOptions.platform;
- }
- compiler.hooks.environment.call();
- compiler.hooks.afterEnvironment.call();
- new WebpackOptionsApply().process(options, compiler);
- compiler.hooks.initialize.call();
- return compiler;
- };
- /**
- * @callback WebpackFunctionSingle
- * @param {WebpackOptions} options options object
- * @param {Callback<Stats>=} callback callback
- * @returns {Compiler} the compiler object
- */
- /**
- * @callback WebpackFunctionMulti
- * @param {ReadonlyArray<WebpackOptions> & MultiCompilerOptions} options options objects
- * @param {Callback<MultiStats>=} callback callback
- * @returns {MultiCompiler} the multi compiler object
- */
- /**
- * @template T
- * @param {Array<T> | T} options options
- * @returns {Array<T>} array of options
- */
- const asArray = options =>
- Array.isArray(options) ? Array.from(options) : [options];
- const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ (
- /**
- * @param {WebpackOptions | (ReadonlyArray<WebpackOptions> & MultiCompilerOptions)} options options
- * @param {Callback<Stats> & Callback<MultiStats>=} callback callback
- * @returns {Compiler | MultiCompiler | null} Compiler or MultiCompiler
- */
- (options, callback) => {
- const create = () => {
- if (!asArray(options).every(webpackOptionsSchemaCheck)) {
- getValidateSchema()(webpackOptionsSchema, options);
- util.deprecate(
- () => {},
- "webpack bug: Pre-compiled schema reports error while real schema is happy. This has performance drawbacks.",
- "DEP_WEBPACK_PRE_COMPILED_SCHEMA_INVALID"
- )();
- }
- /** @type {MultiCompiler|Compiler} */
- let compiler;
- /** @type {boolean | undefined} */
- let watch = false;
- /** @type {WatchOptions|WatchOptions[]} */
- let watchOptions;
- if (Array.isArray(options)) {
- /** @type {MultiCompiler} */
- compiler = createMultiCompiler(
- options,
- /** @type {MultiCompilerOptions} */ (options)
- );
- watch = options.some(options => options.watch);
- watchOptions = options.map(options => options.watchOptions || {});
- } else {
- const webpackOptions = /** @type {WebpackOptions} */ (options);
- /** @type {Compiler} */
- compiler = createCompiler(webpackOptions);
- watch = webpackOptions.watch;
- watchOptions = webpackOptions.watchOptions || {};
- }
- return { compiler, watch, watchOptions };
- };
- if (callback) {
- try {
- const { compiler, watch, watchOptions } = create();
- if (watch) {
- compiler.watch(watchOptions, callback);
- } else {
- compiler.run((err, stats) => {
- compiler.close(err2 => {
- callback(
- err || err2,
- /** @type {options extends WebpackOptions ? Stats : MultiStats} */
- (stats)
- );
- });
- });
- }
- return compiler;
- } catch (err) {
- process.nextTick(() => callback(/** @type {Error} */ (err)));
- return null;
- }
- } else {
- const { compiler, watch } = create();
- if (watch) {
- util.deprecate(
- () => {},
- "A 'callback' argument needs to be provided to the 'webpack(options, callback)' function when the 'watch' option is set. There is no way to handle the 'watch' option without a callback.",
- "DEP_WEBPACK_WATCH_WITHOUT_CALLBACK"
- )();
- }
- return compiler;
- }
- }
- );
- module.exports = webpack;
|