Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Add support for importing index.js from aliased directories path #38

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
node_modules
npm-debug.log

dist
104 changes: 104 additions & 0 deletions dist/rollup-plugin-alias.es2015.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import path, { posix } from 'path';
import { platform } from 'os';
import fs from 'fs';
import slash from 'slash';

const VOLUME = /^([A-Z]:)/;
const IS_WINDOWS = platform() === 'win32';

// Helper functions
const noop = () => null;
const matches = (key, importee) => {
if (importee.length < key.length) {
return false;
}
if (importee === key) {
return true;
}
const importeeStartsWithKey = (importee.indexOf(key) === 0);
const importeeHasSlashAfterKey = (importee.substring(key.length)[0] === '/');
return importeeStartsWithKey && importeeHasSlashAfterKey;
};
const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
const isFilePath = id => /^\.?\//.test(id);
const exists = uri => {
try {
return fs.statSync(uri).isFile();
} catch (e) {
return false;
}
};

const normalizeId = id => {
if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
return slash(id.replace(VOLUME, ''));
}

return id;
};

function alias(options = {}) {
const hasResolve = Array.isArray(options.resolve);
const resolve = hasResolve ? options.resolve : ['.js'];
const aliasKeys = hasResolve ?
Object.keys(options).filter(k => k !== 'resolve') : Object.keys(options);

// No aliases?
if (!aliasKeys.length) {
return {
resolveId: noop,
};
}

return {
resolveId(importee, importer) {
const importeeId = normalizeId(importee);
const importerId = normalizeId(importer);

// First match is supposed to be the correct one
const toReplace = aliasKeys.find(key => matches(key, importeeId));

if (!toReplace || !importerId) {
return null;
}

const entry = options[toReplace];

let updatedId = normalizeId(importeeId.replace(toReplace, entry));

if (isFilePath(updatedId)) {
const directory = posix.dirname(importerId);

// Resolve file names
const filePath = posix.resolve(directory, updatedId);

const match = resolve.map(ext => (endsWith(ext, filePath) ? filePath : `${filePath}${ext}`))
.find(exists);

if (match) {
updatedId = match;
// To keep the previous behaviour we simply return the file path
// with extension
} else if (endsWith('.js', filePath)) {
updatedId = filePath;
// See if filePath + /index.js exists, then use it
} else if (fs.existsSync(posix.join(filePath, 'index.js'))) {
updatedId = posix.join(filePath, 'index.js');
} else {
updatedId = filePath + '.js';
}
}

// if alias is windows absoulate path return resolved path or
// rollup on windows will throw:
// [TypeError: Cannot read property 'specifier' of undefined]
if (VOLUME.test(entry)) {
return path.resolve(updatedId);
}

return updatedId;
},
};
}

export default alias;
109 changes: 109 additions & 0 deletions dist/rollup-plugin-alias.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var path = require('path');
var path__default = _interopDefault(path);
var os = require('os');
var fs = _interopDefault(require('fs'));
var slash = _interopDefault(require('slash'));

const VOLUME = /^([A-Z]:)/;
const IS_WINDOWS = os.platform() === 'win32';

// Helper functions
const noop = () => null;
const matches = (key, importee) => {
if (importee.length < key.length) {
return false;
}
if (importee === key) {
return true;
}
const importeeStartsWithKey = (importee.indexOf(key) === 0);
const importeeHasSlashAfterKey = (importee.substring(key.length)[0] === '/');
return importeeStartsWithKey && importeeHasSlashAfterKey;
};
const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
const isFilePath = id => /^\.?\//.test(id);
const exists = uri => {
try {
return fs.statSync(uri).isFile();
} catch (e) {
return false;
}
};

const normalizeId = id => {
if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
return slash(id.replace(VOLUME, ''));
}

return id;
};

function alias(options = {}) {
const hasResolve = Array.isArray(options.resolve);
const resolve = hasResolve ? options.resolve : ['.js'];
const aliasKeys = hasResolve ?
Object.keys(options).filter(k => k !== 'resolve') : Object.keys(options);

// No aliases?
if (!aliasKeys.length) {
return {
resolveId: noop,
};
}

return {
resolveId(importee, importer) {
const importeeId = normalizeId(importee);
const importerId = normalizeId(importer);

// First match is supposed to be the correct one
const toReplace = aliasKeys.find(key => matches(key, importeeId));

if (!toReplace || !importerId) {
return null;
}

const entry = options[toReplace];

let updatedId = normalizeId(importeeId.replace(toReplace, entry));

if (isFilePath(updatedId)) {
const directory = path.posix.dirname(importerId);

// Resolve file names
const filePath = path.posix.resolve(directory, updatedId);

const match = resolve.map(ext => (endsWith(ext, filePath) ? filePath : `${filePath}${ext}`))
.find(exists);

if (match) {
updatedId = match;
// To keep the previous behaviour we simply return the file path
// with extension
} else if (endsWith('.js', filePath)) {
updatedId = filePath;
// See if filePath + /index.js exists, then use it
} else if (fs.existsSync(path.posix.join(filePath, 'index.js'))) {
updatedId = path.posix.join(filePath, 'index.js');
} else {
updatedId = filePath + '.js';
}
}

// if alias is windows absoulate path return resolved path or
// rollup on windows will throw:
// [TypeError: Cannot read property 'specifier' of undefined]
if (VOLUME.test(entry)) {
return path__default.resolve(updatedId);
}

return updatedId;
},
};
}

module.exports = alias;
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default function alias(options = {}) {

// Resolve file names
const filePath = posix.resolve(directory, updatedId);

const match = resolve.map(ext => (endsWith(ext, filePath) ? filePath : `${filePath}${ext}`))
.find(exists);

Expand All @@ -81,6 +82,9 @@ export default function alias(options = {}) {
// with extension
} else if (endsWith('.js', filePath)) {
updatedId = filePath;
// See if filePath + /index.js exists, then use it
} else if (fs.existsSync(posix.join(filePath, 'index.js'))) {
updatedId = posix.join(filePath, 'index.js');
} else {
updatedId = filePath + '.js';
}
Expand Down
1 change: 1 addition & 0 deletions test/files/folder/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 123;
3 changes: 2 additions & 1 deletion test/files/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import fancyNumber from 'fancyNumber';
import anotherFancyNumber from './anotherFancyNumber';
import anotherNumber from './numberFolder/anotherNumber';
import moreNumbers from 'numberFolder/anotherNumber';
import index from './numberFolder';

export default fancyNumber + anotherFancyNumber + nonAliased + anotherNumber + moreNumbers;
export default fancyNumber + anotherFancyNumber + nonAliased + anotherNumber + moreNumbers + index;
15 changes: 13 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ test('Platform path.resolve(\'file-with.ext\') aliasing', t => {
t.is(resolved, path.resolve('./files/folder/hipster.jsx'));
});

test('index.js resolve', t => {
const result = alias({
test: path.resolve('./files/folder'),
});

const resolved = result.resolveId('test', posix.resolve(DIRNAME, './files/index.js'));

t.is(resolved, path.resolve('./files/folder/index.js'));
});

// Tests in Rollup
test(t =>
rollup({
Expand All @@ -179,7 +189,8 @@ test(t =>
t.is(stats.modules[1].id.endsWith(path.normalize('/files/aliasMe.js')), true);
t.is(stats.modules[2].id.endsWith(path.normalize('/files/localAliasMe.js')), true);
t.is(stats.modules[3].id.endsWith(path.normalize('/files/folder/anotherNumber.js')), true);
t.is(stats.modules[4].id.endsWith(path.normalize('/files/index.js')), true);
t.is(stats.modules.length, 5);
t.is(stats.modules[4].id.endsWith(path.normalize('/files/folder/index.js')), true);
t.is(stats.modules[5].id.endsWith(path.normalize('/files/index.js')), true);
t.is(stats.modules.length, 6);
})
);
Loading