Skip to content

Commit 4019beb

Browse files
authored
Merge pull request webpack#5976 from webpack/feature/resolve-rule
Allow to override resolve configuration
2 parents a53672d + 5e39ec4 commit 4019beb

21 files changed

+262
-55
lines changed

lib/Compilation.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Compilation extends Tapable {
5959
constructor(compiler) {
6060
super();
6161
this.compiler = compiler;
62-
this.resolvers = compiler.resolvers;
62+
this.resolverFactory = compiler.resolverFactory;
6363
this.inputFileSystem = compiler.inputFileSystem;
6464

6565
const options = this.options = compiler.options;
@@ -176,7 +176,7 @@ class Compilation extends Tapable {
176176
callbackList.forEach(cb => cb(err));
177177
};
178178

179-
module.build(this.options, this, this.resolvers.normal, this.inputFileSystem, (error) => {
179+
module.build(this.options, this, this.resolverFactory.get("normal", module.resolveOptions), this.inputFileSystem, (error) => {
180180
const errors = module.errors;
181181
for(let indexError = 0; indexError < errors.length; indexError++) {
182182
const err = errors[indexError];
@@ -273,6 +273,7 @@ class Compilation extends Tapable {
273273
issuer: module.nameForCondition && module.nameForCondition(),
274274
compiler: _this.compiler.name
275275
},
276+
resolveOptions: module.resolveOptions,
276277
context: module.context,
277278
dependencies: dependencies
278279
}, (err, dependentModule) => {

lib/Compiler.js

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const Compilation = require("./Compilation");
1212
const Stats = require("./Stats");
1313
const NormalModuleFactory = require("./NormalModuleFactory");
1414
const ContextModuleFactory = require("./ContextModuleFactory");
15+
const ResolverFactory = require("./ResolverFactory");
1516

1617
const makePathsRelative = require("./util/identifier").makePathsRelative;
1718

@@ -182,10 +183,68 @@ class Compiler extends Tapable {
182183
this.fileTimestamps = {};
183184
this.contextTimestamps = {};
184185

186+
this.resolverFactory = new ResolverFactory();
185187
this.resolvers = {
186-
normal: null,
187-
loader: null,
188-
context: null
188+
normal: {
189+
plugins: util.deprecate(
190+
(hook, fn) => {
191+
this.resolverFactory.plugin("resolver normal", resolver => {
192+
resolver.plugin(hook, fn);
193+
});
194+
},
195+
"webpack: Using compiler.resolvers.normal is deprecated.\n" +
196+
"Use compiler.resolverFactory.plugin(\"resolver normal\", resolver => {\n resolver.plugin(/* ... */);\n}); instead."
197+
),
198+
apply: util.deprecate(
199+
(...args) => {
200+
this.resolverFactory.plugin("resolver normal", resolver => {
201+
resolver.apply(...args);
202+
});
203+
},
204+
"webpack: Using compiler.resolvers.normal is deprecated.\n" +
205+
"Use compiler.resolverFactory.plugin(\"resolver normal\", resolver => {\n resolver.apply(/* ... */);\n}); instead."
206+
)
207+
},
208+
loader: {
209+
plugins: util.deprecate(
210+
(hook, fn) => {
211+
this.resolverFactory.plugin("resolver loader", resolver => {
212+
resolver.plugin(hook, fn);
213+
});
214+
},
215+
"webpack: Using compiler.resolvers.loader is deprecated.\n" +
216+
"Use compiler.resolverFactory.plugin(\"resolver loader\", resolver => {\n resolver.plugin(/* ... */);\n}); instead."
217+
),
218+
apply: util.deprecate(
219+
(...args) => {
220+
this.resolverFactory.plugin("resolver loader", resolver => {
221+
resolver.apply(...args);
222+
});
223+
},
224+
"webpack: Using compiler.resolvers.loader is deprecated.\n" +
225+
"Use compiler.resolverFactory.plugin(\"resolver loader\", resolver => {\n resolver.apply(/* ... */);\n}); instead."
226+
)
227+
},
228+
context: {
229+
plugins: util.deprecate(
230+
(hook, fn) => {
231+
this.resolverFactory.plugin("resolver context", resolver => {
232+
resolver.plugin(hook, fn);
233+
});
234+
},
235+
"webpack: Using compiler.resolvers.context is deprecated.\n" +
236+
"Use compiler.resolverFactory.plugin(\"resolver context\", resolver => {\n resolver.plugin(/* ... */);\n}); instead."
237+
),
238+
apply: util.deprecate(
239+
(...args) => {
240+
this.resolverFactory.plugin("resolver context", resolver => {
241+
resolver.apply(...args);
242+
});
243+
},
244+
"webpack: Using compiler.resolvers.context is deprecated.\n" +
245+
"Use compiler.resolverFactory.plugin(\"resolver context\", resolver => {\n resolver.apply(/* ... */);\n}); instead."
246+
)
247+
}
189248
};
190249
this.parser = {
191250
plugin: util.deprecate(
@@ -419,7 +478,7 @@ class Compiler extends Tapable {
419478
childCompiler.outputPath = this.outputPath;
420479
childCompiler.inputFileSystem = this.inputFileSystem;
421480
childCompiler.outputFileSystem = null;
422-
childCompiler.resolvers = this.resolvers;
481+
childCompiler.resolverFactory = this.resolverFactory;
423482
childCompiler.fileTimestamps = this.fileTimestamps;
424483
childCompiler.contextTimestamps = this.contextTimestamps;
425484

@@ -463,13 +522,13 @@ class Compiler extends Tapable {
463522
}
464523

465524
createNormalModuleFactory() {
466-
const normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolvers, this.options.module || {});
525+
const normalModuleFactory = new NormalModuleFactory(this.options.context, this.resolverFactory, this.options.module || {});
467526
this.applyPlugins("normal-module-factory", normalModuleFactory);
468527
return normalModuleFactory;
469528
}
470529

471530
createContextModuleFactory() {
472-
const contextModuleFactory = new ContextModuleFactory(this.resolvers, this.inputFileSystem);
531+
const contextModuleFactory = new ContextModuleFactory(this.resolverFactory, this.inputFileSystem);
473532
this.applyPlugins("context-module-factory", contextModuleFactory);
474533
return contextModuleFactory;
475534
}

lib/ContextModule.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class ContextModule extends Module {
3636
resourceQuery: resourceQuery
3737
});
3838
this.context = this.options.resource;
39+
if(options.resolveOptions !== undefined)
40+
this.resolveOptions = options.resolveOptions;
3941

4042
// Info from Build
4143
this.builtTime = undefined;

lib/ContextModuleFactory.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@ const Tapable = require("tapable");
1111
const ContextModule = require("./ContextModule");
1212
const ContextElementDependency = require("./dependencies/ContextElementDependency");
1313

14+
const EMPTY_RESOLVE_OPTIONS = {};
15+
1416
module.exports = class ContextModuleFactory extends Tapable {
15-
constructor(resolvers) {
17+
constructor(resolverFactory) {
1618
super();
17-
this.resolvers = resolvers;
19+
this.resolverFactory = resolverFactory;
1820
}
1921

2022
create(data, callback) {
2123
const context = data.context;
2224
const dependencies = data.dependencies;
25+
const resolveOptions = data.resolveOptions;
2326
const dependency = dependencies[0];
2427
this.applyPluginsAsyncWaterfall("before-resolve", Object.assign({
2528
context: context,
26-
dependencies: dependencies
29+
dependencies: dependencies,
30+
resolveOptions
2731
}, dependency.options), (err, beforeResolveResult) => {
2832
if(err) return callback(err);
2933

@@ -32,6 +36,7 @@ module.exports = class ContextModuleFactory extends Tapable {
3236

3337
const context = beforeResolveResult.context;
3438
const request = beforeResolveResult.request;
39+
const resolveOptions = beforeResolveResult.resolveOptions;
3540

3641
let loaders, resource, loadersPrefix = "";
3742
const idx = request.lastIndexOf("!");
@@ -50,18 +55,19 @@ module.exports = class ContextModuleFactory extends Tapable {
5055
resource = request;
5156
}
5257

53-
const resolvers = this.resolvers;
58+
const contextResolver = this.resolverFactory.get("context", resolveOptions || EMPTY_RESOLVE_OPTIONS);
59+
const loaderResolver = this.resolverFactory.get("loader", EMPTY_RESOLVE_OPTIONS);
5460

5561
asyncLib.parallel([
5662
callback => {
57-
resolvers.context.resolve({}, context, resource, (err, result) => {
63+
contextResolver.resolve({}, context, resource, (err, result) => {
5864
if(err) return callback(err);
5965
callback(null, result);
6066
});
6167
},
6268
callback => {
6369
asyncLib.map(loaders, (loader, callback) => {
64-
resolvers.loader.resolve({}, context, loader, (err, result) => {
70+
loaderResolver.resolve({}, context, loader, (err, result) => {
6571
if(err) return callback(err);
6672
callback(null, result);
6773
});
@@ -73,7 +79,7 @@ module.exports = class ContextModuleFactory extends Tapable {
7379
this.applyPluginsAsyncWaterfall("after-resolve", Object.assign({
7480
addon: loadersPrefix + result[1].join("!") + (result[1].length > 0 ? "!" : ""),
7581
resource: result[0],
76-
resolveDependencies: this.resolveDependencies.bind(this),
82+
resolveDependencies: this.resolveDependencies.bind(this)
7783
}, beforeResolveResult), (err, result) => {
7884
if(err) return callback(err);
7985

lib/Module.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const ModuleReason = require("./ModuleReason");
1111
const SortableSet = require("./util/SortableSet");
1212
const Template = require("./Template");
1313

14+
const EMPTY_RESOLVE_OPTIONS = {};
15+
1416
let debugId = 1000;
1517

1618
const sortById = (a, b) => {
@@ -52,6 +54,7 @@ class Module extends DependenciesBlock {
5254
// Info from Factory
5355
// TODO refactor: pass as constructor argument
5456
this.context = null;
57+
this.resolveOptions = EMPTY_RESOLVE_OPTIONS;
5558

5659
// Info from Build
5760
this.sideEffectFree = false;

lib/NormalModule.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const dependencyTemplatesHashMap = new WeakMap();
6666

6767
class NormalModule extends Module {
6868

69-
constructor(type, request, userRequest, rawRequest, loaders, resource, parser) {
69+
constructor(type, request, userRequest, rawRequest, loaders, resource, parser, resolveOptions) {
7070
super(type);
7171

7272
// Info from Factory
@@ -78,6 +78,8 @@ class NormalModule extends Module {
7878
this.resource = resource;
7979
this.context = getContext(resource);
8080
this.loaders = loaders;
81+
if(resolveOptions !== undefined)
82+
this.resolveOptions = resolveOptions;
8183

8284
// Info from Build
8385
this.fileDependencies = new Set();

lib/NormalModuleFactory.js

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const Tapable = require("tapable");
99
const NormalModule = require("./NormalModule");
1010
const RawModule = require("./RawModule");
1111
const RuleSet = require("./RuleSet");
12+
const cachedMerge = require("./util/cachedMerge");
13+
14+
const EMPTY_RESOLVE_OPTIONS = {};
1215

1316
const loaderToIdent = data => {
1417
if(!data.options)
@@ -42,10 +45,10 @@ const identToLoaderRequest = resultString => {
4245
};
4346

4447
class NormalModuleFactory extends Tapable {
45-
constructor(context, resolvers, options) {
48+
constructor(context, resolverFactory, options) {
4649
super();
47-
this.resolvers = resolvers;
48-
this.ruleSet = new RuleSet(options.rules);
50+
this.resolverFactory = resolverFactory;
51+
this.ruleSet = new RuleSet(options.defaultRules.concat(options.rules));
4952
this.cachePredicate = typeof options.unsafeCache === "function" ? options.unsafeCache : Boolean.bind(null, options.unsafeCache);
5053
this.context = context || "";
5154
this.parserCache = {};
@@ -85,7 +88,8 @@ class NormalModuleFactory extends Tapable {
8588
result.rawRequest,
8689
result.loaders,
8790
result.resource,
88-
result.parser
91+
result.parser,
92+
result.resolveOptions
8993
);
9094
}
9195

@@ -107,15 +111,19 @@ class NormalModuleFactory extends Tapable {
107111
let resource = elements.pop();
108112
elements = elements.map(identToLoaderRequest);
109113

114+
const loaderResolver = this.getResolver("loader");
115+
const normalResolver = this.getResolver("normal", data.resolveOptions);
116+
110117
asyncLib.parallel([
111-
callback => this.resolveRequestArray(contextInfo, context, elements, this.resolvers.loader, callback),
118+
callback => this.resolveRequestArray(contextInfo, context, elements, loaderResolver, callback),
112119
callback => {
113-
if(resource === "" || resource[0] === "?")
120+
if(resource === "" || resource[0] === "?") {
114121
return callback(null, {
115122
resource
116123
});
124+
}
117125

118-
this.resolvers.normal.resolve(contextInfo, context, resource, (err, resource, resourceResolveData) => {
126+
normalResolver.resolve(contextInfo, context, resource, (err, resource, resourceResolveData) => {
119127
if(err) return callback(err);
120128
callback(null, {
121129
resourceResolveData,
@@ -179,19 +187,22 @@ class NormalModuleFactory extends Tapable {
179187
useLoadersPre.push(r.value);
180188
else if(!r.enforce && !noAutoLoaders && !noPrePostAutoLoaders)
181189
useLoaders.push(r.value);
190+
} else if(typeof r.value === "object" && r.value !== null && typeof settings[r.type] === "object" && settings[r.type] !== null) {
191+
settings[r.type] = cachedMerge(settings[r.type], r.value);
182192
} else {
183193
settings[r.type] = r.value;
184194
}
185195
});
186196
asyncLib.parallel([
187-
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, this.resolvers.loader),
188-
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, this.resolvers.loader),
189-
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, this.resolvers.loader)
197+
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPost, loaderResolver),
198+
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoaders, loaderResolver),
199+
this.resolveRequestArray.bind(this, contextInfo, this.context, useLoadersPre, loaderResolver)
190200
], (err, results) => {
191201
if(err) return callback(err);
192202
loaders = results[0].concat(loaders, results[1], results[2]);
193203
process.nextTick(() => {
194-
const type = settings.type || this.getDefaultType(resourcePath);
204+
const type = settings.type;
205+
const resolveOptions = settings.resolve;
195206
callback(null, {
196207
context: context,
197208
request: loaders.map(loaderToIdent).concat([resource]).join("!"),
@@ -202,33 +213,26 @@ class NormalModuleFactory extends Tapable {
202213
resource,
203214
resourceResolveData,
204215
type,
205-
parser: this.getParser(type, settings.parser)
216+
parser: this.getParser(type, settings.parser),
217+
resolveOptions
206218
});
207219
});
208220
});
209221
});
210222
});
211223
}
212224

213-
getDefaultType(resourcePath) {
214-
if(/\.wasm$/.test(resourcePath))
215-
return "webassembly/experimental";
216-
if(/\.mjs$/.test(resourcePath))
217-
return "javascript/esm";
218-
if(/\.json$/.test(resourcePath))
219-
return "json";
220-
return "javascript/auto";
221-
}
222-
223225
create(data, callback) {
224226
const dependencies = data.dependencies;
225227
const cacheEntry = dependencies[0].__NormalModuleFactoryCache;
226228
if(cacheEntry) return callback(null, cacheEntry);
227229
const context = data.context || this.context;
230+
const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
228231
const request = dependencies[0].request;
229232
const contextInfo = data.contextInfo || {};
230233
this.applyPluginsAsyncWaterfall("before-resolve", {
231234
contextInfo,
235+
resolveOptions,
232236
context,
233237
request,
234238
dependencies
@@ -307,6 +311,10 @@ class NormalModuleFactory extends Tapable {
307311
this.applyPlugins2(`parser ${type}`, parser, parserOptions);
308312
return parser;
309313
}
314+
315+
getResolver(type, resolveOptions) {
316+
return this.resolverFactory.get(type, resolveOptions || EMPTY_RESOLVE_OPTIONS);
317+
}
310318
}
311319

312320
module.exports = NormalModuleFactory;

0 commit comments

Comments
 (0)