Skip to content

Commit

Permalink
Support passing configuration through .eslintrc
Browse files Browse the repository at this point in the history
  • Loading branch information
unconfident committed Feb 7, 2018
1 parent fd301a0 commit 3209c77
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Inside your `.eslintrc` file, pass this resolver to `eslint-plugin-import`:
```

And see [babel-plugin-root-import] to know how to configure your prefix/suffix.
Configuration will be parsed down from `.babelrc` file
Configuration will be parsed down from `.babelrc` file

### Example

Expand All @@ -38,6 +38,24 @@ Configuration will be parsed down from `.babelrc` file
}
```

Or if you don't use `.babelrc` and keep your babel configuration in, say, webpack
config you can pass those options to resolver directly through `.eslintrc` file:

```json
{
"extends": "airbnb",
"rules": {},
"settings": {
"import/resolver": {
"babel-plugin-root-import": {
"rootPathPrefix": "@",
"rootPathSuffix": "src/js"
}
}
}
}
```

## License

MIT, see [LICENSE.md](/LICENSE.md) for details.
Expand Down
34 changes: 23 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ function isString(value) {
return typeof value === 'string';
}

function isObject(value) {
return value !== null && typeof value === 'object';
}

// returns the root import config as an object. Or an array
function getConfigFromBabel(directory, babelrcName = '.babelrc') {
const babelrcPath = babelrcName && path.join(directory, babelrcName);
Expand Down Expand Up @@ -58,22 +62,30 @@ exports.interfaceVersion = 2;
* resolveImport('./foo', '/Users/ben/bar.js') => '/Users/ben/foo.js'
* @param {string} source - the module to resolve; i.e './some-module'
* @param {string} file - the importing file's full path; i.e. '/usr/local/bin/file.js'
* @param {object} config - the resolver options
* @param {string} babelrc - the name of the babelrc file
* @param {null|object|array} [config] - the resolver options
* @param {string} [babelrc] - the name of the babelrc file
* @return {object}
*/
exports.resolve = (source, file, config, babelrc) => {
const optionsRaw = getConfigFromBabel(process.cwd(), babelrc);
const opts = [].concat(optionsRaw || []);

if (optionsRaw === null) {
return nodeResolve(source, file, config);
exports.resolve = (source, file, config = {}, babelrc = '.babelrc') => {
// Consider any array or an object w/ rootPathPrefix or rootPathSuffix key a valid alias configuration
const isValidConfiguration = Array.isArray(config) ||
isObject(config) && (
config.hasOwnProperty('rootPathPrefix') ||
config.hasOwnProperty('rootPathSuffix')
);

const options = isValidConfiguration ? config : getConfigFromBabel(process.cwd(), babelrc);
const optsArray = [].concat(options || []);

// If parsed config from babel and plugin wasn't listed there
if (!isValidConfiguration && options === null) {
return nodeResolve(source, file, {});
}

// This empty object becomes default '~/` prefix mapped to root during the next step
if (opts.length === 0) opts.push({});
if (optsArray.length === 0) optsArray.push({});

const rootPathConfig = opts.map((item = {}) => ({
const rootPathConfig = optsArray.map((item = {}) => ({
rootPathPrefix: isString(item.rootPathPrefix) ? item.rootPathPrefix : '~',
rootPathSuffix: isString(item.rootPathSuffix) ? item.rootPathSuffix.replace(/^(\/)|(\/)$/g, '') : ''
}));
Expand All @@ -94,6 +106,6 @@ exports.resolve = (source, file, config, babelrc) => {
// Node resolver expects that path would be relative to file, so we have to resolve it first
transformedSource = path.resolve(transformedSource);

return nodeResolve(transformedSource, file, config);
return nodeResolve(transformedSource, file, {});
};

29 changes: 29 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,35 @@ test('Resolves files required from a file deeper in the tree', (t) => {
t.end();
});

test('Supports passing aliases directly through eslint import/resolver settings', (t) => {
t.deepEqual(
resolve('#/file', __filename, [
{ rootPathPrefix: '@', rootPathSuffix: 'modules' },
{ rootPathPrefix: '#', rootPathSuffix: 'modules/anotherpath' },
]),
expectResolvedTo('modules/anotherpath/file.js'),
'Array of objects w/ rootPathPrefix and rootPathSuffix'
);

t.deepEqual(
resolve('~/file', __filename, {
rootPathSuffix: 'modules/anotherpath'
}),
expectResolvedTo('modules/anotherpath/file.js'),
'Object, only suffix specified'
);

t.deepEqual(
resolve('!/modules/file', __filename, {
rootPathPrefix: '!'
}),
expectResolvedTo('modules/file.js'),
'Object, only prefix specified'
);

t.end();
});

test('Correctly resolves default prefix (~/) when no configuration provided', (t) => {
const result = resolve('~/modules/file', relativeToTestDir('./some/other/file.js'), {}, '.babelrcNoConf');
const result2 = resolve('~/modules/file', relativeToTestDir('./some/other/file.js'), {}, '.babelrcNoConfArray');
Expand Down

0 comments on commit 3209c77

Please sign in to comment.