Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
}
},
"rules": {
"comma-dangle": 0,
"indent": [2, 4, {"SwitchCase": 1}],
"indent": [2, 4, { "SwitchCase": 1 }],
"max-len": 0
}
}
31 changes: 16 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "babel-plugin-module-resolver",
"version": "2.2.0",
"main": "lib/index.js",
"description": "Babel plugin to rewrite the path in require() and ES6 import",
"description": "Module resolver plugin for Babel",
"repository": {
"type": "git",
"url": "https://github.com/tleunen/babel-plugin-module-resolver.git"
Expand All @@ -27,23 +27,24 @@
"import"
],
"dependencies": {
"glob": "^7.0.6",
"find-babel-config": "^1.0.1",
"glob": "^7.1.1",
"resolve": "^1.1.7"
},
"devDependencies": {
"babel-cli": "^6.10.1",
"babel-core": "^6.10.4",
"babel-plugin-istanbul": "^2.0.0",
"babel-plugin-transform-object-rest-spread": "^6.8.0",
"babel-preset-es2015": "^6.6.0",
"babel-register": "^6.8.0",
"cross-env": "^2.0.0",
"eslint": "^3.3.0",
"eslint-config-airbnb-base": "^5.0.2",
"eslint-plugin-import": "^1.13.0",
"mocha": "^3.0.2",
"nyc": "^8.1.0",
"standard-version": "^2.4.0"
"babel-cli": "^6.16.0",
"babel-core": "^6.17.0",
"babel-plugin-istanbul": "^2.0.1",
"babel-plugin-transform-object-rest-spread": "^6.16.0",
"babel-preset-es2015": "^6.16.0",
"babel-register": "^6.16.3",
"cross-env": "^3.1.2",
"eslint": "^3.7.1",
"eslint-config-airbnb-base": "^8.0.0",
"eslint-plugin-import": "^1.16.0",
"mocha": "^3.1.1",
"nyc": "^8.3.1",
"standard-version": "^3.0.0"
},
"scripts": {
"lint": "eslint src test",
Expand Down
72 changes: 40 additions & 32 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,47 @@
import path from 'path';
import resolve from 'resolve';
import glob from 'glob';
import findBabelConfig from 'find-babel-config';
import mapToRelative from './mapToRelative';
import { toLocalPath, toPosixPath } from './utils';

function createAliasFileMap(pluginOpts) {
const alias = pluginOpts.alias || {};
return Object.keys(alias).reduce((memo, expose) => (
Object.assign(memo, {
[expose]: alias[expose]
})
), {});
}

function replaceExt(p, ext) {
const filename = path.basename(p, path.extname(p)) + ext;
return path.join(path.dirname(p), filename);
}

const defaultBabelExtensions = ['.js', '.jsx', '.es', '.es6'];

export function mapModule(source, file, pluginOpts) {
export function mapModule(source, file, pluginOpts, cwd) {
// Do not map source starting with a dot
if (source[0] === '.') {
return null;
}

// Search the file under the custom root directories
const rootDirs = pluginOpts.root || [];
for (let i = 0; i < rootDirs.length; i++) {
const extensions = pluginOpts.extensions || defaultBabelExtensions;
let resolvedSourceFile;
rootDirs.some((dir) => {
try {
// check if the file exists (will throw if not)
const extensions = pluginOpts.extensions || defaultBabelExtensions;
const resolvedSourceFile = resolve.sync(`./${source}`, { basedir: path.resolve(rootDirs[i]), extensions });
const realSourceFileExtension = path.extname(resolvedSourceFile);
const sourceFileExtension = path.extname(source);
// map the source and keep its extension if the import/require had one
const ext = realSourceFileExtension === sourceFileExtension ? realSourceFileExtension : '';
return toLocalPath(toPosixPath(replaceExt(mapToRelative(file, resolvedSourceFile), ext)));
resolvedSourceFile = resolve.sync(`./${source}`, { basedir: path.resolve(cwd, dir), extensions });
return true;
} catch (e) {
// empty...
return false;
}
});

if (resolvedSourceFile) {
const realSourceFileExtension = path.extname(resolvedSourceFile);
const sourceFileExtension = path.extname(source);
// map the source and keep its extension if the import/require had one
const ext = realSourceFileExtension === sourceFileExtension ? realSourceFileExtension : '';
return toLocalPath(toPosixPath(replaceExt(mapToRelative(cwd, file, resolvedSourceFile), ext)));
}

// The source file wasn't found in any of the root directories. Lets try the alias
const aliasMapping = createAliasFileMap(pluginOpts);
const aliasMapping = pluginOpts.alias || {};
const moduleSplit = source.split('/');

let aliasPath;
Expand All @@ -71,12 +68,11 @@ export function mapModule(source, file, pluginOpts) {
return newPath;
}
// relative alias
return toLocalPath(toPosixPath(mapToRelative(file, newPath)));
return toLocalPath(toPosixPath(mapToRelative(cwd, file, newPath)));
}


export default ({ types: t }) => {
function transformRequireCall(nodePath, state) {
function transformRequireCall(nodePath, state, cwd) {
if (
!t.isIdentifier(nodePath.node.callee, { name: 'require' }) &&
!(
Expand All @@ -89,7 +85,7 @@ export default ({ types: t }) => {

const moduleArg = nodePath.node.arguments[0];
if (moduleArg && moduleArg.type === 'StringLiteral') {
const modulePath = mapModule(moduleArg.value, state.file.opts.filename, state.opts);
const modulePath = mapModule(moduleArg.value, state.file.opts.filename, state.opts, cwd);
if (modulePath) {
nodePath.replaceWith(t.callExpression(
nodePath.node.callee, [t.stringLiteral(modulePath)]
Expand All @@ -98,10 +94,10 @@ export default ({ types: t }) => {
}
}

function transformImportCall(nodePath, state) {
function transformImportCall(nodePath, state, cwd) {
const moduleArg = nodePath.node.source;
if (moduleArg && moduleArg.type === 'StringLiteral') {
const modulePath = mapModule(moduleArg.value, state.file.opts.filename, state.opts);
const modulePath = mapModule(moduleArg.value, state.file.opts.filename, state.opts, cwd);
if (modulePath) {
nodePath.replaceWith(t.importDeclaration(
nodePath.node.specifiers,
Expand All @@ -112,6 +108,17 @@ export default ({ types: t }) => {
}

return {
pre(file) {
const startPath = (file.opts.filename === 'unknown')
? './'
: file.opts.filename;

const { file: babelFile } = findBabelConfig.sync(startPath);
this.moduleResolverCWD = babelFile
? path.dirname(babelFile)
: process.cwd();
},

manipulateOptions(babelOptions) {
const findPluginOptions = babelOptions.plugins.find(plugin => plugin[0] === this)[1];
if (findPluginOptions.root) {
Expand All @@ -123,17 +130,18 @@ export default ({ types: t }) => {
}, []);
}
},

visitor: {
CallExpression: {
exit(nodePath, state) {
return transformRequireCall(nodePath, state);
}
return transformRequireCall(nodePath, state, this.moduleResolverCWD);
},
},
ImportDeclaration: {
exit(nodePath, state) {
return transformImportCall(nodePath, state);
}
}
}
return transformImportCall(nodePath, state, this.moduleResolverCWD);
},
},
},
};
};
10 changes: 5 additions & 5 deletions src/mapToRelative.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import path from 'path';
import { toPosixPath } from './utils';

function resolve(filename) {
function resolve(cwd, filename) {
if (path.isAbsolute(filename)) return filename;
return path.resolve(process.cwd(), filename);
return path.resolve(cwd, filename);
}

export default function mapToRelative(currentFile, module) {
export default function mapToRelative(cwd, currentFile, module) {
let from = path.dirname(currentFile);
let to = path.normalize(module);

from = resolve(from);
to = resolve(to);
from = resolve(cwd, from);
to = resolve(cwd, to);

const moduleMapped = path.relative(from, to);
return toPosixPath(moduleMapped);
Expand Down
24 changes: 12 additions & 12 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ describe('module-resolver', () => {
[plugin, {
root: [
'./test/examples/components',
'./test/examples/foo'
]
}]
]
'./test/examples/foo',
],
}],
],
};

const transformerOptsGlob = {
plugins: [
[plugin, {
root: ['./test/**/components']
}]
]
root: ['./test/**/components'],
}],
],
};

describe('should resolve the file path', () => {
Expand Down Expand Up @@ -89,7 +89,7 @@ describe('module-resolver', () => {
'../bar',
{
...transformerOpts,
filename: './test/examples/foo/bar/x.js'
filename: './test/examples/foo/bar/x.js',
}
);
});
Expand All @@ -111,10 +111,10 @@ describe('module-resolver', () => {
utils: './src/mylib/subfolder/utils',
'awesome/components': './src/components',
abstract: 'npm:concrete',
underscore: 'lodash'
}
}]
]
underscore: 'lodash',
},
}],
],
};

describe('with a simple alias', () => {
Expand Down
16 changes: 3 additions & 13 deletions test/mapToRelative.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,17 @@ import assert from 'assert';
import mapToRelative from '../src/mapToRelative';

describe('mapToRelative', () => {
describe('should map to relative path when cwd has been changed', () => {
const cwd = process.cwd();

before(() => {
process.chdir('./test');
});

after(() => {
process.chdir(cwd);
});

describe('should map to relative path with a custom cwd', () => {
it('with relative filename', () => {
const currentFile = './utils/test/file.js';
const result = mapToRelative(currentFile, 'utils/dep');
const result = mapToRelative(path.resolve('./test'), currentFile, 'utils/dep');

assert.strictEqual(result, '../dep');
});

it('with absolute filename', () => {
const currentFile = path.join(process.cwd(), './utils/test/file.js');
const result = mapToRelative(currentFile, 'utils/dep');
const result = mapToRelative(process.cwd(), currentFile, 'utils/dep');

assert.strictEqual(result, '../dep');
});
Expand Down