1 | import { parse } from 'acorn';
|
2 | import MagicString from 'magic-string';
|
3 | import Statement from './Statement';
|
4 | import walk from './ast/walk';
|
5 | import { blank, keys } from './utils/object';
|
6 | import { basename, extname } from './utils/path';
|
7 | import getLocation from './utils/getLocation';
|
8 | import makeLegalIdentifier from './utils/makeLegalIdentifier';
|
9 | import SOURCEMAPPING_URL from './utils/sourceMappingURL';
|
10 |
|
11 | function deconflict ( name, names ) {
|
12 | while ( name in names ) {
|
13 | name = `_${name}`;
|
14 | }
|
15 |
|
16 | return name;
|
17 | }
|
18 |
|
19 | function isEmptyExportedVarDeclaration ( node, allBundleExports, moduleReplacements ) {
|
20 | if ( node.type !== 'VariableDeclaration' || node.declarations[0].init ) return false;
|
21 |
|
22 | const name = node.declarations[0].id.name;
|
23 | const canonicalName = moduleReplacements[ name ] || name;
|
24 |
|
25 | return canonicalName in allBundleExports;
|
26 | }
|
27 |
|
28 | export default class Module {
|
29 | constructor ({ id, source, ast, bundle }) {
|
30 | this.source = source;
|
31 |
|
32 | this.bundle = bundle;
|
33 | this.id = id;
|
34 |
|
35 |
|
36 |
|
37 | this.magicString = new MagicString( source, {
|
38 | filename: id
|
39 | });
|
40 |
|
41 |
|
42 | const pattern = new RegExp( `\\/\\/#\\s+${SOURCEMAPPING_URL}=.+\\n?`, 'g' );
|
43 | let match;
|
44 | while ( match = pattern.exec( source ) ) {
|
45 | this.magicString.remove( match.index, match.index + match[0].length );
|
46 | }
|
47 |
|
48 | this.suggestedNames = blank();
|
49 | this.comments = [];
|
50 |
|
51 | this.statements = this.parse( ast );
|
52 |
|
53 |
|
54 | this.dependencies = [];
|
55 | this.resolvedIds = blank();
|
56 | this.boundImportSpecifiers = false;
|
57 |
|
58 |
|
59 | this.imports = blank();
|
60 | this.exports = blank();
|
61 | this.reexports = blank();
|
62 | this.exportDelegates = blank();
|
63 |
|
64 | this.exportAlls = [];
|
65 |
|
66 | this.replacements = blank();
|
67 |
|
68 | this.reassignments = [];
|
69 |
|
70 | this.marked = blank();
|
71 | this.definitions = blank();
|
72 | this.definitionPromises = blank();
|
73 | this.modifications = blank();
|
74 |
|
75 | this.analyse();
|
76 | }
|
77 |
|
78 | addExport ( statement ) {
|
79 | const node = statement.node;
|
80 | const source = node.source && node.source.value;
|
81 |
|
82 |
|
83 | if ( source ) {
|
84 | if ( !~this.dependencies.indexOf( source ) ) this.dependencies.push( source );
|
85 |
|
86 | if ( node.type === 'ExportAllDeclaration' ) {
|
87 |
|
88 |
|
89 | this.exportAlls.push({
|
90 | statement,
|
91 | source
|
92 | });
|
93 | }
|
94 |
|
95 | else {
|
96 | node.specifiers.forEach( specifier => {
|
97 | this.reexports[ specifier.exported.name ] = {
|
98 | source,
|
99 | localName: specifier.local.name,
|
100 | module: null
|
101 | };
|
102 | });
|
103 | }
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | else if ( node.type === 'ExportDefaultDeclaration' ) {
|
110 | const isDeclaration = /Declaration$/.test( node.declaration.type );
|
111 | const isAnonymous = /(?:Class|Function)Expression$/.test( node.declaration.type );
|
112 |
|
113 | const identifier = isDeclaration ?
|
114 | node.declaration.id.name :
|
115 | node.declaration.type === 'Identifier' ?
|
116 | node.declaration.name :
|
117 | null;
|
118 |
|
119 | this.exports.default = {
|
120 | statement,
|
121 | name: 'default',
|
122 | localName: identifier || 'default',
|
123 | identifier,
|
124 | isDeclaration,
|
125 | isAnonymous,
|
126 | isModified: false
|
127 | };
|
128 | }
|
129 |
|
130 |
|
131 |
|
132 |
|
133 | else if ( node.type === 'ExportNamedDeclaration' ) {
|
134 | if ( node.specifiers.length ) {
|
135 |
|
136 | node.specifiers.forEach( specifier => {
|
137 | const localName = specifier.local.name;
|
138 | const exportedName = specifier.exported.name;
|
139 |
|
140 | this.exports[ exportedName ] = {
|
141 | statement,
|
142 | localName,
|
143 | exportedName
|
144 | };
|
145 | });
|
146 | }
|
147 |
|
148 | else {
|
149 | let declaration = node.declaration;
|
150 |
|
151 | let name;
|
152 |
|
153 | if ( declaration.type === 'VariableDeclaration' ) {
|
154 |
|
155 | name = declaration.declarations[0].id.name;
|
156 | } else {
|
157 |
|
158 | name = declaration.id.name;
|
159 | }
|
160 |
|
161 | this.exports[ name ] = {
|
162 | statement,
|
163 | localName: name,
|
164 | expression: declaration
|
165 | };
|
166 | }
|
167 | }
|
168 | }
|
169 |
|
170 | addImport ( statement ) {
|
171 | const node = statement.node;
|
172 | const source = node.source.value;
|
173 |
|
174 | if ( !~this.dependencies.indexOf( source ) ) this.dependencies.push( source );
|
175 |
|
176 | node.specifiers.forEach( specifier => {
|
177 | const isDefault = specifier.type === 'ImportDefaultSpecifier';
|
178 | const isNamespace = specifier.type === 'ImportNamespaceSpecifier';
|
179 |
|
180 | const localName = specifier.local.name;
|
181 | const name = isDefault ? 'default' : isNamespace ? '*' : specifier.imported.name;
|
182 |
|
183 | if ( this.imports[ localName ] ) {
|
184 | const err = new Error( `Duplicated import '${localName}'` );
|
185 | err.file = this.id;
|
186 | err.loc = getLocation( this.source, specifier.start );
|
187 | throw err;
|
188 | }
|
189 |
|
190 | this.imports[ localName ] = {
|
191 | source,
|
192 | name,
|
193 | localName
|
194 | };
|
195 | });
|
196 | }
|
197 |
|
198 | analyse () {
|
199 |
|
200 | this.statements.forEach( statement => {
|
201 | if ( statement.isImportDeclaration ) this.addImport( statement );
|
202 | else if ( statement.isExportDeclaration ) this.addExport( statement );
|
203 |
|
204 | statement.analyse();
|
205 |
|
206 |
|
207 | keys( statement.defines ).forEach( name => {
|
208 | this.definitions[ name ] = statement;
|
209 | });
|
210 |
|
211 | keys( statement.modifies ).forEach( name => {
|
212 | ( this.modifications[ name ] || ( this.modifications[ name ] = [] ) ).push( statement );
|
213 | });
|
214 | });
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 | let reassigned = blank();
|
222 | this.statements.forEach( statement => {
|
223 | keys( statement.reassigns ).forEach( name => {
|
224 | reassigned[ name ] = true;
|
225 | });
|
226 | });
|
227 |
|
228 |
|
229 |
|
230 | this.statements.forEach( statement => {
|
231 | if ( statement.isReexportDeclaration ) return;
|
232 |
|
233 |
|
234 | statement.scope.varDeclarations.forEach( name => {
|
235 | if ( reassigned[ name ] && !~this.reassignments.indexOf( name ) ) {
|
236 | this.reassignments.push( name );
|
237 | }
|
238 | });
|
239 |
|
240 | keys( statement.dependsOn ).forEach( name => {
|
241 | if ( !this.definitions[ name ] && !this.imports[ name ] ) {
|
242 | this.bundle.assumedGlobals[ name ] = true;
|
243 | }
|
244 | });
|
245 | });
|
246 | }
|
247 |
|
248 | basename () {
|
249 | return makeLegalIdentifier( basename( this.id ).slice( 0, -extname( this.id ).length ) );
|
250 | }
|
251 |
|
252 | bindImportSpecifiers () {
|
253 | if ( this.boundImportSpecifiers ) return;
|
254 | this.boundImportSpecifiers = true;
|
255 |
|
256 | [ this.imports, this.reexports ].forEach( specifiers => {
|
257 | keys( specifiers ).forEach( name => {
|
258 | const specifier = specifiers[ name ];
|
259 |
|
260 | if ( specifier.module ) return;
|
261 |
|
262 | const id = this.resolvedIds[ specifier.source ];
|
263 | specifier.module = this.bundle.moduleById[ id ];
|
264 | });
|
265 | });
|
266 |
|
267 | this.exportAlls.forEach( delegate => {
|
268 | const id = this.resolvedIds[ delegate.source ];
|
269 | delegate.module = this.bundle.moduleById[ id ];
|
270 | });
|
271 |
|
272 | this.dependencies.forEach( source => {
|
273 | const id = this.resolvedIds[ source ];
|
274 | const module = this.bundle.moduleById[ id ];
|
275 |
|
276 | if ( !module.isExternal ) module.bindImportSpecifiers();
|
277 | });
|
278 | }
|
279 |
|
280 | consolidateDependencies () {
|
281 | let strongDependencies = blank();
|
282 |
|
283 | function addDependency ( dependencies, declaration ) {
|
284 | if ( declaration && declaration.module && !declaration.module.isExternal ) {
|
285 | dependencies[ declaration.module.id ] = declaration.module;
|
286 | return true;
|
287 | }
|
288 | }
|
289 |
|
290 | this.statements.forEach( statement => {
|
291 | if ( statement.isImportDeclaration && !statement.node.specifiers.length ) {
|
292 |
|
293 | const id = this.resolvedIds[ statement.node.source.value ];
|
294 | const module = this.bundle.moduleById[ id ];
|
295 |
|
296 | if ( !module.isExternal ) strongDependencies[ module.id ] = module;
|
297 | }
|
298 |
|
299 | else if ( statement.isReexportDeclaration ) {
|
300 | if ( statement.node.specifiers ) {
|
301 | statement.node.specifiers.forEach( specifier => {
|
302 | let reexport;
|
303 |
|
304 | let module = this;
|
305 | let name = specifier.exported.name;
|
306 | while ( !module.isExternal && module.reexports[ name ] && module.reexports[ name ].isUsed ) {
|
307 | reexport = module.reexports[ name ];
|
308 | module = reexport.module;
|
309 | name = reexport.localName;
|
310 | }
|
311 |
|
312 | addDependency( strongDependencies, reexport );
|
313 | });
|
314 | }
|
315 | }
|
316 |
|
317 | else {
|
318 | keys( statement.stronglyDependsOn ).forEach( name => {
|
319 | if ( statement.defines[ name ] ) return;
|
320 |
|
321 | addDependency( strongDependencies, this.exportDelegates[ name ] ) ||
|
322 | addDependency( strongDependencies, this.imports[ name ] );
|
323 | });
|
324 | }
|
325 | });
|
326 |
|
327 | let weakDependencies = blank();
|
328 |
|
329 | this.statements.forEach( statement => {
|
330 | keys( statement.dependsOn ).forEach( name => {
|
331 | if ( statement.defines[ name ] ) return;
|
332 |
|
333 | addDependency( weakDependencies, this.exportDelegates[ name ] ) ||
|
334 | addDependency( weakDependencies, this.imports[ name ] );
|
335 | });
|
336 | });
|
337 |
|
338 |
|
339 | if ( this.exportAlls.length ) {
|
340 | this.exportAlls.forEach( ({ source }) => {
|
341 | const resolved = this.resolvedIds[ source ];
|
342 | const otherModule = this.bundle.moduleById[ resolved ];
|
343 |
|
344 | strongDependencies[ otherModule.id ] = otherModule;
|
345 | });
|
346 | }
|
347 |
|
348 | return { strongDependencies, weakDependencies };
|
349 | }
|
350 |
|
351 | defaultName () {
|
352 | const defaultExport = this.exports.default;
|
353 |
|
354 | if ( !defaultExport ) return null;
|
355 |
|
356 | const name = defaultExport.identifier && !defaultExport.isModified ?
|
357 | defaultExport.identifier :
|
358 | this.replacements.default;
|
359 |
|
360 | return this.replacements[ name ] || name;
|
361 | }
|
362 |
|
363 | findDefiningStatement ( name ) {
|
364 | if ( this.definitions[ name ] ) return this.definitions[ name ];
|
365 |
|
366 |
|
367 |
|
368 | const importDeclaration = this.imports[ name ];
|
369 | if ( !importDeclaration ) return null;
|
370 |
|
371 | return importDeclaration.module.findDefiningStatement( name );
|
372 | }
|
373 |
|
374 | getExports () {
|
375 | let exports = blank();
|
376 |
|
377 | keys( this.exports ).forEach( name => {
|
378 | exports[ name ] = true;
|
379 | });
|
380 |
|
381 | keys( this.reexports ).forEach( name => {
|
382 | exports[ name ] = true;
|
383 | });
|
384 |
|
385 | this.exportAlls.forEach( ({ module }) => {
|
386 | module.getExports().forEach( name => {
|
387 | if ( name !== 'default' ) exports[ name ] = true;
|
388 | });
|
389 | });
|
390 |
|
391 | return keys( exports );
|
392 | }
|
393 |
|
394 | mark ( name ) {
|
395 |
|
396 | if ( this.marked[ name ] ) return;
|
397 | this.marked[ name ] = true;
|
398 |
|
399 |
|
400 | if ( this.imports[ name ] ) {
|
401 | const importDeclaration = this.imports[ name ];
|
402 | importDeclaration.isUsed = true;
|
403 |
|
404 | const module = importDeclaration.module;
|
405 |
|
406 |
|
407 | if ( importDeclaration.name === 'default' ) {
|
408 |
|
409 | const localName = importDeclaration.localName;
|
410 | let suggestion = this.suggestedNames[ localName ] || localName;
|
411 |
|
412 |
|
413 | while ( !module.isExternal && module.imports[ suggestion ] ) {
|
414 | suggestion = `_${suggestion}`;
|
415 | }
|
416 |
|
417 | module.suggestName( 'default', suggestion );
|
418 | } else if ( importDeclaration.name === '*' ) {
|
419 | const localName = importDeclaration.localName;
|
420 | const suggestion = this.suggestedNames[ localName ] || localName;
|
421 | module.suggestName( '*', suggestion );
|
422 | module.suggestName( 'default', `${suggestion}__default` );
|
423 | }
|
424 |
|
425 | if ( importDeclaration.name === 'default' ) {
|
426 | module.needsDefault = true;
|
427 | } else if ( importDeclaration.name === '*' ) {
|
428 | module.needsAll = true;
|
429 | } else {
|
430 | module.needsNamed = true;
|
431 | }
|
432 |
|
433 | if ( module.isExternal ) {
|
434 | module.importedByBundle.push( importDeclaration );
|
435 | }
|
436 |
|
437 | else if ( importDeclaration.name === '*' ) {
|
438 |
|
439 | if ( !~this.bundle.internalNamespaceModules.indexOf( module ) ) {
|
440 | this.bundle.internalNamespaceModules.push( module );
|
441 | }
|
442 |
|
443 | module.markAllExportStatements();
|
444 | }
|
445 |
|
446 | else {
|
447 | module.markExport( importDeclaration.name, name, this );
|
448 | }
|
449 | }
|
450 |
|
451 | else {
|
452 | const statement = name === 'default' ? this.exports.default.statement : this.definitions[ name ];
|
453 | if ( statement ) statement.mark();
|
454 | }
|
455 | }
|
456 |
|
457 | markAllSideEffects () {
|
458 | this.statements.forEach( statement => {
|
459 | statement.markSideEffect();
|
460 | });
|
461 | }
|
462 |
|
463 | markAllStatements ( isEntryModule ) {
|
464 | this.statements.forEach( statement => {
|
465 | if ( statement.isIncluded ) return;
|
466 |
|
467 |
|
468 | if ( statement.isImportDeclaration ) {
|
469 |
|
470 |
|
471 | if ( !statement.node.specifiers.length ) {
|
472 | const id = this.resolvedIds[ statement.node.source.value ];
|
473 | const otherModule = this.bundle.moduleById[ id ];
|
474 |
|
475 | if ( !otherModule.isExternal ) otherModule.markAllStatements();
|
476 | }
|
477 | }
|
478 |
|
479 |
|
480 | else if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.specifiers.length ) {
|
481 |
|
482 | if ( isEntryModule ) statement.mark();
|
483 | }
|
484 |
|
485 |
|
486 | else {
|
487 | statement.mark();
|
488 | }
|
489 | });
|
490 | }
|
491 |
|
492 | markAllExportStatements () {
|
493 | this.statements.forEach( statement => {
|
494 | if ( statement.isExportDeclaration ) statement.mark();
|
495 | });
|
496 | }
|
497 |
|
498 | markExport ( name, suggestedName, importer ) {
|
499 | const reexport = this.reexports[ name ];
|
500 | const exportDeclaration = this.exports[ name ];
|
501 |
|
502 | if ( reexport ) {
|
503 | reexport.isUsed = true;
|
504 | reexport.module.markExport( reexport.localName, suggestedName, this );
|
505 | }
|
506 |
|
507 | else if ( exportDeclaration ) {
|
508 | exportDeclaration.isUsed = true;
|
509 | if ( name === 'default' ) {
|
510 | this.needsDefault = true;
|
511 | this.suggestName( 'default', suggestedName );
|
512 | return exportDeclaration.statement.mark();
|
513 | }
|
514 |
|
515 | this.mark( exportDeclaration.localName );
|
516 | }
|
517 |
|
518 | else {
|
519 |
|
520 | let i;
|
521 | for ( i = 0; i < this.exportAlls.length; i += 1 ) {
|
522 | const declaration = this.exportAlls[i];
|
523 |
|
524 | if ( declaration.module.exports[ name ] ) {
|
525 |
|
526 |
|
527 | this.exportDelegates[ name ] = declaration;
|
528 | declaration.module.markExport( name );
|
529 |
|
530 | declaration.statement.dependsOn[ name ] =
|
531 | declaration.statement.stronglyDependsOn[ name ] = true;
|
532 |
|
533 | return;
|
534 | }
|
535 | }
|
536 |
|
537 | throw new Error( `Module ${this.id} does not export ${name} (imported by ${importer.id})` );
|
538 | }
|
539 | }
|
540 |
|
541 | parse ( ast ) {
|
542 |
|
543 | if ( !ast ) {
|
544 |
|
545 |
|
546 | try {
|
547 | ast = parse( this.source, {
|
548 | ecmaVersion: 6,
|
549 | sourceType: 'module',
|
550 | onComment: ( block, text, start, end ) => this.comments.push({ block, text, start, end })
|
551 | });
|
552 | } catch ( err ) {
|
553 | err.code = 'PARSE_ERROR';
|
554 | err.file = this.id;
|
555 | err.message += ` in ${this.id}`;
|
556 | throw err;
|
557 | }
|
558 | }
|
559 |
|
560 | walk( ast, {
|
561 | enter: node => {
|
562 | this.magicString.addSourcemapLocation( node.start );
|
563 | this.magicString.addSourcemapLocation( node.end );
|
564 | }
|
565 | });
|
566 |
|
567 | let statements = [];
|
568 | let lastChar = 0;
|
569 | let commentIndex = 0;
|
570 |
|
571 | ast.body.forEach( node => {
|
572 |
|
573 |
|
574 |
|
575 | if ( node.type === 'VariableDeclaration' && node.declarations.length > 1 ) {
|
576 |
|
577 |
|
578 | const lastStatement = statements[ statements.length - 1 ];
|
579 | if ( !lastStatement || !lastStatement.node.isSynthetic ) {
|
580 | this.magicString.remove( node.start, node.declarations[0].start );
|
581 | }
|
582 |
|
583 | node.declarations.forEach( declarator => {
|
584 | const { start, end } = declarator;
|
585 |
|
586 | const syntheticNode = {
|
587 | type: 'VariableDeclaration',
|
588 | kind: node.kind,
|
589 | start,
|
590 | end,
|
591 | declarations: [ declarator ],
|
592 | isSynthetic: true
|
593 | };
|
594 |
|
595 | const statement = new Statement( syntheticNode, this, start, end );
|
596 | statements.push( statement );
|
597 | });
|
598 |
|
599 | lastChar = node.end;
|
600 | }
|
601 |
|
602 | else {
|
603 | let comment;
|
604 | do {
|
605 | comment = this.comments[ commentIndex ];
|
606 | if ( !comment ) break;
|
607 | if ( comment.start > node.start ) break;
|
608 | commentIndex += 1;
|
609 | } while ( comment.end < lastChar );
|
610 |
|
611 | const start = comment ? Math.min( comment.start, node.start ) : node.start;
|
612 | const end = node.end;
|
613 |
|
614 | const statement = new Statement( node, this, start, end );
|
615 | statements.push( statement );
|
616 |
|
617 | lastChar = end;
|
618 | }
|
619 | });
|
620 |
|
621 | statements.forEach( ( statement, i ) => {
|
622 | const nextStatement = statements[ i + 1 ];
|
623 | statement.next = nextStatement ? nextStatement.start : statement.end;
|
624 | });
|
625 |
|
626 | return statements;
|
627 | }
|
628 |
|
629 | rename ( name, replacement ) {
|
630 | this.replacements[ name ] = replacement;
|
631 | }
|
632 |
|
633 | render ( allBundleExports, moduleReplacements ) {
|
634 | let magicString = this.magicString.clone();
|
635 |
|
636 | this.statements.forEach( statement => {
|
637 | if ( !statement.isIncluded ) {
|
638 | magicString.remove( statement.start, statement.next );
|
639 | return;
|
640 | }
|
641 |
|
642 |
|
643 | if ( statement.node.type === 'ExportNamedDeclaration' ) {
|
644 |
|
645 | if ( statement.node.specifiers.length ) {
|
646 | magicString.remove( statement.start, statement.next );
|
647 | return;
|
648 | }
|
649 |
|
650 |
|
651 | if ( isEmptyExportedVarDeclaration( statement.node.declaration, allBundleExports, moduleReplacements ) ) {
|
652 | magicString.remove( statement.start, statement.next );
|
653 | return;
|
654 | }
|
655 | }
|
656 |
|
657 |
|
658 |
|
659 | if ( isEmptyExportedVarDeclaration( statement.node, allBundleExports, moduleReplacements ) ) {
|
660 | magicString.remove( statement.start, statement.next );
|
661 | return;
|
662 | }
|
663 |
|
664 |
|
665 | if ( statement.node.isSynthetic ) {
|
666 |
|
667 | if ( !allBundleExports[ statement.node.declarations[0].id.name ] ) {
|
668 | magicString.insert( statement.start, `${statement.node.kind} ` );
|
669 | }
|
670 |
|
671 | magicString.overwrite( statement.end, statement.next, ';\n' );
|
672 | }
|
673 |
|
674 | let replacements = blank();
|
675 | let bundleExports = blank();
|
676 |
|
677 | keys( statement.dependsOn )
|
678 | .concat( keys( statement.defines ) )
|
679 | .forEach( name => {
|
680 | const bundleName = moduleReplacements[ name ] || name;
|
681 |
|
682 | if ( allBundleExports[ bundleName ] ) {
|
683 | bundleExports[ name ] = replacements[ name ] = allBundleExports[ bundleName ];
|
684 | } else if ( bundleName !== name ) {
|
685 | replacements[ name ] = bundleName;
|
686 | }
|
687 | });
|
688 |
|
689 | statement.replaceIdentifiers( magicString, replacements, bundleExports );
|
690 |
|
691 |
|
692 | if ( statement.isReexportDeclaration ) {
|
693 |
|
694 | magicString.remove( statement.start, statement.next );
|
695 | }
|
696 |
|
697 | else if ( statement.isExportDeclaration ) {
|
698 |
|
699 | if ( statement.node.type === 'ExportNamedDeclaration' && statement.node.declaration.type === 'VariableDeclaration' ) {
|
700 | magicString.remove( statement.node.start, statement.node.declaration.start );
|
701 | }
|
702 |
|
703 |
|
704 |
|
705 | else if ( statement.node.declaration.id ) {
|
706 | magicString.remove( statement.node.start, statement.node.declaration.start );
|
707 | }
|
708 |
|
709 | else if ( statement.node.type === 'ExportDefaultDeclaration' ) {
|
710 | const canonicalName = this.defaultName();
|
711 |
|
712 | if ( statement.node.declaration.type === 'Identifier' && canonicalName === ( moduleReplacements[ statement.node.declaration.name ] || statement.node.declaration.name ) ) {
|
713 | magicString.remove( statement.start, statement.next );
|
714 | return;
|
715 | }
|
716 |
|
717 |
|
718 | if ( canonicalName === undefined ) {
|
719 | magicString.remove( statement.start, statement.node.declaration.start );
|
720 | return;
|
721 | }
|
722 |
|
723 |
|
724 | if ( statement.node.declaration.type === 'FunctionExpression' ) {
|
725 | magicString.overwrite( statement.node.start, statement.node.declaration.start + 8, `function ${canonicalName}` );
|
726 | } else {
|
727 | magicString.overwrite( statement.node.start, statement.node.declaration.start, `var ${canonicalName} = ` );
|
728 | }
|
729 | }
|
730 |
|
731 | else {
|
732 | throw new Error( 'Unhandled export' );
|
733 | }
|
734 | }
|
735 | });
|
736 |
|
737 | return magicString.trim();
|
738 | }
|
739 |
|
740 | suggestName ( defaultOrBatch, suggestion ) {
|
741 |
|
742 | const shouldDeconflict = this.exports.default && this.exports.default.isAnonymous;
|
743 |
|
744 | if ( shouldDeconflict ) suggestion = deconflict( suggestion, this.definitions );
|
745 |
|
746 | if ( !this.suggestedNames[ defaultOrBatch ] ) {
|
747 | this.suggestedNames[ defaultOrBatch ] = makeLegalIdentifier( suggestion );
|
748 | }
|
749 | }
|
750 | }
|