UNPKG

4.3 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
4*/
5
6"use strict";
7
8const ExternalsPlugin = require("../ExternalsPlugin");
9const RuntimeGlobals = require("../RuntimeGlobals");
10const createSchemaValidation = require("../util/create-schema-validation");
11const FallbackDependency = require("./FallbackDependency");
12const FallbackItemDependency = require("./FallbackItemDependency");
13const FallbackModuleFactory = require("./FallbackModuleFactory");
14const RemoteModule = require("./RemoteModule");
15const RemoteRuntimeModule = require("./RemoteRuntimeModule");
16const RemoteToExternalDependency = require("./RemoteToExternalDependency");
17const { parseOptions } = require("./options");
18
19/** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").ContainerReferencePluginOptions} ContainerReferencePluginOptions */
20/** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").RemotesConfig} RemotesConfig */
21/** @typedef {import("../Compiler")} Compiler */
22
23const validate = createSchemaValidation(
24 require("../../schemas/plugins/container/ContainerReferencePlugin.check.js"),
25 () =>
26 require("../../schemas/plugins/container/ContainerReferencePlugin.json"),
27 {
28 name: "Container Reference Plugin",
29 baseDataPath: "options"
30 }
31);
32
33const slashCode = "/".charCodeAt(0);
34
35class ContainerReferencePlugin {
36 /**
37 * @param {ContainerReferencePluginOptions} options options
38 */
39 constructor(options) {
40 validate(options);
41
42 this._remoteType = options.remoteType;
43 this._remotes = parseOptions(
44 options.remotes,
45 item => ({
46 external: Array.isArray(item) ? item : [item],
47 shareScope: options.shareScope || "default"
48 }),
49 item => ({
50 external: Array.isArray(item.external)
51 ? item.external
52 : [item.external],
53 shareScope: item.shareScope || options.shareScope || "default"
54 })
55 );
56 }
57
58 /**
59 * Apply the plugin
60 * @param {Compiler} compiler the compiler instance
61 * @returns {void}
62 */
63 apply(compiler) {
64 const { _remotes: remotes, _remoteType: remoteType } = this;
65
66 /** @type {Record<string, string>} */
67 const remoteExternals = {};
68 for (const [key, config] of remotes) {
69 let i = 0;
70 for (const external of config.external) {
71 if (external.startsWith("internal ")) continue;
72 remoteExternals[
73 `webpack/container/reference/${key}${i ? `/fallback-${i}` : ""}`
74 ] = external;
75 i++;
76 }
77 }
78
79 new ExternalsPlugin(remoteType, remoteExternals).apply(compiler);
80
81 compiler.hooks.compilation.tap(
82 "ContainerReferencePlugin",
83 (compilation, { normalModuleFactory }) => {
84 compilation.dependencyFactories.set(
85 RemoteToExternalDependency,
86 normalModuleFactory
87 );
88
89 compilation.dependencyFactories.set(
90 FallbackItemDependency,
91 normalModuleFactory
92 );
93
94 compilation.dependencyFactories.set(
95 FallbackDependency,
96 new FallbackModuleFactory()
97 );
98
99 normalModuleFactory.hooks.factorize.tap(
100 "ContainerReferencePlugin",
101 data => {
102 if (!data.request.includes("!")) {
103 for (const [key, config] of remotes) {
104 if (
105 data.request.startsWith(`${key}`) &&
106 (data.request.length === key.length ||
107 data.request.charCodeAt(key.length) === slashCode)
108 ) {
109 return new RemoteModule(
110 data.request,
111 config.external.map((external, i) =>
112 external.startsWith("internal ")
113 ? external.slice(9)
114 : `webpack/container/reference/${key}${
115 i ? `/fallback-${i}` : ""
116 }`
117 ),
118 `.${data.request.slice(key.length)}`,
119 config.shareScope
120 );
121 }
122 }
123 }
124 }
125 );
126
127 compilation.hooks.runtimeRequirementInTree
128 .for(RuntimeGlobals.ensureChunkHandlers)
129 .tap("ContainerReferencePlugin", (chunk, set) => {
130 set.add(RuntimeGlobals.module);
131 set.add(RuntimeGlobals.moduleFactoriesAddOnly);
132 set.add(RuntimeGlobals.hasOwnProperty);
133 set.add(RuntimeGlobals.initializeSharing);
134 set.add(RuntimeGlobals.shareScopeMap);
135 compilation.addRuntimeModule(chunk, new RemoteRuntimeModule());
136 });
137 }
138 );
139 }
140}
141
142module.exports = ContainerReferencePlugin;