All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.lib.BannerPlugin.js Maven / Gradle / Ivy

Go to download

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 { ConcatSource } = require("webpack-sources");
const Compilation = require("./Compilation");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const Template = require("./Template");
const createSchemaValidation = require("./util/create-schema-validation");

/** @typedef {import("../declarations/plugins/BannerPlugin").BannerFunction} BannerFunction */
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */
/** @typedef {import("./Compiler")} Compiler */

const validate = createSchemaValidation(
	require("../schemas/plugins/BannerPlugin.check.js"),
	() => require("../schemas/plugins/BannerPlugin.json"),
	{
		name: "Banner Plugin",
		baseDataPath: "options"
	}
);

/**
 * @param {string} str string to wrap
 * @returns {string} wrapped string
 */
const wrapComment = str => {
	if (!str.includes("\n")) {
		return Template.toComment(str);
	}
	return `/*!\n * ${str
		.replace(/\*\//g, "* /")
		.split("\n")
		.join("\n * ")
		.replace(/\s+\n/g, "\n")
		.trimEnd()}\n */`;
};

class BannerPlugin {
	/**
	 * @param {BannerPluginArgument} options options object
	 */
	constructor(options) {
		if (typeof options === "string" || typeof options === "function") {
			options = {
				banner: options
			};
		}

		validate(options);

		this.options = options;

		const bannerOption = options.banner;
		if (typeof bannerOption === "function") {
			const getBanner = bannerOption;
			this.banner = this.options.raw
				? getBanner
				: /** @type {BannerFunction} */ data => wrapComment(getBanner(data));
		} else {
			const banner = this.options.raw
				? bannerOption
				: wrapComment(bannerOption);
			this.banner = () => banner;
		}
	}

	/**
	 * Apply the plugin
	 * @param {Compiler} compiler the compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		const options = this.options;
		const banner = this.banner;
		const matchObject = ModuleFilenameHelpers.matchObject.bind(
			undefined,
			options
		);
		const cache = new WeakMap();
		const stage =
			this.options.stage || Compilation.PROCESS_ASSETS_STAGE_ADDITIONS;

		compiler.hooks.compilation.tap("BannerPlugin", compilation => {
			compilation.hooks.processAssets.tap(
				{
					name: "BannerPlugin",
					stage
				},
				() => {
					for (const chunk of compilation.chunks) {
						if (options.entryOnly && !chunk.canBeInitial()) {
							continue;
						}

						for (const file of chunk.files) {
							if (!matchObject(file)) {
								continue;
							}

							const data = {
								chunk,
								filename: file
							};

							const comment = compilation.getPath(banner, data);

							compilation.updateAsset(file, old => {
								let cached = cache.get(old);
								if (!cached || cached.comment !== comment) {
									const source = options.footer
										? new ConcatSource(old, "\n", comment)
										: new ConcatSource(comment, "\n", old);
									cache.set(old, { source, comment });
									return source;
								}
								return cached.source;
							});
						}
					}
				}
			);
		});
	}
}

module.exports = BannerPlugin;




© 2015 - 2024 Weber Informatics LLC | Privacy Policy