Skip to content

Commit 79743f0

Browse files
committed
work with queries in loaders
1 parent 31c6ffc commit 79743f0

10 files changed

Lines changed: 137 additions & 90 deletions

File tree

lib/buildDeps.js

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
var parse = require("./parse");
66
var resolve = require("enhanced-resolve");
77
var execLoaders = require("enhanced-require/lib/execLoaders");
8+
var matchRegExpObject = require("enhanced-resolve/lib/matchRegExpObject");
89
var buildModule = require("./buildModule");
910
var fs = require("fs");
1011
var path = require("path");
@@ -136,37 +137,34 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
136137

137138
// resolve the filename of the required module
138139
var resolveFunc = !options.workersNoResolve && options.workers && options.workers.ready() ?
139-
seperateResolve :
140+
separateResolve :
140141
resolve;
141142
resolveFunc(context = context || path.dirname(modu), modu, options.resolve, resolved);
142-
function resolved(err, filename) {
143+
function resolved(err, request) {
143144
if(err) {
144145
callback(err);
145146
return;
146147
}
147148
// check if the module is already included
148-
if(depTree.modules[filename]) {
149-
depTree.modules[filename].reasons.push(reason);
150-
callback(null, depTree.modules[filename].id);
149+
if(depTree.modules[request]) {
150+
depTree.modules[request].reasons.push(reason);
151+
callback(null, depTree.modules[request].id);
151152
} else {
152153
profile && (profile.resolveEnd = new Date());
153154
// create a new module
154-
var modu = depTree.modules[filename] = {
155+
var modu = depTree.modules[request] = {
155156
id: depTree.nextModuleId++,
156-
filename: filename,
157+
request: request,
157158
reasons: [reason]
158159
};
159160
depTree.modulesById[modu.id] = modu;
160161

161162
profile && (profile.module = modu);
162163

163-
// split the loaders from the require
164-
var filenameWithLoaders = filename;
165-
var loaders = filename.split(/!/g);
166-
filename = loaders.pop();
164+
var requestObj = resolve.parse(request);
167165

168166
if(options.cache) {
169-
options.cache.get(filenameWithLoaders, function(err, cachedData) {
167+
options.cache.get(request, function(err, cachedData) {
170168
if(err) return readFile();
171169
if(profile) {
172170
profile.buildModuleEnd = profile.loadersCheckEnd = profile.resolvePrePostLoadersEnd = new Date()
@@ -183,62 +181,82 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
183181
// Read the file and process it with loaders
184182
// [this step is cached]
185183
function readFile() {
186-
// read file content
187-
var preLoaders = options.preLoaders ? matchLoadersList(options.preLoaders) : "";
188-
var postLoaders = options.postLoaders ? matchLoadersList(options.postLoaders) : "";
184+
// match pre and post loaders from resource
185+
var preLoaders = options.preLoaders && requestObj.resource && requestObj.resource.path ? matchLoadersList(options.preLoaders) : "";
186+
var postLoaders = options.postLoaders && requestObj.resource && requestObj.resource.path ? matchLoadersList(options.postLoaders) : "";
189187

188+
// get the current function for loader resolving
190189
var resolveLoadersFunc = !options.workersNoResolve && options.workers && options.workers.ready() ?
191-
seperateResolveLoaders :
190+
separateResolveLoaders :
192191
resolve.loaders;
193192

193+
// resolve preLoaders
194194
if(preLoaders) resolveLoadersFunc(context, preLoaders, options.resolve, onPreLoadersResolved);
195195
else onPreLoadersResolved(null, []);
196196
function onPreLoadersResolved(err, preLoaders) {
197197
if(err) return callback(err);
198+
199+
// resolve postLoaders
198200
if(postLoaders) resolveLoadersFunc(context, postLoaders, options.resolve, onPostLoadersResolved);
199201
else onPostLoadersResolved(null, []);
200202
function onPostLoadersResolved(err, postLoaders) {
201203
if(err) return callback(err);
202204
profile && (profile.resolvePrePostLoadersEnd = new Date());
205+
206+
// put all loaders in a list
203207
var allLoaders = [];
204-
allLoaders.push.apply(allLoaders, preLoaders);
205-
allLoaders.push.apply(allLoaders, loaders);
206-
allLoaders.push.apply(allLoaders, postLoaders);
208+
if(preLoaders.length > 0)
209+
allLoaders.push.apply(allLoaders, preLoaders = preLoaders.map(resolve.parse.part));
210+
if(requestObj.loaders && requestObj.loaders.length > 0)
211+
allLoaders.push.apply(allLoaders, requestObj.loaders);
212+
if(postLoaders.length > 0)
213+
allLoaders.push.apply(allLoaders, postLoaders = postLoaders.map(resolve.parse.part));
214+
215+
// store the list in the module
207216
modu.loaders = allLoaders;
208-
modu.dependencies = [filename];
209-
var seperate = !!(options.workers &&
217+
218+
// and put premature dependencies into module (in case of loader error)
219+
modu.dependencies = requestObj.resource &&
220+
requestObj.resource.path &&
221+
[requestObj.resource.path] ||
222+
[];
223+
224+
// check if it is possible to separate the process
225+
var separate = !!(options.workers &&
210226
options.workers.ready() &&
211227
allLoaders.length >= (options.workerMinLoaders || 0));
212228
try {
213-
for(var i = 0; i < allLoaders.length && seperate; i++) {
214-
var loaderFilename = allLoaders[i];
229+
for(var i = 0; i < allLoaders.length && separate; i++) {
230+
var loaderFilename = allLoaders[i].path;
215231
var loader = require(loaderFilename);
216-
if(!loader.seperable && (!loader.seperableIfResolve || options.workersNoResolve))
217-
seperate = false;
232+
if(!loader.separable && (!loader.separableIfResolve || options.workersNoResolve))
233+
separate = false;
218234
}
219235
} catch(e) {
236+
// Syntax error in loader
220237
return callback(e);
221238
}
222-
modu.seperate = seperate;
239+
modu.separate = separate;
240+
223241
var buildModuleStart = new Date();
224242
profile && (profile.loadersCheckEnd = buildModuleStart);
225-
(seperate ? seperateBuildModule : buildModule)(
226-
context, filenameWithLoaders,
227-
preLoaders, loaders, postLoaders,
228-
filename,
243+
(separate ? separateBuildModule : buildModule)(
244+
context, request,
245+
preLoaders, requestObj.loaders || [], postLoaders,
246+
requestObj,
229247
options, function(err, extraResults, source, deps) {
230248

231249
var dependencyInfo = extraResults && extraResults.dependencyInfo;
232250
if(dependencyInfo) modu.dependencies = dependencyInfo.files; // It my be also supplied if err is set.
233251
if(extraResults && extraResults.warnings && extraResults.warnings.length > 0) {
234252
extraResults.warnings.forEach(function(w) {
235-
depTree.warnings.push(w + "\n @ loader @ " + filenameWithLoaders);
253+
depTree.warnings.push(w + "\n @ loader @ " + request);
236254
});
237255
modu.warnings = extraResults.warnings;
238256
}
239257
if(extraResults && extraResults.errors && extraResults.errors.length > 0) {
240258
extraResults.errors.forEach(function(e) {
241-
depTree.errors.push(e + "\n @ loader @ " + filenameWithLoaders);
259+
depTree.errors.push(e + "\n @ loader @ " + request);
242260
});
243261
modu.errors = extraResults.errors;
244262
}
@@ -253,11 +271,11 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
253271
}
254272
if(dependencyInfo.cacheable && options.cache) {
255273
modu.toCache = true;
256-
options.cache.store(filenameWithLoaders, dependencyInfo.files, buildModuleStart, JSON.stringify({
274+
options.cache.store(request, dependencyInfo.files, buildModuleStart, JSON.stringify({
257275
deps: deps,
258276
source: source,
259277
dependencies: dependencyInfo.files,
260-
loaders: allLoaders
278+
loaders: allLoaders.map(function(l) { return l.path; })
261279
}));
262280
}
263281
return processParsedJs(source, deps);
@@ -266,33 +284,11 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
266284
}
267285
}
268286

269-
function asRegExp(test) {
270-
if(typeof test == "string") test = new RegExp(test);
271-
return test;
272-
}
273-
274-
function matchAny(test, str) {
275-
if(!test) return true;
276-
test = asRegExp(test);
277-
if(Array.isArray(test)) {
278-
return test.map(asRegExp).filter(function(regExp) {
279-
return regExp.test(str);
280-
}).length > 0;
281-
} else {
282-
return test.test(str);
283-
}
284-
}
285-
286287
function matchLoadersList(list) {
287288
return list.filter(function(item) {
288-
return matchAny(item.test, filename);
289-
}).filter(function(item) {
290-
return matchAny(item.include, filename);
291-
}).filter(function(item) {
292-
if(!item.exclude) return true;
293-
return !matchAny(item.exclude, filename);
289+
return matchRegExpObject(item, requestObj.resource.path);
294290
}).map(function(item) {
295-
return item.loader;
291+
return item.loader || item.loaders.join("!");
296292
}).join("!");
297293
}
298294

@@ -340,25 +336,30 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
340336
var requiresNames = Object.keys(requires);
341337
var count = requiresNames.length + contexts.length + 1;
342338
var errors = [];
339+
var requireContext = requestObj.resource &&
340+
requestObj.resource.path &&
341+
path.dirname(requestObj.resource.path) ||
342+
context;
343343
if(requiresNames.length)
344344
requiresNames.forEach(function(moduleName) {
345345
var reason = {
346346
type: "require",
347347
async: !directRequire[moduleName] || undefined,
348348
count: requires[moduleName].length,
349-
filename: filenameWithLoaders
349+
request: request,
350+
filename: requestObj.resource && requestObj.resource.path
350351
};
351352

352353
// create or get the module for each require
353-
addModule(depTree, path.dirname(filename), moduleName, options, reason, function(err, moduleId) {
354+
addModule(depTree, requireContext, moduleName, options, reason, function(err, moduleId) {
354355
if(err) {
355356
var error = false;
356357
requires[moduleName].forEach(function(requireItem) {
357358
if(!requireItem.inTry)
358359
error = true;
359360
});
360361
(error ? depTree.errors : depTree.warnings).push("Cannot find module '" + moduleName + "'\n " + err +
361-
"\n @ " + filename + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")");
362+
"\n @ " + request + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")");
362363
} else {
363364
requires[moduleName].forEach(function(requireItem) {
364365
requireItem.id = moduleId;
@@ -374,22 +375,23 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
374375
var reason = {
375376
type: "context",
376377
async: !directContexts[context.name] || undefined,
377-
filename: filenameWithLoaders
378+
request: request,
379+
filename: requestObj.resource && requestObj.resource.path
378380
};
379381

380382
// create of get the context module for each require.context
381-
addContextModule(depTree, path.dirname(filename), context.name, options, reason, function(err, contextModuleId) {
383+
addContextModule(depTree, requireContext, context.name, options, reason, function(err, contextModuleId) {
382384
if(err) {
383385
depTree.errors.push("Cannot find context '"+context.name+"'\n " + err +
384-
"\n @ " + filename + " (line " + context.line + ", column " + context.column + ")");
386+
"\n @ " + request + " (line " + context.line + ", column " + context.column + ")");
385387
} else {
386388
context.id = contextModuleId;
387389
module.requires.push({id: context.id});
388390
}
389391
endOne();
390392
});
391393
if(context.warn) {
392-
depTree.warnings.push(filename + " (line " + context.line + ", column " + context.column + "): " +
394+
depTree.warnings.push(request + " (line " + context.line + ", column " + context.column + "): " +
393395
"implicit use of require.context(\".\") is not recommended.");
394396
}
395397
});
@@ -402,7 +404,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
402404
if(errors.length) {
403405
callback(errors.join("\n"));
404406
} else {
405-
options.events.emit("module", modu, filename);
407+
options.events.emit("module", modu, requestObj.resource && requestObj.resource.path);
406408
callback(null, modu.id);
407409
}
408410
}
@@ -411,7 +413,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
411413
}
412414
}
413415

414-
function seperateBuildModule(context, filenameWithLoaders,
416+
function separateBuildModule(context, requestObj,
415417
preLoaders, loaders, postLoaders,
416418
filename, options, callback) {
417419
var opt = {};
@@ -421,7 +423,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
421423
if(name == "workers") return;
422424
opt[name] = options[name];
423425
});
424-
options.workers.run("buildModule", context, filenameWithLoaders,
426+
options.workers.run("buildModule", context, requestObj,
425427
preLoaders, loaders, postLoaders,
426428
filename, opt, function(err, extraResults, source, deps) {
427429
if(err) err = {
@@ -436,7 +438,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
436438
});
437439
}
438440

439-
function seperateResolve() {
441+
function separateResolve() {
440442
var args = Array.prototype.slice.call(arguments, 0);
441443
args.unshift("resolve");
442444
var callback = args.pop();
@@ -454,7 +456,7 @@ function addModule(depTree, context, modu, options, reason, finalCallback) {
454456
options.workers.run.apply(options.workers, args);
455457
}
456458

457-
function seperateResolveLoaders() {
459+
function separateResolveLoaders() {
458460
var args = Array.prototype.slice.call(arguments, 0);
459461
args.unshift("resolve.loaders");
460462
var callback = args.pop();

0 commit comments

Comments
 (0)