Skip to content

Commit fdf5da9

Browse files
amosyuenfatfisz
authored andcommitted
feat: Add stripExtensions option to determine which extensions get removed (#247)
1 parent 00794c5 commit fdf5da9

5 files changed

Lines changed: 88 additions & 26 deletions

File tree

DOCS.md

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* [root](#root)
44
* [alias](#alias)
55
* [extensions](#extensions)
6+
* [stripExtensions](#stripExtensions)
67
* [cwd](#cwd)
78
* [transformFunctions](#transformfunctions)
89
* [resolvePath](#resolvepath)
@@ -20,6 +21,7 @@ $ npm install --save-dev babel-plugin-module-resolver
2021
```
2122

2223
Specify the plugin in your `.babelrc` with the custom root or alias. Here's an example:
24+
2325
```json
2426
{
2527
"plugins": [
@@ -100,9 +102,29 @@ An array of extensions used in the resolver.
100102
```json
101103
{
102104
"plugins": [
103-
["module-resolver", {
104-
"extensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
105-
}]
105+
[
106+
"module-resolver",
107+
{
108+
"extensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
109+
}
110+
]
111+
]
112+
}
113+
```
114+
115+
## stripExtensions
116+
117+
An array of extensions that will be stripped from file paths. Defaults to the `extensions` option value.
118+
119+
```json
120+
{
121+
"plugins": [
122+
[
123+
"module-resolver",
124+
{
125+
"stripExtensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
126+
}
127+
]
106128
]
107129
}
108130
```

src/normalizeOptions.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ export default createSelector(
141141
const alias = normalizeAlias(opts.alias);
142142
const transformFunctions = normalizeTransformedFunctions(opts.transformFunctions);
143143
const extensions = opts.extensions || defaultExtensions;
144+
const stripExtensions = opts.stripExtensions || extensions;
144145
const resolvePath = opts.resolvePath || defaultResolvePath;
145146

146147
return {
@@ -149,6 +150,7 @@ export default createSelector(
149150
alias,
150151
transformFunctions,
151152
extensions,
153+
stripExtensions,
152154
resolvePath,
153155
};
154156
},

src/resolvePath.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ import mapToRelative from './mapToRelative';
55
import normalizeOptions from './normalizeOptions';
66
import { nodeResolvePath, replaceExtension, toLocalPath, toPosixPath } from './utils';
77

8+
function getRelativePath(sourcePath, currentFile, absFileInRoot, opts) {
9+
const realSourceFileExtension = path.extname(absFileInRoot);
10+
const sourceFileExtension = path.extname(sourcePath);
11+
12+
let relativePath = mapToRelative(opts.cwd, currentFile, absFileInRoot);
13+
if (realSourceFileExtension !== sourceFileExtension) {
14+
relativePath = replaceExtension(relativePath, opts);
15+
}
16+
17+
return toLocalPath(toPosixPath(relativePath));
18+
}
819

920
function findPathInRoots(sourcePath, { extensions, root }) {
1021
// Search the source path inside every custom root directory
@@ -25,16 +36,7 @@ function resolvePathFromRootConfig(sourcePath, currentFile, opts) {
2536
return null;
2637
}
2738

28-
const realSourceFileExtension = path.extname(absFileInRoot);
29-
const sourceFileExtension = path.extname(sourcePath);
30-
31-
// Map the source and keep its extension if the import/require had one
32-
const ext = realSourceFileExtension === sourceFileExtension ? realSourceFileExtension : '';
33-
return toLocalPath(toPosixPath(replaceExtension(
34-
mapToRelative(opts.cwd, currentFile, absFileInRoot),
35-
ext,
36-
opts,
37-
)));
39+
return getRelativePath(sourcePath, currentFile, absFileInRoot, opts);
3840
}
3941

4042
function checkIfPackageExists(modulePath, currentFile, extensions) {

src/utils.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,20 @@ export function toLocalPath(modulePath) {
2121
.replace(/^(?!\.)/, './'); // insert `./` to make it a local path
2222
}
2323

24-
export function stripExtension(modulePath, extensions) {
25-
const [name, ...splits] = path.basename(modulePath).split('.');
26-
const fileExtension = `.${splits.join('.')}`;
27-
return extensions.reduce((filename, extension) => {
28-
// To allow filename to contain a dot
29-
if (extension === fileExtension) {
30-
// Strip extension
31-
return name;
24+
export function stripExtension(modulePath, stripExtensions) {
25+
let name = path.basename(modulePath);
26+
stripExtensions.some((extension) => {
27+
if (name.endsWith(extension)) {
28+
name = name.slice(0, name.length - extension.length);
29+
return true;
3230
}
33-
return filename;
34-
}, path.basename(modulePath, path.extname(modulePath)));
31+
return false;
32+
});
33+
return name;
3534
}
3635

37-
export function replaceExtension(modulePath, ext, opts) {
38-
const filename = stripExtension(modulePath, opts.extensions) + ext;
36+
export function replaceExtension(modulePath, opts) {
37+
const filename = stripExtension(modulePath, opts.stripExtensions);
3938
return path.join(path.dirname(modulePath), filename);
4039
}
4140

test/index.test.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ describe('module-resolver', () => {
241241
plugins: [
242242
[plugin, {
243243
root: './test/testproject/src',
244-
extensions: ['.js', '.ios.js', '.android.js'],
244+
extensions: ['.ios.js', '.android.js', '.js'],
245245
}],
246246
],
247247
};
@@ -261,6 +261,43 @@ describe('module-resolver', () => {
261261
rootTransformerOpts,
262262
);
263263
});
264+
265+
it('should resolve the file path with an explicit extension and not strip the extension', () => {
266+
testWithImport(
267+
'rn/index.ios.js',
268+
'./test/testproject/src/rn/index.ios.js',
269+
rootTransformerOpts,
270+
);
271+
});
272+
});
273+
274+
describe('non-standard double extensions with strip extensions', () => {
275+
const rootTransformerOpts = {
276+
babelrc: false,
277+
plugins: [
278+
[plugin, {
279+
root: './test/testproject/src',
280+
extensions: ['.js', '.ios.js', '.android.js'],
281+
stripExtensions: [],
282+
}],
283+
],
284+
};
285+
286+
it('should not resolve the file path with an unknown extension', () => {
287+
testWithImport(
288+
'text',
289+
'text',
290+
rootTransformerOpts,
291+
);
292+
});
293+
294+
it('should resolve the file path with a known defined extension', () => {
295+
testWithImport(
296+
'rn',
297+
'./test/testproject/src/rn/index.ios.js',
298+
rootTransformerOpts,
299+
);
300+
});
264301
});
265302

266303
describe('root and alias', () => {

0 commit comments

Comments
 (0)