Apply module bundling
[platform/framework/web/wrtjs.git] / node_modules / webpack / lib / dependencies / LoaderPlugin.js
1 /*
2         MIT License http://www.opensource.org/licenses/mit-license.php
3         Author Tobias Koppers @sokra
4 */
5
6 "use strict";
7
8 const NormalModule = require("../NormalModule");
9 const LazySet = require("../util/LazySet");
10 const LoaderDependency = require("./LoaderDependency");
11 const LoaderImportDependency = require("./LoaderImportDependency");
12
13 /** @typedef {import("../Compilation").DepConstructor} DepConstructor */
14 /** @typedef {import("../Compiler")} Compiler */
15 /** @typedef {import("../Module")} Module */
16
17 /**
18  * @callback LoadModuleCallback
19  * @param {(Error | null)=} err error object
20  * @param {string | Buffer=} source source code
21  * @param {object=} map source map
22  * @param {Module=} module loaded module if successful
23  */
24
25 /**
26  * @callback ImportModuleCallback
27  * @param {(Error | null)=} err error object
28  * @param {any=} exports exports of the evaluated module
29  */
30
31 /**
32  * @typedef {Object} ImportModuleOptions
33  * @property {string=} layer the target layer
34  * @property {string=} publicPath the target public path
35  * @property {string=} baseUri target base uri
36  */
37
38 class LoaderPlugin {
39         /**
40          * @param {Object} options options
41          */
42         constructor(options = {}) {}
43
44         /**
45          * Apply the plugin
46          * @param {Compiler} compiler the compiler instance
47          * @returns {void}
48          */
49         apply(compiler) {
50                 compiler.hooks.compilation.tap(
51                         "LoaderPlugin",
52                         (compilation, { normalModuleFactory }) => {
53                                 compilation.dependencyFactories.set(
54                                         LoaderDependency,
55                                         normalModuleFactory
56                                 );
57                                 compilation.dependencyFactories.set(
58                                         LoaderImportDependency,
59                                         normalModuleFactory
60                                 );
61                         }
62                 );
63
64                 compiler.hooks.compilation.tap("LoaderPlugin", compilation => {
65                         const moduleGraph = compilation.moduleGraph;
66                         NormalModule.getCompilationHooks(compilation).loader.tap(
67                                 "LoaderPlugin",
68                                 loaderContext => {
69                                         /**
70                                          * @param {string} request the request string to load the module from
71                                          * @param {LoadModuleCallback} callback callback returning the loaded module or error
72                                          * @returns {void}
73                                          */
74                                         loaderContext.loadModule = (request, callback) => {
75                                                 const dep = new LoaderDependency(request);
76                                                 dep.loc = {
77                                                         name: request
78                                                 };
79                                                 const factory = compilation.dependencyFactories.get(
80                                                         /** @type {DepConstructor} */ (dep.constructor)
81                                                 );
82                                                 if (factory === undefined) {
83                                                         return callback(
84                                                                 new Error(
85                                                                         `No module factory available for dependency type: ${dep.constructor.name}`
86                                                                 )
87                                                         );
88                                                 }
89                                                 compilation.buildQueue.increaseParallelism();
90                                                 compilation.handleModuleCreation(
91                                                         {
92                                                                 factory,
93                                                                 dependencies: [dep],
94                                                                 originModule: loaderContext._module,
95                                                                 context: loaderContext.context,
96                                                                 recursive: false
97                                                         },
98                                                         err => {
99                                                                 compilation.buildQueue.decreaseParallelism();
100                                                                 if (err) {
101                                                                         return callback(err);
102                                                                 }
103                                                                 const referencedModule = moduleGraph.getModule(dep);
104                                                                 if (!referencedModule) {
105                                                                         return callback(new Error("Cannot load the module"));
106                                                                 }
107                                                                 if (referencedModule.getNumberOfErrors() > 0) {
108                                                                         return callback(
109                                                                                 new Error("The loaded module contains errors")
110                                                                         );
111                                                                 }
112                                                                 const moduleSource = referencedModule.originalSource();
113                                                                 if (!moduleSource) {
114                                                                         return callback(
115                                                                                 new Error(
116                                                                                         "The module created for a LoaderDependency must have an original source"
117                                                                                 )
118                                                                         );
119                                                                 }
120                                                                 let source, map;
121                                                                 if (moduleSource.sourceAndMap) {
122                                                                         const sourceAndMap = moduleSource.sourceAndMap();
123                                                                         map = sourceAndMap.map;
124                                                                         source = sourceAndMap.source;
125                                                                 } else {
126                                                                         map = moduleSource.map();
127                                                                         source = moduleSource.source();
128                                                                 }
129                                                                 const fileDependencies = new LazySet();
130                                                                 const contextDependencies = new LazySet();
131                                                                 const missingDependencies = new LazySet();
132                                                                 const buildDependencies = new LazySet();
133                                                                 referencedModule.addCacheDependencies(
134                                                                         fileDependencies,
135                                                                         contextDependencies,
136                                                                         missingDependencies,
137                                                                         buildDependencies
138                                                                 );
139
140                                                                 for (const d of fileDependencies) {
141                                                                         loaderContext.addDependency(d);
142                                                                 }
143                                                                 for (const d of contextDependencies) {
144                                                                         loaderContext.addContextDependency(d);
145                                                                 }
146                                                                 for (const d of missingDependencies) {
147                                                                         loaderContext.addMissingDependency(d);
148                                                                 }
149                                                                 for (const d of buildDependencies) {
150                                                                         loaderContext.addBuildDependency(d);
151                                                                 }
152                                                                 return callback(null, source, map, referencedModule);
153                                                         }
154                                                 );
155                                         };
156
157                                         /**
158                                          * @param {string} request the request string to load the module from
159                                          * @param {ImportModuleOptions=} options options
160                                          * @param {ImportModuleCallback=} callback callback returning the exports
161                                          * @returns {void}
162                                          */
163                                         const importModule = (request, options, callback) => {
164                                                 const dep = new LoaderImportDependency(request);
165                                                 dep.loc = {
166                                                         name: request
167                                                 };
168                                                 const factory = compilation.dependencyFactories.get(
169                                                         /** @type {DepConstructor} */ (dep.constructor)
170                                                 );
171                                                 if (factory === undefined) {
172                                                         return callback(
173                                                                 new Error(
174                                                                         `No module factory available for dependency type: ${dep.constructor.name}`
175                                                                 )
176                                                         );
177                                                 }
178                                                 compilation.buildQueue.increaseParallelism();
179                                                 compilation.handleModuleCreation(
180                                                         {
181                                                                 factory,
182                                                                 dependencies: [dep],
183                                                                 originModule: loaderContext._module,
184                                                                 contextInfo: {
185                                                                         issuerLayer: options.layer
186                                                                 },
187                                                                 context: loaderContext.context,
188                                                                 connectOrigin: false
189                                                         },
190                                                         err => {
191                                                                 compilation.buildQueue.decreaseParallelism();
192                                                                 if (err) {
193                                                                         return callback(err);
194                                                                 }
195                                                                 const referencedModule = moduleGraph.getModule(dep);
196                                                                 if (!referencedModule) {
197                                                                         return callback(new Error("Cannot load the module"));
198                                                                 }
199                                                                 compilation.executeModule(
200                                                                         referencedModule,
201                                                                         {
202                                                                                 entryOptions: {
203                                                                                         baseUri: options.baseUri,
204                                                                                         publicPath: options.publicPath
205                                                                                 }
206                                                                         },
207                                                                         (err, result) => {
208                                                                                 if (err) return callback(err);
209                                                                                 for (const d of result.fileDependencies) {
210                                                                                         loaderContext.addDependency(d);
211                                                                                 }
212                                                                                 for (const d of result.contextDependencies) {
213                                                                                         loaderContext.addContextDependency(d);
214                                                                                 }
215                                                                                 for (const d of result.missingDependencies) {
216                                                                                         loaderContext.addMissingDependency(d);
217                                                                                 }
218                                                                                 for (const d of result.buildDependencies) {
219                                                                                         loaderContext.addBuildDependency(d);
220                                                                                 }
221                                                                                 if (result.cacheable === false)
222                                                                                         loaderContext.cacheable(false);
223                                                                                 for (const [name, { source, info }] of result.assets) {
224                                                                                         const { buildInfo } = loaderContext._module;
225                                                                                         if (!buildInfo.assets) {
226                                                                                                 buildInfo.assets = Object.create(null);
227                                                                                                 buildInfo.assetsInfo = new Map();
228                                                                                         }
229                                                                                         buildInfo.assets[name] = source;
230                                                                                         buildInfo.assetsInfo.set(name, info);
231                                                                                 }
232                                                                                 callback(null, result.exports);
233                                                                         }
234                                                                 );
235                                                         }
236                                                 );
237                                         };
238
239                                         /**
240                                          * @param {string} request the request string to load the module from
241                                          * @param {ImportModuleOptions} options options
242                                          * @param {ImportModuleCallback=} callback callback returning the exports
243                                          * @returns {Promise<any> | void} exports
244                                          */
245                                         loaderContext.importModule = (request, options, callback) => {
246                                                 if (!callback) {
247                                                         return new Promise((resolve, reject) => {
248                                                                 importModule(request, options || {}, (err, result) => {
249                                                                         if (err) reject(err);
250                                                                         else resolve(result);
251                                                                 });
252                                                         });
253                                                 }
254                                                 return importModule(request, options || {}, callback);
255                                         };
256                                 }
257                         );
258                 });
259         }
260 }
261 module.exports = LoaderPlugin;