This repository was archived by the owner on May 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMultidefineLibraryWebpackPlugin.js
More file actions
129 lines (98 loc) · 3.79 KB
/
MultidefineLibraryWebpackPlugin.js
File metadata and controls
129 lines (98 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict';
const EXPORTS_VALUES_BY_DEFINITION = {
amd: '__WEBPACK_AMD_DEFINE_RESULT__',
commonjs: 'module.exports'
};
const DEFINE_PATTERN = (name, definition, extra) =>
`\n\ndefine('${name}', function () {\n` +
extra +
` return ${EXPORTS_VALUES_BY_DEFINITION[definition]};
});`;
const DEPRECATION_PATTERN = (methodName, message) =>
`\twindow.${methodName} && window.${methodName}('${message}');\n`;
class MultidefineLibraryWebpacklugin {
constructor (modulesToExpose, options) {
this.options = Object.assign({
deprecationMethodName: 'deprecated'
}, options);
if (!modulesToExpose) {
throw new Error('List of modules to expose should be provided');
}
if (Array.isArray(modulesToExpose)) {
modulesToExpose = this._convertArrayToObject(modulesToExpose);
}
this.modulesToExpose = modulesToExpose;
}
apply (compiler) {
this.context = compiler.context;
compiler.plugin('compilation', (compilation, data) => {
compilation.plugin('succeed-module', (module) => {
const modulePath = module.resource && this._getRelativePath(module.resource);
if (!modulePath) { return; }
const moduleToExpose = this.modulesToExpose[modulePath];
if (!moduleToExpose) { return; }
moduleToExpose.definition = this._detectModuleDefinition(module);
this._appendDefine(module, moduleToExpose);
});
});
}
_addModuleToList (module, list, namesIndex) {
if (list[module.path]) {
throw new Error('Duplicated exposed module path "' + module.path + '"');
}
if (namesIndex[module.name]) {
throw new Error('Conflict on exposed module name "' + module.name + '"');
}
if (module.aliases) {
// We use a temporary index here to avoid touching global names index
// before we have checked all aliases
let aliasesIndex = {};
module.aliases.forEach((alias) => {
if (namesIndex[alias]) {
throw new Error('Conflict on exposed module alias "' + alias + '"');
}
aliasesIndex[alias] = module.name;
});
Object.assign(namesIndex, aliasesIndex);
}
namesIndex[module.name] = module.name;
return Object.assign({}, list, { [module.path]: module });
}
_convertArrayToObject (modulesToExpose) {
const namesIndex = {};
return modulesToExpose.reduce((modulesList, module) =>
this._addModuleToList(module, modulesList, namesIndex),
{});
}
_getRelativePath (resource) {
resource = resource.slice(this.context.length);
if (resource.startsWith('/')) { resource = resource.slice(1); }
return resource;
}
_detectModuleDefinition (module) {
let isAMD = module.dependencies.some((dependency) => dependency.constructor.name === 'AMDDefineDependency');
return isAMD ? 'amd' : 'commonjs';
}
_prepareStatement (moduleToExpose, name) {
let extra = '';
if (moduleToExpose.deprecated) {
let deprecationMessage = `Deprecated module usage: "${name}"`;
extra += DEPRECATION_PATTERN(this.options.deprecationMethodName, deprecationMessage);
} else if (moduleToExpose.name !== name) {
let deprecationMessage = `Deprecated module alias "${name}" used. Please use real module name "${moduleToExpose.name}"`;
extra += DEPRECATION_PATTERN(this.options.deprecationMethodName, deprecationMessage);
}
return DEFINE_PATTERN(name, moduleToExpose.definition, extra);
}
_appendDefine (module, moduleToExpose) {
let appendix = [];
appendix.push(this._prepareStatement(moduleToExpose, moduleToExpose.name));
if (moduleToExpose.aliases) {
moduleToExpose.aliases.forEach((alias) => {
appendix.push(this._prepareStatement(moduleToExpose, alias));
});
}
module._source._value += appendix.join('');
}
}
module.exports = MultidefineLibraryWebpacklugin;