1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const ExternalModule = require("./ExternalModule");
|
8 |
|
9 | class ExternalModuleFactoryPlugin {
|
10 | constructor(type, externals) {
|
11 | this.type = type;
|
12 | this.externals = externals;
|
13 | }
|
14 |
|
15 | apply(normalModuleFactory) {
|
16 | const globalType = this.type;
|
17 | normalModuleFactory.hooks.factory.tap(
|
18 | "ExternalModuleFactoryPlugin",
|
19 | factory => (data, callback) => {
|
20 | const context = data.context;
|
21 | const dependency = data.dependencies[0];
|
22 |
|
23 | const handleExternal = (value, type, callback) => {
|
24 | if (typeof type === "function") {
|
25 | callback = type;
|
26 | type = undefined;
|
27 | }
|
28 | if (value === false) return factory(data, callback);
|
29 | if (value === true) value = dependency.request;
|
30 | if (type === undefined && /^[a-z0-9]+ /.test(value)) {
|
31 | const idx = value.indexOf(" ");
|
32 | type = value.substr(0, idx);
|
33 | value = value.substr(idx + 1);
|
34 | }
|
35 | callback(
|
36 | null,
|
37 | new ExternalModule(value, type || globalType, dependency.request)
|
38 | );
|
39 | return true;
|
40 | };
|
41 |
|
42 | const handleExternals = (externals, callback) => {
|
43 | if (typeof externals === "string") {
|
44 | if (externals === dependency.request) {
|
45 | return handleExternal(dependency.request, callback);
|
46 | }
|
47 | } else if (Array.isArray(externals)) {
|
48 | let i = 0;
|
49 | const next = () => {
|
50 | let asyncFlag;
|
51 | const handleExternalsAndCallback = (err, module) => {
|
52 | if (err) return callback(err);
|
53 | if (!module) {
|
54 | if (asyncFlag) {
|
55 | asyncFlag = false;
|
56 | return;
|
57 | }
|
58 | return next();
|
59 | }
|
60 | callback(null, module);
|
61 | };
|
62 |
|
63 | do {
|
64 | asyncFlag = true;
|
65 | if (i >= externals.length) return callback();
|
66 | handleExternals(externals[i++], handleExternalsAndCallback);
|
67 | } while (!asyncFlag);
|
68 | asyncFlag = false;
|
69 | };
|
70 |
|
71 | next();
|
72 | return;
|
73 | } else if (externals instanceof RegExp) {
|
74 | if (externals.test(dependency.request)) {
|
75 | return handleExternal(dependency.request, callback);
|
76 | }
|
77 | } else if (typeof externals === "function") {
|
78 | externals.call(
|
79 | null,
|
80 | context,
|
81 | dependency.request,
|
82 | (err, value, type) => {
|
83 | if (err) return callback(err);
|
84 | if (value !== undefined) {
|
85 | handleExternal(value, type, callback);
|
86 | } else {
|
87 | callback();
|
88 | }
|
89 | }
|
90 | );
|
91 | return;
|
92 | } else if (
|
93 | typeof externals === "object" &&
|
94 | Object.prototype.hasOwnProperty.call(externals, dependency.request)
|
95 | ) {
|
96 | return handleExternal(externals[dependency.request], callback);
|
97 | }
|
98 | callback();
|
99 | };
|
100 |
|
101 | handleExternals(this.externals, (err, module) => {
|
102 | if (err) return callback(err);
|
103 | if (!module) return handleExternal(false, callback);
|
104 | return callback(null, module);
|
105 | });
|
106 | }
|
107 | );
|
108 | }
|
109 | }
|
110 | module.exports = ExternalModuleFactoryPlugin;
|