source: frontend/node_modules/webpack/lib/BannerPlugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.2 KB
Line 
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");
12
13/** @typedef {import("webpack-sources").Source} Source */
14/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
15/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */
16/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
17/** @typedef {import("./Compiler")} Compiler */
18/** @typedef {import("./Chunk")} Chunk */
19
20/** @typedef {(data: { hash?: string, chunk: Chunk, filename: string }) => string} BannerFunction */
21
22/**
23 * Wraps banner text in a JavaScript block comment, preserving multi-line
24 * formatting and escaping accidental comment terminators.
25 * @param {string} str string to wrap
26 * @returns {string} wrapped string
27 */
28const wrapComment = (str) => {
29 if (!str.includes("\n")) {
30 return Template.toComment(str);
31 }
32 return `/*!\n * ${str
33 .replace(/\*\//g, "* /")
34 .split("\n")
35 .join("\n * ")
36 .replace(/\s+\n/g, "\n")
37 .trimEnd()}\n */`;
38};
39
40const PLUGIN_NAME = "BannerPlugin";
41
42/**
43 * Prepends or appends banner text to emitted assets that match the configured
44 * file filters.
45 */
46class BannerPlugin {
47 /**
48 * Normalizes banner options and compiles the configured banner source into a
49 * function that can render per-asset banner text.
50 * @param {BannerPluginArgument} options options object
51 */
52 constructor(options) {
53 if (typeof options === "string" || typeof options === "function") {
54 options = {
55 banner: options
56 };
57 }
58
59 /** @type {BannerPluginOptions} */
60 this.options = options;
61
62 const bannerOption = options.banner;
63 if (typeof bannerOption === "function") {
64 const getBanner = bannerOption;
65 /** @type {BannerFunction} */
66 this.banner = this.options.raw
67 ? getBanner
68 : /** @type {BannerFunction} */ (data) => wrapComment(getBanner(data));
69 } else {
70 const banner = this.options.raw
71 ? bannerOption
72 : wrapComment(bannerOption);
73 /** @type {BannerFunction} */
74 this.banner = () => banner;
75 }
76 }
77
78 /**
79 * Validates the configured options and injects rendered banner comments into
80 * matching compilation assets at the configured process-assets stage.
81 * @param {Compiler} compiler the compiler instance
82 * @returns {void}
83 */
84 apply(compiler) {
85 compiler.hooks.validate.tap(PLUGIN_NAME, () => {
86 compiler.validate(
87 () => require("../schemas/plugins/BannerPlugin.json"),
88 this.options,
89 {
90 name: "Banner Plugin",
91 baseDataPath: "options"
92 },
93 (options) => require("../schemas/plugins/BannerPlugin.check")(options)
94 );
95 });
96 const options = this.options;
97 const banner = this.banner;
98 const matchObject = ModuleFilenameHelpers.matchObject.bind(
99 undefined,
100 options
101 );
102 /** @type {WeakMap<Source, { source: ConcatSource, comment: string }>} */
103 const cache = new WeakMap();
104 const stage =
105 this.options.stage || Compilation.PROCESS_ASSETS_STAGE_ADDITIONS;
106
107 compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
108 compilation.hooks.processAssets.tap({ name: PLUGIN_NAME, stage }, () => {
109 for (const chunk of compilation.chunks) {
110 if (options.entryOnly && !chunk.canBeInitial()) {
111 continue;
112 }
113
114 for (const file of chunk.files) {
115 if (!matchObject(file)) {
116 continue;
117 }
118
119 /** @type {PathDataChunk} */
120 const data = { chunk, filename: file };
121
122 const comment = compilation.getPath(
123 /** @type {string | import("./TemplatedPathPlugin").TemplatePathFn<PathDataChunk>} */
124 (banner),
125 data
126 );
127
128 compilation.updateAsset(file, (old) => {
129 const cached = cache.get(old);
130 if (!cached || cached.comment !== comment) {
131 const source = options.footer
132 ? new ConcatSource(old, "\n", comment)
133 : new ConcatSource(comment, "\n", old);
134 cache.set(old, { source, comment });
135 return source;
136 }
137 return cached.source;
138 });
139 }
140 }
141 });
142 });
143 }
144}
145
146module.exports = BannerPlugin;
Note: See TracBrowser for help on using the repository browser.