Skip to content

Commit 6cd15b9

Browse files
authored
feat(pluginutils): normalizePath (#550)
* fix(pluginutils): normalize pattern sep * fix: missing quotes * doc: normalizePath * feat: normalizePath
1 parent 7941389 commit 6cd15b9

File tree

7 files changed

+74
-21
lines changed

7 files changed

+74
-21
lines changed

packages/pluginutils/README.md

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ export default function myPlugin(options = {}) {
5050
return {
5151
resolveId(code, id) {
5252
// only adds an extension if there isn't one already
53-
id = addExtension(id); // `foo` -> `foo.js`, `foo.js -> foo.js`
54-
id = addExtension(id, '.myext'); // `foo` -> `foo.myext`, `foo.js -> `foo.js`
55-
}
53+
id = addExtension(id); // `foo` -> `foo.js`, `foo.js` -> `foo.js`
54+
id = addExtension(id, '.myext'); // `foo` -> `foo.myext`, `foo.js` -> `foo.js`
55+
},
5656
};
5757
}
5858
```
@@ -88,9 +88,9 @@ export default function myPlugin(options = {}) {
8888
},
8989
leave(node) {
9090
if (node.scope) scope = scope.parent;
91-
}
91+
},
9292
});
93-
}
93+
},
9494
};
9595
}
9696
```
@@ -126,15 +126,15 @@ import { createFilter } from '@rollup/pluginutils';
126126
export default function myPlugin(options = {}) {
127127
// assume that the myPlugin accepts options of `options.include` and `options.exclude`
128128
var filter = createFilter(options.include, options.exclude, {
129-
resolve: '/my/base/dir'
129+
resolve: '/my/base/dir',
130130
});
131131

132132
return {
133133
transform(code, id) {
134134
if (!filter(id)) return;
135135

136136
// proceed with the transformation...
137-
}
137+
},
138138
};
139139
}
140140
```
@@ -160,14 +160,14 @@ import { dataToEsm } from '@rollup/pluginutils';
160160
const esModuleSource = dataToEsm(
161161
{
162162
custom: 'data',
163-
to: ['treeshake']
163+
to: ['treeshake'],
164164
},
165165
{
166166
compact: false,
167167
indent: '\t',
168168
preferConst: false,
169169
objectShorthand: false,
170-
namedExports: true
170+
namedExports: true,
171171
}
172172
);
173173
/*
@@ -207,11 +207,11 @@ export default function myPlugin(options = {}) {
207207
if (node.type === 'VariableDeclarator') {
208208
const declaredNames = extractAssignedNames(node.id);
209209
// do something with the declared names
210-
// e.g. for `const {x, y: z} = ... => declaredNames = ['x', 'z']
210+
// e.g. for `const {x, y: z} = ...` => declaredNames = ['x', 'z']
211211
}
212-
}
212+
},
213213
});
214-
}
214+
},
215215
};
216216
}
217217
```
@@ -232,6 +232,22 @@ makeLegalIdentifier('foo-bar'); // 'foo_bar'
232232
makeLegalIdentifier('typeof'); // '_typeof'
233233
```
234234

235+
### normalizePath
236+
237+
Converts path separators to forward slash.
238+
239+
Parameters: `(filename: String)`<br>
240+
Returns: `String`
241+
242+
#### Usage
243+
244+
```js
245+
import { normalizePath } from '@rollup/pluginutils';
246+
247+
normalizePath('foo\\bar'); // 'foo/bar'
248+
normalizePath('foo/bar'); // 'foo/bar'
249+
```
250+
235251
## Meta
236252

237253
[CONTRIBUTING](/.github/CONTRIBUTING.md)

packages/pluginutils/src/createFilter.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
import { resolve, sep, posix, isAbsolute } from 'path';
1+
import { resolve, posix, isAbsolute } from 'path';
22

33
import pm from 'picomatch';
44

55
import { CreateFilter } from '../types';
66

77
import ensureArray from './utils/ensureArray';
8+
import normalizePath from './normalizePath';
89

910
function getMatcherString(id: string, resolutionBase: string | false | null | undefined) {
1011
if (resolutionBase === false || isAbsolute(id) || id.startsWith('*')) {
1112
return id;
1213
}
1314

1415
// resolve('') is valid and will default to process.cwd()
15-
const basePath = resolve(resolutionBase || '')
16-
.split(sep)
17-
.join('/')
16+
const basePath = normalizePath(resolve(resolutionBase || ''))
1817
// escape all possible (posix + win) path characters that might interfere with regex
1918
.replace(/[-^$*+?.()|[\]{}]/g, '\\$&');
2019
// Note that we use posix.join because:
@@ -48,7 +47,7 @@ const createFilter: CreateFilter = function createFilter(include?, exclude?, opt
4847
if (typeof id !== 'string') return false;
4948
if (/\0/.test(id)) return false;
5049

51-
const pathId = id.split(sep).join('/');
50+
const pathId = normalizePath(id);
5251

5352
for (let i = 0; i < excludeMatchers.length; ++i) {
5453
const matcher = excludeMatchers[i];

packages/pluginutils/src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import createFilter from './createFilter';
44
import dataToEsm from './dataToEsm';
55
import extractAssignedNames from './extractAssignedNames';
66
import makeLegalIdentifier from './makeLegalIdentifier';
7+
import normalizePath from './normalizePath';
78

89
export {
910
addExtension,
1011
attachScopes,
1112
createFilter,
1213
dataToEsm,
1314
extractAssignedNames,
14-
makeLegalIdentifier
15+
makeLegalIdentifier,
16+
normalizePath
1517
};
1618

1719
// TODO: remove this in next major
@@ -21,5 +23,6 @@ export default {
2123
createFilter,
2224
dataToEsm,
2325
extractAssignedNames,
24-
makeLegalIdentifier
26+
makeLegalIdentifier,
27+
normalizePath
2528
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { win32, posix } from 'path';
2+
3+
import { NormalizePath } from '../types';
4+
5+
const normalizePath: NormalizePath = function(filename: string) {
6+
return filename.split(win32.sep).join(posix.sep);
7+
};
8+
9+
export { normalizePath as default };

packages/pluginutils/test/createFilter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { resolve } from 'path';
1+
import { resolve as rawResolve } from 'path';
22

33
import test from 'ava';
44

5-
import { createFilter } from '../';
5+
import { createFilter, normalizePath } from '../';
6+
7+
const resolve = (...parts: string[]) => normalizePath(rawResolve(...parts));
68

79
test.beforeEach(() => process.chdir(__dirname));
810

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import test from 'ava';
2+
3+
import { normalizePath } from '../';
4+
5+
test('replaces \\ with /', (t) => {
6+
t.is(normalizePath('foo\\bar'), 'foo/bar');
7+
t.is(normalizePath('foo\\bar\\baz'), 'foo/bar/baz');
8+
});
9+
10+
test('ignores forward slash', (t) => {
11+
t.is(normalizePath('foo/bar'), 'foo/bar');
12+
t.is(normalizePath('foo/bar\\baz'), 'foo/bar/baz');
13+
});
14+
15+
test('handles empty string', (t) => {
16+
t.is(normalizePath(''), '');
17+
});

packages/pluginutils/types/index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,17 @@ export function extractAssignedNames(param: BaseNode): string[];
6868
*/
6969
export function makeLegalIdentifier(str: string): string;
7070

71+
/**
72+
* Converts path separators to forward slash.
73+
*/
74+
export function normalizePath(filename: string): string;
75+
7176
export type AddExtension = typeof addExtension;
7277
export type AttachScopes = typeof attachScopes;
7378
export type CreateFilter = typeof createFilter;
7479
export type ExtractAssignedNames = typeof extractAssignedNames;
7580
export type MakeLegalIdentifier = typeof makeLegalIdentifier;
81+
export type NormalizePath = typeof normalizePath;
7682
export type DataToEsm = typeof dataToEsm;
7783

7884
declare const defaultExport: {
@@ -82,5 +88,6 @@ declare const defaultExport: {
8288
dataToEsm: DataToEsm;
8389
extractAssignedNames: ExtractAssignedNames;
8490
makeLegalIdentifier: MakeLegalIdentifier;
91+
normalizePath: NormalizePath;
8592
};
8693
export default defaultExport;

0 commit comments

Comments
 (0)