UNPKG

2.89 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 ConstDependency = require("./dependencies/ConstDependency");
9const ProvidedDependency = require("./dependencies/ProvidedDependency");
10const { approve } = require("./javascript/JavascriptParserHelpers");
11
12/** @typedef {import("./Compiler")} Compiler */
13
14class ProvidePlugin {
15 /**
16 * @param {Record<string, string | string[]>} definitions the provided identifiers
17 */
18 constructor(definitions) {
19 this.definitions = definitions;
20 }
21
22 /**
23 * Apply the plugin
24 * @param {Compiler} compiler the compiler instance
25 * @returns {void}
26 */
27 apply(compiler) {
28 const definitions = this.definitions;
29 compiler.hooks.compilation.tap(
30 "ProvidePlugin",
31 (compilation, { normalModuleFactory }) => {
32 compilation.dependencyTemplates.set(
33 ConstDependency,
34 new ConstDependency.Template()
35 );
36 compilation.dependencyFactories.set(
37 ProvidedDependency,
38 normalModuleFactory
39 );
40 compilation.dependencyTemplates.set(
41 ProvidedDependency,
42 new ProvidedDependency.Template()
43 );
44 const handler = (parser, parserOptions) => {
45 Object.keys(definitions).forEach(name => {
46 const request = [].concat(definitions[name]);
47 const splittedName = name.split(".");
48 if (splittedName.length > 0) {
49 splittedName.slice(1).forEach((_, i) => {
50 const name = splittedName.slice(0, i + 1).join(".");
51 parser.hooks.canRename.for(name).tap("ProvidePlugin", approve);
52 });
53 }
54
55 parser.hooks.expression.for(name).tap("ProvidePlugin", expr => {
56 const nameIdentifier = name.includes(".")
57 ? `__webpack_provided_${name.replace(/\./g, "_dot_")}`
58 : name;
59 const dep = new ProvidedDependency(
60 request[0],
61 nameIdentifier,
62 request.slice(1),
63 expr.range
64 );
65 dep.loc = expr.loc;
66 parser.state.module.addDependency(dep);
67 return true;
68 });
69
70 parser.hooks.call.for(name).tap("ProvidePlugin", expr => {
71 const nameIdentifier = name.includes(".")
72 ? `__webpack_provided_${name.replace(/\./g, "_dot_")}`
73 : name;
74 const dep = new ProvidedDependency(
75 request[0],
76 nameIdentifier,
77 request.slice(1),
78 expr.callee.range
79 );
80 dep.loc = expr.callee.loc;
81 parser.state.module.addDependency(dep);
82 parser.walkExpressions(expr.arguments);
83 return true;
84 });
85 });
86 };
87 normalModuleFactory.hooks.parser
88 .for("javascript/auto")
89 .tap("ProvidePlugin", handler);
90 normalModuleFactory.hooks.parser
91 .for("javascript/dynamic")
92 .tap("ProvidePlugin", handler);
93 normalModuleFactory.hooks.parser
94 .for("javascript/esm")
95 .tap("ProvidePlugin", handler);
96 }
97 );
98 }
99}
100
101module.exports = ProvidePlugin;