package.lib.webpack.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webpack Show documentation
Show all versions of webpack Show documentation
Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
The newest version!
/*
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} 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=} callback callback
* @returns {Compiler} the compiler object
*/
/**
* @callback WebpackFunctionMulti
* @param {ReadonlyArray & MultiCompilerOptions} options options objects
* @param {Callback=} callback callback
* @returns {MultiCompiler} the multi compiler object
*/
/**
* @template T
* @param {Array | T} options options
* @returns {Array} array of options
*/
const asArray = options =>
Array.isArray(options) ? Array.from(options) : [options];
const webpack = /** @type {WebpackFunctionSingle & WebpackFunctionMulti} */ (
/**
* @param {WebpackOptions | (ReadonlyArray & MultiCompilerOptions)} options options
* @param {Callback & Callback=} 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;