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

Commit c95e4bf

Browse files
dak0rnfrostney
authored andcommitted
Add resolve property (#1)
* Add a few more tests * Move things to the top * Add another helper * Use path.dirname instead of basename & split * Remove comments * Add first test for resolve * Add resolve feature If provided as an array a `resolve` key in the plugin's options is used to resolve existing files on the file system * Add tests for the resolve property * Update readme * Remove unused identity function * Use startsWith utility
1 parent d14c641 commit c95e4bf

File tree

4 files changed

+137
-15
lines changed

4 files changed

+137
-15
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,22 @@ rollup({
2525
});
2626
```
2727

28+
An optional `resolve` array with file extensions can be provided.
29+
If present local aliases beginning with `./` will be resolved to existing files:
30+
31+
```javascript
32+
import { rollup } from 'rollup';
33+
import alias from 'rollup-plugin-alias';
34+
35+
rollup({
36+
entry: './src/index.js',
37+
plugins: [alias({
38+
resolve: ['.jsx', '.js']
39+
foo: './bar', // Will check for ./bar.jsx and ./bar.js
40+
})],
41+
});
42+
```
43+
If not given local aliases will be resolved with a `.js` extension.
44+
2845
## License
2946
MIT, see `LICENSE` for more information

src/index.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,58 @@
11
import path from 'path';
2+
import fs from 'fs';
3+
4+
// Helper functions
5+
const noop = () => null;
6+
const startsWith = (needle, haystack) => ! haystack.indexOf(needle);
7+
const exists = uri => {
8+
try {
9+
return fs.statSync(uri).isFile();
10+
} catch (e) {
11+
return false;
12+
}
13+
};
214

315
export default function alias(options = {}) {
16+
const hasResolve = Array.isArray(options.resolve);
17+
const resolve = hasResolve ? options.resolve : ['.js'];
18+
const aliasKeys = hasResolve ?
19+
Object.keys(options).filter(k => k !== 'resolve') : Object.keys(options);
20+
21+
// No aliases?
22+
if (!aliasKeys.length) {
23+
return {
24+
resolveId: noop,
25+
};
26+
}
27+
428
return {
529
resolveId(importee, importer) {
6-
if (Object.keys(options).length === 0) {
30+
// First match is supposed to be the correct one
31+
const toReplace = aliasKeys.find(key => startsWith(key, importee));
32+
33+
if (!toReplace) {
734
return null;
835
}
936

10-
const aliasKeys = Object.keys(options);
11-
// TODO: We shouldn't have a case of double aliases. But may need to handle that better
12-
const filteredAlias = aliasKeys.filter(value => importee.indexOf(value) === 0)[0];
37+
const entry = options[toReplace];
1338

14-
if (!filteredAlias) {
15-
return null;
16-
}
39+
const updatedId = importee.replace(toReplace, entry);
1740

18-
const entry = options[filteredAlias];
41+
if (startsWith('./', updatedId)) {
42+
const directory = path.dirname(importer);
1943

20-
const updatedId = importee.replace(filteredAlias, entry);
44+
// Resolve file names
45+
const filePath = path.resolve(directory, updatedId);
46+
const match = resolve.map(ext => `${filePath}${ext}`)
47+
.find(exists);
2148

22-
if (updatedId.indexOf('./') === 0) {
23-
const basename = path.basename(importer);
24-
const directory = importer.split(basename)[0];
49+
if (match) {
50+
return match;
51+
}
2552

26-
// TODO: Is there a way not to have the extension being defined explicitly?
27-
return path.resolve(directory, updatedId) + '.js';
53+
// To keep the previous behaviour we simply return the file path
54+
// with extension
55+
return filePath + '.js';
2856
}
2957

3058
return updatedId;

test/files/folder/hipster.jsx

Whitespace-only changes.

test/index.js

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,85 @@
11
import test from 'ava';
2-
2+
import path from 'path';
33
import { rollup } from 'rollup';
44
import alias from '../dist/rollup-plugin-alias';
55

6+
test(t => {
7+
t.is(typeof alias, 'function');
8+
});
9+
10+
test(t => {
11+
const result = alias();
12+
t.is(typeof result, 'object');
13+
t.is(typeof result.resolveId, 'function');
14+
});
15+
16+
test(t => {
17+
const result = alias({});
18+
t.is(typeof result, 'object');
19+
t.is(typeof result.resolveId, 'function');
20+
});
21+
22+
// Simple aliasing
23+
test(t => {
24+
const result = alias({
25+
foo: 'bar',
26+
pony: 'paradise',
27+
});
28+
29+
const resolved = result.resolveId('foo', '/src/importer.js');
30+
const resolved2 = result.resolveId('pony', '/src/importer.js');
31+
32+
t.is(resolved, 'bar');
33+
t.is(resolved2, 'paradise');
34+
});
35+
36+
// Local aliasing
37+
test(t => {
38+
const result = alias({
39+
foo: './bar',
40+
pony: './par/a/di/se',
41+
});
42+
43+
const resolved = result.resolveId('foo', '/src/importer.js');
44+
const resolved2 = result.resolveId('pony', '/src/highly/nested/importer.js');
45+
46+
t.is(resolved, '/src/bar.js');
47+
t.is(resolved2, '/src/highly/nested/par/a/di/se.js');
48+
});
49+
50+
// Test for the resolve property
51+
test(t => {
52+
const result = alias({
53+
ember: './folder/hipster',
54+
resolve: ['.js', '.jsx'],
55+
});
56+
57+
const resolved = result.resolveId('ember', path.resolve(__dirname, './files/index.js'));
58+
59+
t.is(resolved, path.resolve(__dirname, './files/folder/hipster.jsx'));
60+
});
61+
62+
test(t => {
63+
const result = alias({
64+
resolve: 'i/am/a/file',
65+
});
66+
67+
const resolved = result.resolveId('resolve', '/src/import.js');
68+
69+
t.is(resolved, 'i/am/a/file');
70+
});
71+
72+
test(t => {
73+
const result = alias({
74+
resolve: './i/am/a/local/file',
75+
});
76+
77+
const resolved = result.resolveId('resolve', path.resolve(__dirname, './files/index.js'));
78+
79+
t.is(resolved, path.resolve(__dirname, './files/i/am/a/local/file.js'));
80+
});
81+
82+
// Tests in Rollup
683
test(t =>
784
rollup({
885
entry: './files/index.js',

0 commit comments

Comments
 (0)