Skip to content
This repository was archived by the owner on Aug 4, 2021. It is now read-only.
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
47 changes: 24 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { posix as path } from 'path';
import { platform } from 'os';
import path from 'path';
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) => {
Expand All @@ -21,18 +16,18 @@ const matches = (key, importee) => {
return importeeStartsWithKey && importeeHasSlashAfterKey;
};
const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
const isFilePath = id => /^\.?\//.test(id);
const isAbsolutePath = id => /^(?:\/|(?:[A-Za-z]:)?[\\\/])/.test(id);
const isRelativePath = 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') {
return slash(id.replace(VOLUME, ''));
if (typeof id === 'string') {
return slash(id);
}

return id;
Expand Down Expand Up @@ -63,29 +58,35 @@ export default function alias(options = {}) {
return null;
}

const entry = options[toReplace];
const entry = normalizeId(options[toReplace]);

const updatedId = importeeId.replace(toReplace, entry);

if (isFilePath(updatedId)) {
const directory = path.dirname(importerId);
if (isRelativePath(updatedId) || isAbsolutePath(updatedId)) {
let filePath;
if (isRelativePath(updatedId) && importer === undefined) {
// Cannot handle this, so return null
return null;
} else if (isRelativePath(updatedId) && importer !== undefined) {
// Resolve file names
filePath = path.resolve(path.dirname(importerId), updatedId);
} else {
// Absolute path doesn't need resolve
filePath = updatedId;
}

// Resolve file names
const filePath = path.resolve(directory, updatedId);
const match = resolve.map(ext => `${filePath}${ext}`)
.find(exists);

if (match) {
return match;
}

// To keep the previous behaviour we simply return the file path
// with extension
if (endsWith('.js', filePath)) {
return filePath;
filePath = match;
} else if (!endsWith('.js', filePath)) {
// To keep the previous behaviour we simply return the file path
// with extension
filePath = filePath + '.js';
}

return filePath + '.js';
return normalizeId(filePath);
}

return updatedId;
Expand Down
117 changes: 80 additions & 37 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import test from 'ava';
import { posix as path } from 'path';
import path from 'path';
import { rollup } from 'rollup';
import alias from '../dist/rollup-plugin-alias';
import slash from 'slash';

const DIRNAME = slash(__dirname.replace(/^([A-Z]:)/, ''));
const normalizeId = id => slash(id);

test(t => {
t.is(typeof alias, 'function');
Expand All @@ -29,9 +29,9 @@ test('Simple aliasing', t => {
'./local': 'global',
});

const resolved = result.resolveId('foo', '/src/importer.js');
const resolved2 = result.resolveId('pony', '/src/importer.js');
const resolved3 = result.resolveId('./local', '/src/importer.js');
const resolved = result.resolveId('foo', path.resolve('/src/importer.js'));
const resolved2 = result.resolveId('pony', path.resolve('/src/importer.js'));
const resolved3 = result.resolveId('./local', path.resolve('/src/importer.js'));

t.is(resolved, 'bar');
t.is(resolved2, 'paradise');
Expand All @@ -44,47 +44,64 @@ test('Will not confuse modules with similar names', t => {
'./foo': 'bar',
});

const resolved = result.resolveId('foo2', '/src/importer.js');
const resolved2 = result.resolveId('./fooze/bar', '/src/importer.js');
const resolved3 = result.resolveId('./someFile.foo', '/src/importer.js');
const resolved = result.resolveId('foo2', path.resolve('/src/importer.js'));
const resolved2 = result.resolveId('./fooze/bar', path.resolve('/src/importer.js'));
const resolved3 = result.resolveId('./someFile.foo', path.resolve('/src/importer.js'));

t.is(resolved, null);
t.is(resolved2, null);
t.is(resolved3, null);
});

test('Local aliasing', t => {
test('Local aliasing with POSIX path', t => {
const result = alias({
foo: './bar',
pony: './par/a/di/se',
});

const resolved = result.resolveId('foo', '/src/importer.js');
const resolved2 = result.resolveId('foo/baz', '/src/importer.js');
const resolved3 = result.resolveId('foo/baz.js', '/src/importer.js');
const resolved4 = result.resolveId('pony', '/src/highly/nested/importer.js');
const resolved = result.resolveId('foo', path.resolve('/src/importer.js'));
const resolved2 = result.resolveId('foo/baz', path.resolve('/src/importer.js'));
const resolved3 = result.resolveId('foo/baz.js', path.resolve('/src/importer.js'));
const resolved4 = result.resolveId('pony', path.resolve('/src/highly/nested/importer.js'));

t.is(resolved, '/src/bar.js');
t.is(resolved2, '/src/bar/baz.js');
t.is(resolved3, '/src/bar/baz.js');
t.is(resolved4, '/src/highly/nested/par/a/di/se.js');
t.is(resolved, normalizeId(path.resolve('/src/bar.js')));
t.is(resolved2, normalizeId(path.resolve('/src/bar/baz.js')));
t.is(resolved3, normalizeId(path.resolve('/src/bar/baz.js')));
t.is(resolved4, normalizeId(path.resolve('/src/highly/nested/par/a/di/se.js')));
});

test('Local aliasing with Windows path', t => {
const result = alias({
foo: '.\\bar',
pony: '.\\par\\a\\di\\se',
});

const resolved = result.resolveId('foo', path.resolve('/src/importer.js'));
const resolved2 = result.resolveId('foo/baz', path.resolve('/src/importer.js'));
const resolved3 = result.resolveId('foo/baz.js', path.resolve('/src/importer.js'));
const resolved4 = result.resolveId('pony', path.resolve('/src/highly/nested/importer.js'));

t.is(resolved, normalizeId(path.resolve('/src/bar.js')));
t.is(resolved2, normalizeId(path.resolve('/src/bar/baz.js')));
t.is(resolved3, normalizeId(path.resolve('/src/bar/baz.js')));
t.is(resolved4, normalizeId(path.resolve('/src/highly/nested/par/a/di/se.js')));
});

test('Absolute local aliasing', t => {
const result = alias({
foo: '/bar',
pony: '/par/a/di/se.js',
foo: path.resolve('/bar'),
pony: path.resolve('/par/a/di/se.js'),
});

const resolved = result.resolveId('foo', '/src/importer.js');
const resolved2 = result.resolveId('foo/baz', '/src/importer.js');
const resolved3 = result.resolveId('foo/baz.js', '/src/importer.js');
const resolved4 = result.resolveId('pony', '/src/highly/nested/importer.js');
const resolved = result.resolveId('foo', path.resolve('/src/importer.js'));
const resolved2 = result.resolveId('foo/baz', path.resolve('/src/importer.js'));
const resolved3 = result.resolveId('foo/baz.js', path.resolve('/src/importer.js'));
const resolved4 = result.resolveId('pony', path.resolve('/src/highly/nested/importer.js'));

t.is(resolved, '/bar.js');
t.is(resolved2, '/bar/baz.js');
t.is(resolved3, '/bar/baz.js');
t.is(resolved4, '/par/a/di/se.js');
t.is(resolved, normalizeId(path.resolve('/bar.js')));
t.is(resolved2, normalizeId(path.resolve('/bar/baz.js')));
t.is(resolved3, normalizeId(path.resolve('/bar/baz.js')));
t.is(resolved4, normalizeId(path.resolve('/par/a/di/se.js')));
});

test('Test for the resolve property', t => {
Expand All @@ -93,17 +110,17 @@ test('Test for the resolve property', t => {
resolve: ['.js', '.jsx'],
});

const resolved = result.resolveId('ember', path.resolve(DIRNAME, './files/index.js'));
const resolved = result.resolveId('ember', path.resolve(__dirname, './files/index.js'));

t.is(resolved, path.resolve(DIRNAME, './files/folder/hipster.jsx'));
t.is(resolved, normalizeId(path.resolve(__dirname, './files/folder/hipster.jsx')));
});

test(t => {
const result = alias({
resolve: 'i/am/a/file',
});

const resolved = result.resolveId('resolve', '/src/import.js');
const resolved = result.resolveId('resolve', path.resolve('/src/import.js'));

t.is(resolved, 'i/am/a/file');
});
Expand All @@ -113,9 +130,9 @@ test(t => {
resolve: './i/am/a/local/file',
});

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

t.is(resolved, path.resolve(DIRNAME, './files/i/am/a/local/file.js'));
t.is(resolved, normalizeId(path.resolve(__dirname, './files/i/am/a/local/file.js')));
});

// Tests in Rollup
Expand All @@ -129,11 +146,37 @@ test(t =>
'./numberFolder': './folder',
})],
}).then(stats => {
t.is(stats.modules[0].id.endsWith('/files/nonAliased.js'), true);
t.is(stats.modules[1].id.endsWith('/files/aliasMe.js'), true);
t.is(stats.modules[2].id.endsWith('/files/localAliasMe.js'), true);
t.is(stats.modules[3].id.endsWith('/files/folder/anotherNumber.js'), true);
t.is(stats.modules[4].id.endsWith('/files/index.js'), true);
t.is(stats.modules[0].id, normalizeId(path.resolve('./files/nonAliased.js')));
t.is(stats.modules[1].id, normalizeId(path.resolve('./files/aliasMe.js')));
t.is(stats.modules[2].id, normalizeId(path.resolve('./files/localAliasMe.js')));
t.is(stats.modules[3].id, normalizeId(path.resolve('./files/folder/anotherNumber.js')));
t.is(stats.modules[4].id, normalizeId(path.resolve('./files/index.js')));
t.is(stats.modules.length, 5);
})
);

test('Relative local aliasing in rollup entry', t =>
rollup({
entry: 'src/aliasMe.js',
plugins: [alias({
src: './files',
})],
}).then(() => {
t.fail();
}).catch(() => {
t.pass();
})
);

test('Absolute local aliasing in rollup entry', t =>
rollup({
entry: 'src/aliasMe.js',
plugins: [alias({
src: path.resolve('./files'),
})],
}).then(() => {
t.pass();
}).catch(() => {
t.fail();
})
);