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

Commit a791ed6

Browse files
thiscantbeseriouslukastaegert
authored andcommitted
Add RegExp support and strict order of entries (+unit-tests) (#53)
* Add RegExp support and strict order of entries (+unit-tests) * Updated README.md to reflect change in options * Updated README.me to reflect changes to options * Updated README.me to reflect changes to options * Switched to instanceof instead of isRegEx option in entries to keep configuration easier * Fixes after Code-Review * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md
1 parent 841cd79 commit a791ed6

File tree

3 files changed

+96
-59
lines changed

3 files changed

+96
-59
lines changed

README.md

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,36 +27,31 @@ For Webpack users: This is a plugin to mimic the `resolve.alias` functionality i
2727
```
2828
$ npm install rollup-plugin-alias
2929
```
30-
30+
#
3131
## Usage
3232
```javascript
3333
// rollup.config.js
3434
import alias from 'rollup-plugin-alias';
3535

3636
export default {
3737
input: './src/index.js',
38-
plugins: [alias({
39-
somelibrary: './mylocallibrary'
40-
})],
38+
plugins: [
39+
alias({
40+
resolve: ['.jsx', '.js'], //optional, by default this will just look for .js files or folders
41+
entries:[
42+
{find:'something', replacement: '../../../something'}, //the initial example
43+
{find:'somelibrary-1.0.0', replacement: './mylocallibrary-1.5.0'}, //remap a library with a specific version
44+
{find:/^i18n\!(.*)/, replacement: '$1.js'}, //remove something in front of the import and append an extension (e.g. loaders, for files that were previously transpiled via the AMD module, to properly handle them in rollup as internals now)
45+
//for whatever reason, replace all .js extensions with .wasm
46+
{find:/^(.*)\.js$/, replacement: '$1.wasm'}
47+
]
48+
})
49+
],
4150
};
4251
```
52+
The order of the entries is important, in that the first rules are applied first.
4353

44-
An optional `resolve` array with file extensions can be provided.
45-
If present local aliases beginning with `./` will be resolved to existing files:
46-
47-
```javascript
48-
// rollup.config.js
49-
import alias from 'rollup-plugin-alias';
50-
51-
export default {
52-
input: './src/index.js',
53-
plugins: [alias({
54-
resolve: ['.jsx', '.js'],
55-
foo: './bar' // Will check for ./bar.jsx and ./bar.js
56-
})],
57-
};
58-
```
59-
If not given local aliases will be resolved with a `.js` extension.
54+
You can use either simple Strings or Regular Expressions to search in a more distinct and complex manner (e.g. to do partial replacements via subpattern-matching, see aboves example).
6055

6156
## License
6257
MIT, see `LICENSE` for more information

src/index.js

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ const IS_WINDOWS = platform() === 'win32';
99

1010
// Helper functions
1111
const noop = () => null;
12-
const matches = (key, importee) => {
13-
if (importee.length < key.length) {
12+
const matches = (pattern, importee) => {
13+
if (pattern instanceof RegExp) {
14+
return pattern.test(importee);
15+
}
16+
if (importee.length < pattern.length) {
1417
return false;
1518
}
16-
if (importee === key) {
19+
if (importee === pattern) {
1720
return true;
1821
}
19-
const importeeStartsWithKey = (importee.indexOf(key) === 0);
20-
const importeeHasSlashAfterKey = (importee.substring(key.length)[0] === '/');
22+
const importeeStartsWithKey = (importee.indexOf(pattern) === 0);
23+
const importeeHasSlashAfterKey = (importee.substring(pattern.length)[0] === '/');
2124
return importeeStartsWithKey && importeeHasSlashAfterKey;
2225
};
2326
const endsWith = (needle, haystack) => haystack.slice(-needle.length) === needle;
@@ -34,18 +37,15 @@ const normalizeId = (id) => {
3437
if ((IS_WINDOWS && typeof id === 'string') || VOLUME.test(id)) {
3538
return slash(id.replace(VOLUME, ''));
3639
}
37-
3840
return id;
3941
};
4042

4143
export default function alias(options = {}) {
42-
const hasResolve = Array.isArray(options.resolve);
43-
const resolve = hasResolve ? options.resolve : ['.js'];
44-
const aliasKeys = hasResolve
45-
? Object.keys(options).filter(k => k !== 'resolve') : Object.keys(options);
44+
const resolve = Array.isArray(options.resolve) ? options.resolve : ['.js'];
45+
const entries = options.entries?options.entries:[];
4646

4747
// No aliases?
48-
if (!aliasKeys.length) {
48+
if (!entries || entries.length === 0) {
4949
return {
5050
resolveId: noop,
5151
};
@@ -57,15 +57,12 @@ export default function alias(options = {}) {
5757
const importerId = normalizeId(importer);
5858

5959
// First match is supposed to be the correct one
60-
const toReplace = aliasKeys.find(key => matches(key, importeeId));
61-
62-
if (!toReplace || !importerId) {
60+
const matchedEntry = entries.find(entry => matches(entry.find, importeeId));
61+
if (!matchedEntry || !importerId) {
6362
return null;
6463
}
6564

66-
const entry = options[toReplace];
67-
68-
let updatedId = normalizeId(importeeId.replace(toReplace, entry));
65+
let updatedId = normalizeId(importeeId.replace(matchedEntry.find, matchedEntry.replacement));
6966

7067
if (isFilePath(updatedId)) {
7168
const directory = posix.dirname(importerId);
@@ -89,10 +86,9 @@ export default function alias(options = {}) {
8986
// if alias is windows absoulate path return resolved path or
9087
// rollup on windows will throw:
9188
// [TypeError: Cannot read property 'specifier' of undefined]
92-
if (VOLUME.test(entry)) {
89+
if (VOLUME.test(matchedEntry.replacement)) {
9390
return path.resolve(updatedId);
9491
}
95-
9692
return updatedId;
9793
},
9894
};

test/index.js

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ test('defaults', (t) => {
2525

2626
test('Simple aliasing', (t) => {
2727
const result = alias({
28-
foo: 'bar',
29-
pony: 'paradise',
30-
'./local': 'global',
28+
entries: [
29+
{find:'foo', replacement:'bar'},
30+
{find:'pony', replacement:'paradise'},
31+
{find:'./local',replacement:'global'}
32+
]
3133
});
3234

3335
const resolved = result.resolveId('foo', '/src/importer.js');
@@ -39,10 +41,34 @@ test('Simple aliasing', (t) => {
3941
t.is(resolved3, 'global');
4042
});
4143

44+
test('RegExp aliasing', (t) => {
45+
const result = alias({
46+
entries: [
47+
{find:/f(o+)bar/, replacement:'f$1bar2019'},
48+
{find:new RegExp('.*pony.*'), replacement:'i/am/a/barbie/girl'},
49+
{find:/^test\/$/, replacement:'this/is/strict'}
50+
]
51+
});
52+
53+
const resolved = result.resolveId('fooooooooobar', '/src/importer.js');
54+
const resolved2 = result.resolveId('im/a/little/pony/yes', '/src/importer.js');
55+
const resolved3 = result.resolveId('./test', '/src/importer.js');
56+
const resolved4 = result.resolveId('test', '/src/importer.js');
57+
const resolved5 = result.resolveId('test/', '/src/importer.js');
58+
59+
t.is(resolved, 'fooooooooobar2019');
60+
t.is(resolved2, 'i/am/a/barbie/girl');
61+
t.is(resolved3, null);
62+
t.is(resolved4, null);
63+
t.is(resolved5, 'this/is/strict');
64+
});
65+
4266
test('Will not confuse modules with similar names', (t) => {
4367
const result = alias({
44-
foo: 'bar',
45-
'./foo': 'bar',
68+
entries:[
69+
{find:'foo', replacement:'bar'},
70+
{find:'./foo', replacement:'bar'},
71+
]
4672
});
4773

4874
const resolved = result.resolveId('foo2', '/src/importer.js');
@@ -56,8 +82,10 @@ test('Will not confuse modules with similar names', (t) => {
5682

5783
test('Local aliasing', (t) => {
5884
const result = alias({
59-
foo: './bar',
60-
pony: './par/a/di/se',
85+
entries:[
86+
{find:'foo', replacement:'./bar'},
87+
{find:'pony', replacement:'./par/a/di/se'}
88+
]
6189
});
6290

6391
const resolved = result.resolveId('foo', '/src/importer.js');
@@ -73,8 +101,10 @@ test('Local aliasing', (t) => {
73101

74102
test('Absolute local aliasing', (t) => {
75103
const result = alias({
76-
foo: '/bar',
77-
pony: '/par/a/di/se.js',
104+
entries:[
105+
{find:'foo', replacement:'/bar'},
106+
{find:'pony', replacement:'/par/a/di/se.js'}
107+
]
78108
});
79109

80110
const resolved = result.resolveId('foo', '/src/importer.js');
@@ -90,7 +120,9 @@ test('Absolute local aliasing', (t) => {
90120

91121
test('Leaves entry file untouched if matches alias', (t) => {
92122
const result = alias({
93-
abacaxi: './abacaxi',
123+
entries:[
124+
{find:'abacaxi', replacement:'./abacaxi'}
125+
]
94126
});
95127

96128
const resolved = result.resolveId('abacaxi/entry.js', undefined);
@@ -100,8 +132,10 @@ test('Leaves entry file untouched if matches alias', (t) => {
100132

101133
test('Test for the resolve property', (t) => {
102134
const result = alias({
103-
ember: './folder/hipster',
104135
resolve: ['.js', '.jsx'],
136+
entries:[
137+
{find:'ember', replacement: './folder/hipster'},
138+
]
105139
});
106140

107141
const resolved = result.resolveId('ember', posix.resolve(DIRNAME, './files/index.js'));
@@ -111,7 +145,9 @@ test('Test for the resolve property', (t) => {
111145

112146
test('i/am/a/file', (t) => {
113147
const result = alias({
114-
resolve: 'i/am/a/file',
148+
entries:[
149+
{find:'resolve', replacement: 'i/am/a/file'}
150+
]
115151
});
116152

117153
const resolved = result.resolveId('resolve', '/src/import.js');
@@ -121,7 +157,9 @@ test('i/am/a/file', (t) => {
121157

122158
test('i/am/a/local/file', (t) => {
123159
const result = alias({
124-
resolve: './i/am/a/local/file',
160+
entries:[
161+
{find:'resolve', replacement: './i/am/a/local/file'}
162+
]
125163
});
126164

127165
const resolved = result.resolveId('resolve', posix.resolve(DIRNAME, './files/index.js'));
@@ -132,7 +170,9 @@ test('i/am/a/local/file', (t) => {
132170
test('Platform path.resolve(\'file-without-extension\') aliasing', (t) => {
133171
// this what used in React and Vue
134172
const result = alias({
135-
test: path.resolve('./test/files/aliasMe'),
173+
entries:[
174+
{find:'test', replacement:path.resolve('./test/files/aliasMe')}
175+
]
136176
});
137177

138178
const resolved = result.resolveId('test', posix.resolve(DIRNAME, './files/index.js'));
@@ -142,7 +182,9 @@ test('Platform path.resolve(\'file-without-extension\') aliasing', (t) => {
142182

143183
test('Windows absolute path aliasing', (t) => {
144184
const result = alias({
145-
resolve: 'E:\\react\\node_modules\\fbjs\\lib\\warning',
185+
entries:[
186+
{find:'resolve', replacement:'E:\\react\\node_modules\\fbjs\\lib\\warning'}
187+
]
146188
});
147189

148190
const resolved = result.resolveId('resolve', posix.resolve(DIRNAME, './files/index.js'));
@@ -155,7 +197,9 @@ test('Windows absolute path aliasing', (t) => {
155197

156198
test('Platform path.resolve(\'file-with.ext\') aliasing', (t) => {
157199
const result = alias({
158-
test: path.resolve('./test/files/folder/hipster.jsx'),
200+
entries:[
201+
{find:'test', replacement:path.resolve('./test/files/folder/hipster.jsx')},
202+
],
159203
resolve: ['.js', '.jsx'],
160204
});
161205

@@ -181,10 +225,12 @@ const getModuleIdsFromBundle = (bundle) => {
181225
test('Works in rollup', t => rollup({
182226
input: './test/files/index.js',
183227
plugins: [alias({
184-
fancyNumber: './aliasMe',
185-
'./anotherFancyNumber': './localAliasMe',
186-
numberFolder: './folder',
187-
'./numberFolder': './folder',
228+
entries:[
229+
{find:'fancyNumber', replacement:'./aliasMe'},
230+
{find:'./anotherFancyNumber', replacement: './localAliasMe'},
231+
{find:'numberFolder', replacement:'./folder'},
232+
{find:'./numberFolder', replacement: './folder'}
233+
]
188234
})],
189235
}).then(getModuleIdsFromBundle)
190236
.then((moduleIds) => {

0 commit comments

Comments
 (0)