@@ -103,11 +103,6 @@ namespace ts {
103
103
insertStatementsAfterStandardPrologue ( statements , endLexicalEnvironment ( ) ) ;
104
104
105
105
const updated = updateSourceFileNode ( node , setTextRange ( createNodeArray ( statements ) , node . statements ) ) ;
106
- if ( currentModuleInfo . hasExportStarsToExportValues && ! compilerOptions . importHelpers ) {
107
- // If we have any `export * from ...` declarations
108
- // we need to inform the emitter to add the __export helper.
109
- addEmitHelper ( updated , exportStarHelper ) ;
110
- }
111
106
addEmitHelpers ( updated , context . readEmitHelpers ( ) ) ;
112
107
return updated ;
113
108
}
@@ -435,11 +430,6 @@ namespace ts {
435
430
insertStatementsAfterStandardPrologue ( statements , endLexicalEnvironment ( ) ) ;
436
431
437
432
const body = createBlock ( statements , /*multiLine*/ true ) ;
438
- if ( currentModuleInfo . hasExportStarsToExportValues && ! compilerOptions . importHelpers ) {
439
- // If we have any `export * from ...` declarations
440
- // we need to inform the emitter to add the __export helper.
441
- addEmitHelper ( body , exportStarHelper ) ;
442
- }
443
433
if ( needUMDDynamicImportHelper ) {
444
434
addEmitHelper ( body , dynamicImportUMDHelper ) ;
445
435
}
@@ -1001,20 +991,34 @@ namespace ts {
1001
991
) ;
1002
992
}
1003
993
for ( const specifier of node . exportClause . elements ) {
1004
- const exportedValue = createPropertyAccess (
1005
- generatedName ,
1006
- specifier . propertyName || specifier . name
1007
- ) ;
1008
- statements . push (
1009
- setOriginalNode (
1010
- setTextRange (
1011
- createExpressionStatement (
1012
- createExportExpression ( getExportName ( specifier ) , exportedValue )
1013
- ) ,
1014
- specifier ) ,
1015
- specifier
1016
- )
1017
- ) ;
994
+ if ( languageVersion === ScriptTarget . ES3 ) {
995
+ statements . push (
996
+ setOriginalNode (
997
+ setTextRange (
998
+ createExpressionStatement (
999
+ createCreateBindingHelper ( context , generatedName , createLiteral ( specifier . propertyName || specifier . name ) , specifier . propertyName ? createLiteral ( specifier . name ) : undefined )
1000
+ ) ,
1001
+ specifier ) ,
1002
+ specifier
1003
+ )
1004
+ ) ;
1005
+ }
1006
+ else {
1007
+ const exportedValue = createPropertyAccess (
1008
+ generatedName ,
1009
+ specifier . propertyName || specifier . name
1010
+ ) ;
1011
+ statements . push (
1012
+ setOriginalNode (
1013
+ setTextRange (
1014
+ createExpressionStatement (
1015
+ createExportExpression ( getExportName ( specifier ) , exportedValue , /* location */ undefined , /* liveBinding */ true )
1016
+ ) ,
1017
+ specifier ) ,
1018
+ specifier
1019
+ )
1020
+ ) ;
1021
+ }
1018
1022
}
1019
1023
1020
1024
return singleOrMany ( statements ) ;
@@ -1343,7 +1347,7 @@ namespace ts {
1343
1347
1344
1348
case SyntaxKind . NamedImports :
1345
1349
for ( const importBinding of namedBindings . elements ) {
1346
- statements = appendExportsOfDeclaration ( statements , importBinding ) ;
1350
+ statements = appendExportsOfDeclaration ( statements , importBinding , /* liveBinding */ true ) ;
1347
1351
}
1348
1352
1349
1353
break ;
@@ -1453,12 +1457,12 @@ namespace ts {
1453
1457
* appended.
1454
1458
* @param decl The declaration to export.
1455
1459
*/
1456
- function appendExportsOfDeclaration ( statements : Statement [ ] | undefined , decl : Declaration ) : Statement [ ] | undefined {
1460
+ function appendExportsOfDeclaration ( statements : Statement [ ] | undefined , decl : Declaration , liveBinding ?: boolean ) : Statement [ ] | undefined {
1457
1461
const name = getDeclarationName ( decl ) ;
1458
1462
const exportSpecifiers = currentModuleInfo . exportSpecifiers . get ( idText ( name ) ) ;
1459
1463
if ( exportSpecifiers ) {
1460
1464
for ( const exportSpecifier of exportSpecifiers ) {
1461
- statements = appendExportStatement ( statements , exportSpecifier . name , name , /*location*/ exportSpecifier . name ) ;
1465
+ statements = appendExportStatement ( statements , exportSpecifier . name , name , /*location*/ exportSpecifier . name , /* allowComments */ undefined , liveBinding ) ;
1462
1466
}
1463
1467
}
1464
1468
return statements ;
@@ -1476,8 +1480,8 @@ namespace ts {
1476
1480
* @param location The location to use for source maps and comments for the export.
1477
1481
* @param allowComments Whether to allow comments on the export.
1478
1482
*/
1479
- function appendExportStatement ( statements : Statement [ ] | undefined , exportName : Identifier , expression : Expression , location ?: TextRange , allowComments ?: boolean ) : Statement [ ] | undefined {
1480
- statements = append ( statements , createExportStatement ( exportName , expression , location , allowComments ) ) ;
1483
+ function appendExportStatement ( statements : Statement [ ] | undefined , exportName : Identifier , expression : Expression , location ?: TextRange , allowComments ?: boolean , liveBinding ?: boolean ) : Statement [ ] | undefined {
1484
+ statements = append ( statements , createExportStatement ( exportName , expression , location , allowComments , liveBinding ) ) ;
1481
1485
return statements ;
1482
1486
}
1483
1487
@@ -1518,8 +1522,8 @@ namespace ts {
1518
1522
* @param location The location to use for source maps and comments for the export.
1519
1523
* @param allowComments An optional value indicating whether to emit comments for the statement.
1520
1524
*/
1521
- function createExportStatement ( name : Identifier , value : Expression , location ?: TextRange , allowComments ?: boolean ) {
1522
- const statement = setTextRange ( createExpressionStatement ( createExportExpression ( name , value ) ) , location ) ;
1525
+ function createExportStatement ( name : Identifier , value : Expression , location ?: TextRange , allowComments ?: boolean , liveBinding ?: boolean ) {
1526
+ const statement = setTextRange ( createExpressionStatement ( createExportExpression ( name , value , /* location */ undefined , liveBinding ) ) , location ) ;
1523
1527
startOnNewLine ( statement ) ;
1524
1528
if ( ! allowComments ) {
1525
1529
setEmitFlags ( statement , EmitFlags . NoComments ) ;
@@ -1535,9 +1539,31 @@ namespace ts {
1535
1539
* @param value The exported value.
1536
1540
* @param location The location to use for source maps and comments for the export.
1537
1541
*/
1538
- function createExportExpression ( name : Identifier , value : Expression , location ?: TextRange ) {
1542
+ function createExportExpression ( name : Identifier , value : Expression , location ?: TextRange , liveBinding ?: boolean ) {
1539
1543
return setTextRange (
1540
- createAssignment (
1544
+ liveBinding && languageVersion !== ScriptTarget . ES3 ? createCall (
1545
+ createPropertyAccess (
1546
+ createIdentifier ( "Object" ) ,
1547
+ "defineProperty"
1548
+ ) ,
1549
+ /*typeArguments*/ undefined ,
1550
+ [
1551
+ createIdentifier ( "exports" ) ,
1552
+ createLiteral ( name ) ,
1553
+ createObjectLiteral ( [
1554
+ createPropertyAssignment ( "enumerable" , createLiteral ( /*value*/ true ) ) ,
1555
+ createPropertyAssignment ( "get" , createFunctionExpression (
1556
+ /*modifiers*/ undefined ,
1557
+ /*asteriskToken*/ undefined ,
1558
+ /*name*/ undefined ,
1559
+ /*typeParameters*/ undefined ,
1560
+ /*parameters*/ [ ] ,
1561
+ /*type*/ undefined ,
1562
+ createBlock ( [ createReturn ( value ) ] )
1563
+ ) )
1564
+ ] )
1565
+ ]
1566
+ ) : createAssignment (
1541
1567
createPropertyAccess (
1542
1568
createIdentifier ( "exports" ) ,
1543
1569
getSynthesizedClone ( name )
@@ -1813,21 +1839,55 @@ namespace ts {
1813
1839
}
1814
1840
}
1815
1841
1842
+ export const createBindingHelper : UnscopedEmitHelper = {
1843
+ name : "typescript:commonjscreatebinding" ,
1844
+ importName : "__createBinding" ,
1845
+ scoped : false ,
1846
+ priority : 1 ,
1847
+ text : `
1848
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
1849
+ if (k2 === undefined) k2 = k;
1850
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
1851
+ }) : (function(o, m, k, k2) {
1852
+ if (k2 === undefined) k2 = k;
1853
+ o[k2] = m[k];
1854
+ }));`
1855
+ } ;
1856
+
1857
+ function createCreateBindingHelper ( context : TransformationContext , module : Expression , inputName : Expression , outputName : Expression | undefined ) {
1858
+ context . requestEmitHelper ( createBindingHelper ) ;
1859
+ return createCall ( getUnscopedHelperName ( "__createBinding" ) , /*typeArguments*/ undefined , [ createIdentifier ( "exports" ) , module , inputName , ...( outputName ? [ outputName ] : [ ] ) ] ) ;
1860
+ }
1861
+
1862
+ export const setModuleDefaultHelper : UnscopedEmitHelper = {
1863
+ name : "typescript:commonjscreatevalue" ,
1864
+ importName : "__setModuleDefault" ,
1865
+ scoped : false ,
1866
+ priority : 1 ,
1867
+ text : `
1868
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
1869
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
1870
+ }) : function(o, v) {
1871
+ o["default"] = v;
1872
+ });`
1873
+ } ;
1874
+
1816
1875
// emit output for the __export helper function
1817
- const exportStarHelper : EmitHelper = {
1876
+ const exportStarHelper : UnscopedEmitHelper = {
1818
1877
name : "typescript:export-star" ,
1819
- scoped : true ,
1878
+ importName : "__exportStar" ,
1879
+ scoped : false ,
1880
+ dependencies : [ createBindingHelper ] ,
1881
+ priority : 2 ,
1820
1882
text : `
1821
- function __export(m ) {
1822
- for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p] ;
1883
+ var __exportStar = (this && this.__exportStar) || function(m, exports ) {
1884
+ for (var p in m) if (!exports.hasOwnProperty(p)) __createBinding( exports, m, p) ;
1823
1885
}`
1824
1886
} ;
1825
1887
1826
1888
function createExportStarHelper ( context : TransformationContext , module : Expression ) {
1827
- const compilerOptions = context . getCompilerOptions ( ) ;
1828
- return compilerOptions . importHelpers
1829
- ? createCall ( getUnscopedHelperName ( "__exportStar" ) , /*typeArguments*/ undefined , [ module , createIdentifier ( "exports" ) ] )
1830
- : createCall ( createIdentifier ( "__export" ) , /*typeArguments*/ undefined , [ module ] ) ;
1889
+ context . requestEmitHelper ( exportStarHelper ) ;
1890
+ return createCall ( getUnscopedHelperName ( "__exportStar" ) , /*typeArguments*/ undefined , [ module , createIdentifier ( "exports" ) ] ) ;
1831
1891
}
1832
1892
1833
1893
// emit helper for dynamic import
@@ -1843,12 +1903,14 @@ namespace ts {
1843
1903
name : "typescript:commonjsimportstar" ,
1844
1904
importName : "__importStar" ,
1845
1905
scoped : false ,
1906
+ dependencies : [ createBindingHelper , setModuleDefaultHelper ] ,
1907
+ priority : 2 ,
1846
1908
text : `
1847
1909
var __importStar = (this && this.__importStar) || function (mod) {
1848
1910
if (mod && mod.__esModule) return mod;
1849
1911
var result = {};
1850
- if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k] ;
1851
- result["default"] = mod;
1912
+ if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding( result, mod, k) ;
1913
+ __setModuleDefault( result, mod) ;
1852
1914
return result;
1853
1915
};`
1854
1916
} ;
0 commit comments