UNPKG

2.02 kBPlain TextView Raw
1import * as tippex from 'tippex';
2
3// Hack around TypeScript's broken handling of `export class` with
4// ES6 modules and ES5 script target.
5//
6// It works because TypeScript transforms
7//
8// export class A {}
9//
10// into something like CommonJS, when we wanted ES6 modules.
11//
12// var A = (function () {
13// function A() {
14// }
15// return A;
16// }());
17// exports.A = A;
18//
19// But
20//
21// class A {}
22// export { A };
23//
24// is transformed into this beauty.
25//
26// var A = (function () {
27// function A() {
28// }
29// return A;
30// }());
31// export { A };
32//
33// The solution is to replace the previous export syntax with the latter.
34export default function fix ( code: string, id: string ): string {
35
36 // Erase comments, strings etc. to avoid erroneous matches for the Regex.
37 const cleanCode = getErasedCode( code, id );
38
39 const re = /export\s+(default\s+)?((?:abstract\s+)?class)(?:\s+(\w+))?/g;
40 let match: RegExpExecArray;
41
42 while ( match = re.exec( cleanCode ) ) {
43 // To keep source maps intact, replace non-whitespace characters with spaces.
44 code = erase( code, match.index, match[ 0 ].indexOf( match[ 2 ] ) );
45
46 let name = match[ 3 ];
47
48 if ( match[ 1 ] ) { // it is a default export
49
50 // TODO: support this too
51 if ( !name ) throw new Error( `TypeScript Plugin: cannot export an un-named class (module ${ id })` );
52
53 // Export the name ` as default`.
54 name += ' as default';
55 }
56
57 // To keep source maps intact, append the injected exports last.
58 code += `\nexport { ${ name } };`
59 }
60
61 return code;
62}
63
64function getErasedCode ( code: string, id: string ): string {
65 try {
66 return tippex.erase( code );
67 } catch (e) {
68 throw new Error( `rollup-plugin-typescript: ${ e.message }; when processing: '${ id }'` );
69 }
70}
71
72function erase ( code: string, start: number, length: number ): string {
73 const end = start + length;
74
75 return code.slice( 0, start ) +
76 code.slice( start, end ).replace( /[^\s]/g, ' ' ) +
77 code.slice( end );
78}