Skip to content

Commit

Permalink
feat: Add stripExtensions option to determine which extensions get re…
Browse files Browse the repository at this point in the history
…moved (#247)
  • Loading branch information
amosyuen authored and fatfisz committed Dec 22, 2017
1 parent 00794c5 commit fdf5da9
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 26 deletions.
28 changes: 25 additions & 3 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* [root](#root)
* [alias](#alias)
* [extensions](#extensions)
* [stripExtensions](#stripExtensions)
* [cwd](#cwd)
* [transformFunctions](#transformfunctions)
* [resolvePath](#resolvepath)
Expand All @@ -20,6 +21,7 @@ $ npm install --save-dev babel-plugin-module-resolver
```

Specify the plugin in your `.babelrc` with the custom root or alias. Here's an example:

```json
{
"plugins": [
Expand Down Expand Up @@ -100,9 +102,29 @@ An array of extensions used in the resolver.
```json
{
"plugins": [
["module-resolver", {
"extensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
}]
[
"module-resolver",
{
"extensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
}
]
]
}
```

## stripExtensions

An array of extensions that will be stripped from file paths. Defaults to the `extensions` option value.

```json
{
"plugins": [
[
"module-resolver",
{
"stripExtensions": [".js", ".jsx", ".es", ".es6", ".mjs"]
}
]
]
}
```
Expand Down
2 changes: 2 additions & 0 deletions src/normalizeOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export default createSelector(
const alias = normalizeAlias(opts.alias);
const transformFunctions = normalizeTransformedFunctions(opts.transformFunctions);
const extensions = opts.extensions || defaultExtensions;
const stripExtensions = opts.stripExtensions || extensions;
const resolvePath = opts.resolvePath || defaultResolvePath;

return {
Expand All @@ -149,6 +150,7 @@ export default createSelector(
alias,
transformFunctions,
extensions,
stripExtensions,
resolvePath,
};
},
Expand Down
22 changes: 12 additions & 10 deletions src/resolvePath.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ import mapToRelative from './mapToRelative';
import normalizeOptions from './normalizeOptions';
import { nodeResolvePath, replaceExtension, toLocalPath, toPosixPath } from './utils';

function getRelativePath(sourcePath, currentFile, absFileInRoot, opts) {
const realSourceFileExtension = path.extname(absFileInRoot);
const sourceFileExtension = path.extname(sourcePath);

let relativePath = mapToRelative(opts.cwd, currentFile, absFileInRoot);
if (realSourceFileExtension !== sourceFileExtension) {
relativePath = replaceExtension(relativePath, opts);
}

return toLocalPath(toPosixPath(relativePath));
}

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

const realSourceFileExtension = path.extname(absFileInRoot);
const sourceFileExtension = path.extname(sourcePath);

// Map the source and keep its extension if the import/require had one
const ext = realSourceFileExtension === sourceFileExtension ? realSourceFileExtension : '';
return toLocalPath(toPosixPath(replaceExtension(
mapToRelative(opts.cwd, currentFile, absFileInRoot),
ext,
opts,
)));
return getRelativePath(sourcePath, currentFile, absFileInRoot, opts);
}

function checkIfPackageExists(modulePath, currentFile, extensions) {
Expand Down
23 changes: 11 additions & 12 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,20 @@ export function toLocalPath(modulePath) {
.replace(/^(?!\.)/, './'); // insert `./` to make it a local path
}

export function stripExtension(modulePath, extensions) {
const [name, ...splits] = path.basename(modulePath).split('.');
const fileExtension = `.${splits.join('.')}`;
return extensions.reduce((filename, extension) => {
// To allow filename to contain a dot
if (extension === fileExtension) {
// Strip extension
return name;
export function stripExtension(modulePath, stripExtensions) {
let name = path.basename(modulePath);
stripExtensions.some((extension) => {
if (name.endsWith(extension)) {
name = name.slice(0, name.length - extension.length);
return true;
}
return filename;
}, path.basename(modulePath, path.extname(modulePath)));
return false;
});
return name;
}

export function replaceExtension(modulePath, ext, opts) {
const filename = stripExtension(modulePath, opts.extensions) + ext;
export function replaceExtension(modulePath, opts) {
const filename = stripExtension(modulePath, opts.stripExtensions);
return path.join(path.dirname(modulePath), filename);
}

Expand Down
39 changes: 38 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ describe('module-resolver', () => {
plugins: [
[plugin, {
root: './test/testproject/src',
extensions: ['.js', '.ios.js', '.android.js'],
extensions: ['.ios.js', '.android.js', '.js'],
}],
],
};
Expand All @@ -261,6 +261,43 @@ describe('module-resolver', () => {
rootTransformerOpts,
);
});

it('should resolve the file path with an explicit extension and not strip the extension', () => {
testWithImport(
'rn/index.ios.js',
'./test/testproject/src/rn/index.ios.js',
rootTransformerOpts,
);
});
});

describe('non-standard double extensions with strip extensions', () => {
const rootTransformerOpts = {
babelrc: false,
plugins: [
[plugin, {
root: './test/testproject/src',
extensions: ['.js', '.ios.js', '.android.js'],
stripExtensions: [],
}],
],
};

it('should not resolve the file path with an unknown extension', () => {
testWithImport(
'text',
'text',
rootTransformerOpts,
);
});

it('should resolve the file path with a known defined extension', () => {
testWithImport(
'rn',
'./test/testproject/src/rn/index.ios.js',
rootTransformerOpts,
);
});
});

describe('root and alias', () => {
Expand Down

0 comments on commit fdf5da9

Please sign in to comment.