UNPKG

2.75 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { ConcatSource } = require("webpack-sources");
9const Compilation = require("./Compilation");
10const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
11const Template = require("./Template");
12const createSchemaValidation = require("./util/create-schema-validation");
13
14/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
15/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */
16/** @typedef {import("./Compiler")} Compiler */
17
18const validate = createSchemaValidation(
19 require("../schemas/plugins/BannerPlugin.check.js"),
20 () => require("../schemas/plugins/BannerPlugin.json"),
21 {
22 name: "Banner Plugin",
23 baseDataPath: "options"
24 }
25);
26
27const wrapComment = str => {
28 if (!str.includes("\n")) {
29 return Template.toComment(str);
30 }
31 return `/*!\n * ${str
32 .replace(/\*\//g, "* /")
33 .split("\n")
34 .join("\n * ")
35 .replace(/\s+\n/g, "\n")
36 .trimRight()}\n */`;
37};
38
39class BannerPlugin {
40 /**
41 * @param {BannerPluginArgument} options options object
42 */
43 constructor(options) {
44 if (typeof options === "string" || typeof options === "function") {
45 options = {
46 banner: options
47 };
48 }
49
50 validate(options);
51
52 this.options = options;
53
54 const bannerOption = options.banner;
55 if (typeof bannerOption === "function") {
56 const getBanner = bannerOption;
57 this.banner = this.options.raw
58 ? getBanner
59 : data => wrapComment(getBanner(data));
60 } else {
61 const banner = this.options.raw
62 ? bannerOption
63 : wrapComment(bannerOption);
64 this.banner = () => banner;
65 }
66 }
67
68 /**
69 * Apply the plugin
70 * @param {Compiler} compiler the compiler instance
71 * @returns {void}
72 */
73 apply(compiler) {
74 const options = this.options;
75 const banner = this.banner;
76 const matchObject = ModuleFilenameHelpers.matchObject.bind(
77 undefined,
78 options
79 );
80
81 compiler.hooks.compilation.tap("BannerPlugin", compilation => {
82 compilation.hooks.processAssets.tap(
83 {
84 name: "BannerPlugin",
85 stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
86 },
87 () => {
88 for (const chunk of compilation.chunks) {
89 if (options.entryOnly && !chunk.canBeInitial()) {
90 continue;
91 }
92
93 for (const file of chunk.files) {
94 if (!matchObject(file)) {
95 continue;
96 }
97
98 const data = {
99 chunk,
100 filename: file
101 };
102
103 const comment = compilation.getPath(banner, data);
104
105 compilation.updateAsset(
106 file,
107 old => new ConcatSource(comment, "\n", old)
108 );
109 }
110 }
111 }
112 );
113 });
114 }
115}
116
117module.exports = BannerPlugin;