1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const { ConcatSource } = require("webpack-sources");
|
9 | const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
|
10 | const Template = require("./Template");
|
11 |
|
12 | const validateOptions = require("schema-utils");
|
13 | const schema = require("../schemas/plugins/BannerPlugin.json");
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | const wrapComment = str => {
|
19 | if (!str.includes("\n")) {
|
20 | return Template.toComment(str);
|
21 | }
|
22 | return `/*!\n * ${str
|
23 | .replace(/\*\//g, "* /")
|
24 | .split("\n")
|
25 | .join("\n * ")}\n */`;
|
26 | };
|
27 |
|
28 | class BannerPlugin {
|
29 | |
30 |
|
31 |
|
32 | constructor(options) {
|
33 | if (arguments.length > 1) {
|
34 | throw new Error(
|
35 | "BannerPlugin only takes one argument (pass an options object)"
|
36 | );
|
37 | }
|
38 |
|
39 | validateOptions(schema, options, "Banner Plugin");
|
40 |
|
41 | if (typeof options === "string" || typeof options === "function") {
|
42 | options = {
|
43 | banner: options
|
44 | };
|
45 | }
|
46 |
|
47 |
|
48 | this.options = options;
|
49 |
|
50 | const bannerOption = options.banner;
|
51 | if (typeof bannerOption === "function") {
|
52 | const getBanner = bannerOption;
|
53 | this.banner = this.options.raw
|
54 | ? getBanner
|
55 | : data => wrapComment(getBanner(data));
|
56 | } else {
|
57 | const banner = this.options.raw
|
58 | ? bannerOption
|
59 | : wrapComment(bannerOption);
|
60 | this.banner = () => banner;
|
61 | }
|
62 | }
|
63 |
|
64 | apply(compiler) {
|
65 | const options = this.options;
|
66 | const banner = this.banner;
|
67 | const matchObject = ModuleFilenameHelpers.matchObject.bind(
|
68 | undefined,
|
69 | options
|
70 | );
|
71 |
|
72 | compiler.hooks.compilation.tap("BannerPlugin", compilation => {
|
73 | compilation.hooks.optimizeChunkAssets.tap("BannerPlugin", chunks => {
|
74 | for (const chunk of chunks) {
|
75 | if (options.entryOnly && !chunk.canBeInitial()) {
|
76 | continue;
|
77 | }
|
78 |
|
79 | for (const file of chunk.files) {
|
80 | if (!matchObject(file)) {
|
81 | continue;
|
82 | }
|
83 |
|
84 | let basename;
|
85 | let query = "";
|
86 | let filename = file;
|
87 | const hash = compilation.hash;
|
88 | const querySplit = filename.indexOf("?");
|
89 |
|
90 | if (querySplit >= 0) {
|
91 | query = filename.substr(querySplit);
|
92 | filename = filename.substr(0, querySplit);
|
93 | }
|
94 |
|
95 | const lastSlashIndex = filename.lastIndexOf("/");
|
96 |
|
97 | if (lastSlashIndex === -1) {
|
98 | basename = filename;
|
99 | } else {
|
100 | basename = filename.substr(lastSlashIndex + 1);
|
101 | }
|
102 |
|
103 | const data = {
|
104 | hash,
|
105 | chunk,
|
106 | filename,
|
107 | basename,
|
108 | query
|
109 | };
|
110 |
|
111 | const comment = compilation.getPath(banner(data), data);
|
112 |
|
113 | compilation.assets[file] = new ConcatSource(
|
114 | comment,
|
115 | "\n",
|
116 | compilation.assets[file]
|
117 | );
|
118 | }
|
119 | }
|
120 | });
|
121 | });
|
122 | }
|
123 | }
|
124 |
|
125 | module.exports = BannerPlugin;
|