diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c745d5ea65c..bdd0ef60812 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5343,13 +5343,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi emitExportMemberAssignments(node.name); } } + + function tryRenameExternalModule(moduleName: LiteralExpression): string { + if (currentSourceFile.renamedDependencies && hasProperty(currentSourceFile.renamedDependencies, moduleName.text)) { + return `"${currentSourceFile.renamedDependencies[moduleName.text]}"` + } + return undefined; + } function emitRequire(moduleName: Expression) { if (moduleName.kind === SyntaxKind.StringLiteral) { write("require("); - emitStart(moduleName); - emitLiteral(moduleName); - emitEnd(moduleName); + let text = tryRenameExternalModule(moduleName); + if (text) { + write(text); + } + else { + emitStart(moduleName); + emitLiteral(moduleName); + emitEnd(moduleName); + } emitToken(SyntaxKind.CloseParenToken, moduleName.end); } else { @@ -5752,7 +5765,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi function getExternalModuleNameText(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string { let moduleName = getExternalModuleName(importNode); if (moduleName.kind === SyntaxKind.StringLiteral) { - return getLiteralText(moduleName); + return tryRenameExternalModule(moduleName) || getLiteralText(moduleName); } return undefined; @@ -6320,7 +6333,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi if (i !== 0) { write(", "); - } + } + write(text); } write(`], function(${exportFunctionForFile}) {`); @@ -6333,7 +6347,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi writeLine(); write("});"); } - + function emitAMDDependencies(node: SourceFile, includeNonAmdDependencies: boolean) { // An AMD define function has the following shape: // define(id?, dependencies?, factory); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 89862792540..6a89d1d2321 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1243,6 +1243,10 @@ namespace ts { moduleName: string; referencedFiles: FileReference[]; languageVariant: LanguageVariant; + + // this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling) + /* @internal */ + renamedDependencies?: Map; /** * lib.d.ts should have a reference comment like diff --git a/src/services/services.ts b/src/services/services.ts index bfee19b3a6a..87a6c7ff2b6 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1767,6 +1767,7 @@ namespace ts { fileName?: string; reportDiagnostics?: boolean; moduleName?: string; + renamedDependencies?: Map; } export interface TranspileOutput { @@ -1784,7 +1785,7 @@ namespace ts { * - noLib = true * - noResolve = true */ - export function transpileModule(input: string, transpileOptions?: TranspileOptions): TranspileOutput { + export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput { let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions(); options.isolatedModules = true; @@ -1807,6 +1808,8 @@ namespace ts { sourceFile.moduleName = transpileOptions.moduleName; } + sourceFile.renamedDependencies = transpileOptions.renamedDependencies; + let newLine = getNewLineCharacter(options); // Output diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts index 1fd8c860d01..b3806c4f675 100644 --- a/tests/cases/unittests/transpile.ts +++ b/tests/cases/unittests/transpile.ts @@ -21,22 +21,29 @@ module ts { } function test(input: string, testSettings: TranspileTestSettings): void { - let diagnostics: Diagnostic[] = []; - let transpileOptions: TranspileOptions = testSettings.options || {}; - let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName); + let transpileOptions: TranspileOptions = testSettings.options || {}; + + let canUseOldTranspile = !transpileOptions.renamedDependencies; transpileOptions.reportDiagnostics = true; let transpileModuleResult = transpileModule(input, transpileOptions); - checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes); checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes); if (testSettings.expectedOutput !== undefined) { - assert.equal(transpileResult, testSettings.expectedOutput); assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput); } + if (canUseOldTranspile) { + let diagnostics: Diagnostic[] = []; + let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName); + checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes); + if (testSettings.expectedOutput) { + assert.equal(transpileResult, testSettings.expectedOutput); + } + } + // check source maps if (!transpileOptions.compilerOptions) { transpileOptions.compilerOptions = {}; @@ -138,5 +145,74 @@ var x = 0;`, it("No extra errors for file without extension", () => { test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } }); }); + + it("Rename dependencies - System", () => { + let input = + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);` + let output = + `System.register(["SomeOtherName"], function(exports_1) {\n` + + ` var SomeName_1;\n` + + ` return {\n` + + ` setters:[\n` + + ` function (SomeName_1_1) {\n` + + ` SomeName_1 = SomeName_1_1;\n` + + ` }],\n` + + ` execute: function() {\n` + + ` use(SomeName_1.foo);\n` + + ` }\n` + + ` }\n` + + `});\n` + + test(input, + { + options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, + expectedOutput: output + }); + }); + + it("Rename dependencies - AMD", () => { + let input = + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);` + let output = + `define(["require", "exports", "SomeOtherName"], function (require, exports, SomeName_1) {\n` + + ` use(SomeName_1.foo);\n` + + `});\n`; + + test(input, + { + options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, + expectedOutput: output + }); + }); + + it("Rename dependencies - UMD", () => { + let input = + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);` + let output = + `(function (deps, factory) {\n` + + ` if (typeof module === 'object' && typeof module.exports === 'object') {\n` + + ` var v = factory(require, exports); if (v !== undefined) module.exports = v;\n` + + ` }\n` + + ` else if (typeof define === 'function' && define.amd) {\n` + + ` define(deps, factory);\n` + + ` }\n` + + `})(["require", "exports", "SomeOtherName"], function (require, exports) {\n` + + ` var SomeName_1 = require("SomeOtherName");\n` + + ` use(SomeName_1.foo);\n` + + `});\n`; + + test(input, + { + options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, + expectedOutput: output + }); + }); + }); }