Skip to content

Commit 16225de

Browse files
committed
apply extensionAlias before extensions and mainFiles
1 parent 9722550 commit 16225de

File tree

7 files changed

+51
-31
lines changed

7 files changed

+51
-31
lines changed

lib/ExtensionAliasPlugin.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,38 @@ module.exports = class ExtensionAliasPlugin {
3030
*/
3131
apply(resolver) {
3232
const target = resolver.ensureHook(this.target);
33-
const { extension, alias: aliasArray } = this.options;
33+
const { extension, alias } = this.options;
3434
resolver
3535
.getHook(this.source)
3636
.tapAsync("ExtensionAliasPlugin", (request, resolveContext, callback) => {
37-
const requestPath = request.path;
37+
const requestPath = request.request;
3838
if (!requestPath || !requestPath.endsWith(extension)) return callback();
3939
const resolve = (alias, callback) => {
4040
resolver.doResolve(
4141
target,
4242
{
4343
...request,
44-
path: `${requestPath.slice(0, -extension.length)}${alias}`,
45-
relativePath: request.relativePath
46-
? `${request.relativePath.slice(0, -extension.length)}${alias}`
47-
: request.relativePath
44+
request: `${requestPath.slice(0, -extension.length)}${alias}`,
45+
fullySpecified: true
4846
},
4947
`aliased from extension alias with mapping '${extension}' to '${alias}'`,
5048
resolveContext,
5149
callback
5250
);
5351
};
5452

55-
if (aliasArray.length > 1) {
56-
forEachBail(aliasArray, resolve, callback);
53+
const stoppingCallback = (err, result) => {
54+
if (err) return callback(err);
55+
if (result) return callback(null, result);
56+
// Don't allow other aliasing or raw request
57+
return callback(null, null);
58+
};
59+
if (typeof alias === "string") {
60+
resolve(alias, stoppingCallback);
61+
} else if (alias.length > 1) {
62+
forEachBail(alias, resolve, stoppingCallback);
5763
} else {
58-
resolve(aliasArray[0], callback);
64+
resolve(alias[0], stoppingCallback);
5965
}
6066
});
6167
}

lib/ResolverFactory.js

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const UseFilePlugin = require("./UseFilePlugin");
4747

4848
/** @typedef {string|string[]|false} AliasOptionNewRequest */
4949
/** @typedef {{[k: string]: AliasOptionNewRequest}} AliasOptions */
50-
/** @typedef {{[k: string]: string[] }} ExtensionAliasOptions */
50+
/** @typedef {{[k: string]: string|string[] }} ExtensionAliasOptions */
5151
/** @typedef {{apply: function(Resolver): void} | function(this: Resolver, Resolver): void} Plugin */
5252

5353
/**
@@ -297,6 +297,8 @@ exports.createResolver = function (options) {
297297
resolver.ensureHook("newInternalResolve");
298298
resolver.ensureHook("parsedResolve");
299299
resolver.ensureHook("describedResolve");
300+
resolver.ensureHook("rawResolve");
301+
resolver.ensureHook("normalResolve");
300302
resolver.ensureHook("internal");
301303
resolver.ensureHook("rawModule");
302304
resolver.ensureHook("module");
@@ -356,21 +358,28 @@ exports.createResolver = function (options) {
356358
plugins.push(new NextPlugin("after-parsed-resolve", "described-resolve"));
357359

358360
// described-resolve
359-
plugins.push(new NextPlugin("described-resolve", "normal-resolve"));
361+
plugins.push(new NextPlugin("described-resolve", "raw-resolve"));
360362
if (fallback.length > 0) {
361363
plugins.push(
362364
new AliasPlugin("described-resolve", fallback, "internal-resolve")
363365
);
364366
}
365367

366-
// normal-resolve
367-
if (alias.length > 0)
368-
plugins.push(new AliasPlugin("normal-resolve", alias, "internal-resolve"));
368+
// raw-resolve
369+
if (alias.length > 0) {
370+
plugins.push(new AliasPlugin("raw-resolve", alias, "internal-resolve"));
371+
}
369372
aliasFields.forEach(item => {
370-
plugins.push(
371-
new AliasFieldPlugin("normal-resolve", item, "internal-resolve")
372-
);
373+
plugins.push(new AliasFieldPlugin("raw-resolve", item, "internal-resolve"));
373374
});
375+
extensionAlias.forEach(item =>
376+
plugins.push(
377+
new ExtensionAliasPlugin("raw-resolve", item, "normal-resolve")
378+
)
379+
);
380+
plugins.push(new NextPlugin("raw-resolve", "normal-resolve"));
381+
382+
// normal-resolve
374383
if (preferRelative) {
375384
plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
376385
}
@@ -616,9 +625,6 @@ exports.createResolver = function (options) {
616625
aliasFields.forEach(item => {
617626
plugins.push(new AliasFieldPlugin("file", item, "internal-resolve"));
618627
});
619-
extensionAlias.forEach(item =>
620-
plugins.push(new ExtensionAliasPlugin("file", item, "final-file"))
621-
);
622628
plugins.push(new NextPlugin("file", "final-file"));
623629

624630
// final-file

test/extension-alias.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ describe("extension-alias", () => {
1616
fileSystem: nodeFileSystem,
1717
mainFiles: ["index.js"],
1818
extensionAlias: {
19-
".js": [".ts", ".js"]
19+
".js": [".ts", ".js"],
20+
".mjs": ".mts"
2021
}
2122
});
2223

@@ -28,31 +29,38 @@ describe("extension-alias", () => {
2829
});
2930
});
3031

31-
it("should alias specified extension", done => {
32-
resolver.resolve({}, fixture, "./dir", {}, (err, result) => {
32+
it("should alias fully specified file when there are two alternatives", done => {
33+
resolver.resolve({}, fixture, "./dir/index.js", {}, (err, result) => {
3334
if (err) return done(err);
3435
should(result).be.eql(path.resolve(fixture, "dir", "index.ts"));
3536
done();
3637
});
3738
});
3839

39-
it("should result successfully without aliasing #1", done => {
40-
resolver.resolve({}, fixture, "./dir2", {}, (err, result) => {
40+
it("should also allow the second alternative", done => {
41+
resolver.resolve({}, fixture, "./dir2/index.js", {}, (err, result) => {
4142
if (err) return done(err);
4243
should(result).be.eql(path.resolve(fixture, "dir2", "index.js"));
4344
done();
4445
});
4546
});
4647

47-
it("should result successfully without aliasing #2", done => {
48-
resolver.resolve({}, fixture, "./dir2/index.js", {}, (err, result) => {
48+
it("should support alias option without an array", done => {
49+
resolver.resolve({}, fixture, "./dir2/index.mjs", {}, (err, result) => {
4950
if (err) return done(err);
50-
should(result).be.eql(path.resolve(fixture, "dir2", "index.js"));
51+
should(result).be.eql(path.resolve(fixture, "dir2", "index.mts"));
52+
done();
53+
});
54+
});
55+
56+
it("should not allow to fallback to the original extension or add extensions", done => {
57+
resolver.resolve({}, fixture, "./index.mjs", {}, (err, result) => {
58+
should(err).be.instanceOf(Error);
5159
done();
5260
});
5361
});
5462

55-
describe("should result successfully without alias array", () => {
63+
describe("should not apply extension alias to extensions or mainFiles field", () => {
5664
const resolver = ResolverFactory.createResolver({
5765
extensions: [".js"],
5866
fileSystem: nodeFileSystem,
@@ -71,7 +79,7 @@ describe("extension-alias", () => {
7179
});
7280

7381
it("file", done => {
74-
resolver.resolve({}, fixture, "./dir2/index.js", {}, (err, result) => {
82+
resolver.resolve({}, fixture, "./dir2/index", {}, (err, result) => {
7583
if (err) return done(err);
7684
should(result).be.eql(path.resolve(fixture, "dir2", "index.js"));
7785
done();

test/fixtures/extension-alias/dir2/index.mts

Whitespace-only changes.

test/fixtures/extension-alias/index.mjs

Whitespace-only changes.

test/fixtures/extension-alias/index.mts.js

Whitespace-only changes.

types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ declare interface ExtensionAliasOption {
9696
extension: string;
9797
}
9898
declare interface ExtensionAliasOptions {
99-
[index: string]: string[];
99+
[index: string]: string | string[];
100100
}
101101
declare interface FileSystem {
102102
readFile: {

0 commit comments

Comments
 (0)