Merge pull request #4319 from Microsoft/renameDependencies

allow transpiler to provide alternative names for dependencies
This commit is contained in:
Vladimir Matveev 2015-08-17 10:44:53 -07:00
commit 6a17db8e3b
5 changed files with 113 additions and 12 deletions

View file

@ -5343,13 +5343,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emitExportMemberAssignments(<Identifier>node.name);
}
}
/*
* Some bundlers (SystemJS builder) sometimes want to rename dependencies.
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
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(<LiteralExpression>moduleName);
emitEnd(moduleName);
let text = tryRenameExternalModule(<LiteralExpression>moduleName);
if (text) {
write(text);
}
else {
emitStart(moduleName);
emitLiteral(<LiteralExpression>moduleName);
emitEnd(moduleName);
}
emitToken(SyntaxKind.CloseParenToken, moduleName.end);
}
else {
@ -5752,7 +5769,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(<LiteralExpression>moduleName);
return tryRenameExternalModule(<LiteralExpression>moduleName) || getLiteralText(<LiteralExpression>moduleName);
}
return undefined;
@ -6317,10 +6334,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
groupIndices[text] = dependencyGroups.length;
dependencyGroups.push([externalImports[i]]);
}
if (i !== 0) {
write(", ");
}
write(text);
}
write(`], function(${exportFunctionForFile}) {`);

View file

@ -334,7 +334,7 @@ namespace ts {
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
return getWScriptSystem();
}
else if (typeof process !== "undefined" && process.nextTick && !process.browser) {
else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
// process and process.nextTick checks if current environment is node-like
// process.browser check excludes webpack and browserify
return getNodeSystem();

View file

@ -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<string>;
/**
* lib.d.ts should have a reference comment like

View file

@ -1767,6 +1767,7 @@ namespace ts {
fileName?: string;
reportDiagnostics?: boolean;
moduleName?: string;
renamedDependencies?: Map<string>;
}
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

View file

@ -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
});
});
});
}