Skip to content

Adds ability to support array of alias values. #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ module.exports = {
['babel-polyfill', 'babel-polyfill/dist/polyfill.min.js'],
['helper', './utils/helper'],
['material-ui/DatePicker', '../custom/DatePicker'],
['material-ui', 'material-ui-ie10']
['material-ui', 'material-ui-ie10'],
['lib', ['app/lib', 'common/lib']]
],
extensions: ['.ts', '.js', '.jsx', '.json']
}
Expand All @@ -62,6 +63,7 @@ Note:
- The item of `map` array is also array type which contains 2 string
+ The first string represents the alias of module name or path
+ The second string represents the actual module name or path
+ The second string may also be an array that is evaluated in order, with the first found used as resolved
- The `map` item `['helper', './utils/helper']` means that the modules which match `helper` or `helper/*` will be resolved to `./utils/helper` or `./utils/helper/*` which are located relative to the `process current working directory` (almost the project root directory). If you just want to resolve `helper` to `./utils/helper`, use `['^helper$', './utils/helper']` instead. See [issue #3](https://github.com/johvin/eslint-import-resolver-alias/issues/3)
- The order of 'material-ui/DatePicker' and 'material-ui' cannot be reversed, otherwise the alias rule 'material-ui/DatePicker' does not work
- The default value of `extensions` property is `['.js', '.json', '.node']` if it is assigned to an empty array or not specified
Expand Down
49 changes: 39 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,39 @@ exports.resolve = (modulePath, sourceFile, config) => {
const re = new RegExp(`^${map[i][0]}($|/)`);
const match = modulePath.match(re);
if (match) {
resolvePath = modulePath.replace(match[0], `${map[i][1]}${match[1]}`);
resolvePath = getResolvePath(modulePath, match, map[i][1], extensions, sourceDir);
break;
}
}
}

// there is a relative path mapping in alias.map,
// the relative path is relative to the project root directory
if (resolvePath[0] === '.') {
resolvePath = path.resolve(process.cwd(), resolvePath);
return findModulePath(resolvePath, null, extensions);
}

const paths = resolveLookupPaths(sourceDir);
return findModulePath(resolvePath, paths, extensions);
return smartFindModulePath(resolvePath, extensions, sourceDir);
};

// Get the resolved path
function getResolvePath(alias, match, actual, extensions, sourceDir) {
if (Array.isArray(actual)) {
let resolvePath, found;

// Iterate through all possible paths
for (let i = 0; i < actual.length; i++) {
resolvePath = alias.replace(match[0], `${actual[i]}${match[1]}`);
found = smartFindModulePath(resolvePath, extensions, sourceDir);

// If path resolves, use it, don't check any more
if (found.found) {
return resolvePath;
}
}

// If no paths resolve, still return final path, we want to know if no paths resolve
return resolvePath;
}
else {
return alias.replace(match[0], `${actual}${match[1]}`);
}
}

// get extension object like Module._extensions
function getExtensions(extArray) {
if (Array.isArray(extArray) && extArray.length > 0) {
Expand All @@ -87,6 +103,19 @@ function getExtensions(extArray) {
return null;
}

// Find module path, taking into account relative paths
function smartFindModulePath(resolvePath, extensions, sourceDir) {
// there is a relative path mapping in alias.map,
// the relative path is relative to the project root directory
if (resolvePath[0] === '.') {
resolvePath = path.resolve(process.cwd(), resolvePath);
return findModulePath(resolvePath, null, extensions);
}

const paths = resolveLookupPaths(sourceDir);
return findModulePath(resolvePath, paths, extensions);
}

// find module path according to support file extensions.
function findModulePath(request, paths, extArray) {
if (extArray) {
Expand Down
4 changes: 3 additions & 1 deletion test/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ const files = [
`${moduleDir}/module2/smile.js`,
`${moduleDir}/module2/nav.jsx`,
`${moduleDir}/polyfill2/polyfill.min.js`,
`${moduleDir}/mod/a.js`
`${moduleDir}/has_abc/abc.js`,
`${moduleDir}/has_def/def.js`,
`${moduleDir}/mod/a.js`,
];

files.forEach(file => {
Expand Down
26 changes: 24 additions & 2 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ describe('resolver-alias/index.js', () => {
['red', './nothing'], // should not impact the paths which contain red and not starts with red
['module3', 'module2'],
['srcCore', './core'],
['relativeSetup', './test/setup']
['relativeSetup', './test/setup'],
['arrayPaths', ['has_abc', 'has_none', 'has_def']],
],
extensions: ['.js', '.ts', '.jsx', '.json']
};
Expand Down Expand Up @@ -43,6 +44,16 @@ describe('resolver-alias/index.js', () => {
'srcCore',
'relativeSetup'
];
const aliasModuleArrayPathArr = [
'module3/heihei',
'module3/styles/red',
'module3/nav',
'polyfill',
'core/red',
'core',
'arrayPaths/abc',
'arrayPaths/def',
];
const noneExistModulePathArr = [
'abc/ggg',
'module2/bye',
Expand Down Expand Up @@ -132,6 +143,18 @@ describe('resolver-alias/index.js', () => {
});
});

it('resolve alias modules that have an array of actual modules or paths', () => {
aliasModuleArrayPathArr.forEach((p) => {
const resolveModule = resolver.resolve(p, sourceFile, alias);
assert(resolveModule.found, `alias modulePath ${p} isn't resolved`);
});
});

it('unable to resolve array modules that do not exist', () => {
const resolveModule = resolver.resolve('arrayPaths/ghi', sourceFile, alias);
assert(!resolveModule.found, `alias modulePath arrayPaths/ghi is resolved`);
});

it('unable to resolve the modules that do not exist', () => {
noneExistModulePathArr.forEach((p) => {
const resolveModule = resolver.resolve(p, sourceFile, alias);
Expand All @@ -154,5 +177,4 @@ describe('resolver-alias/index.js', () => {
const a = require('mod/a');
assert(a.abc.found && a.abc.path != null, 'exist module is not resolved');
});

});