Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit a2213f8

Browse files
theRobinatormprobst
authored andcommitted
Fix goog.module naming consistency
Ensure that modules are named after their path relative to `rootDir` or the closest common parent path.
1 parent 26d89fe commit a2213f8

File tree

7 files changed

+50
-12
lines changed

7 files changed

+50
-12
lines changed

src/cli_support.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,23 @@
99
import * as path from 'path';
1010

1111
// Postprocess generated JS.
12-
export function pathToModuleName(context: string, fileName: string): string {
13-
fileName = fileName.replace(/\.js$/, '');
12+
export function pathToModuleName(
13+
rootModulePath: string, context: string, fileName: string): string {
14+
fileName = fileName.replace(/\.[tj]s$/, '');
1415

1516
if (fileName[0] === '.') {
1617
// './foo' or '../foo'.
1718
// Resolve the path against the dirname of the current module.
1819
fileName = path.join(path.dirname(context), fileName);
1920
}
21+
22+
// Ensure consistency by naming all modules after their absolute paths
23+
fileName = path.resolve(fileName);
24+
25+
if (rootModulePath) {
26+
fileName = path.relative(rootModulePath, fileName);
27+
}
28+
2029
// Replace characters not supported by goog.module.
2130
const moduleName =
2231
fileName.replace(/\/|\\/g, '.').replace(/^[^a-zA-Z_$]/, '_').replace(/[^a-zA-Z0-9._$]/g, '_');

src/main.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import * as ts from './typescript';
1717
import * as cliSupport from './cli_support';
1818
import * as tsickle from './tsickle';
1919
import {ModulesManifest} from './tsickle';
20-
import {createSourceReplacingCompilerHost} from './util';
20+
import {getCommonParentDirectory} from './util';
2121

2222
/** Tsickle settings passed on the command line. */
2323
export interface Settings {
@@ -131,17 +131,20 @@ function loadTscConfig(args: string[]):
131131
export function toClosureJS(
132132
options: ts.CompilerOptions, fileNames: string[], settings: Settings,
133133
writeFile?: ts.WriteFileCallback): tsickle.EmitResult {
134-
const compilerHost = ts.createCompilerHost(options);
135-
const program = ts.createProgram(fileNames, options, compilerHost);
136134
// Use absolute paths to determine what files to process since files may be imported using
137135
// relative or absolute paths
138-
const filesToProcess = new Set(fileNames.map(i => path.resolve(i)));
136+
const absoluteFileNames = fileNames.map(i => path.resolve(i));
137+
138+
const compilerHost = ts.createCompilerHost(options);
139+
const program = ts.createProgram(fileNames, options, compilerHost);
140+
const filesToProcess = new Set(absoluteFileNames);
141+
const rootModulePath = options.rootDir || getCommonParentDirectory(absoluteFileNames);
139142
const transformerHost: tsickle.TsickleHost = {
140143
shouldSkipTsickleProcessing: (fileName: string) => {
141144
return !filesToProcess.has(path.resolve(fileName));
142145
},
143146
shouldIgnoreWarningsForPath: (fileName: string) => false,
144-
pathToModuleName: cliSupport.pathToModuleName,
147+
pathToModuleName: cliSupport.pathToModuleName.bind(null, rootModulePath),
145148
fileNameToModuleId: (fileName) => fileName,
146149
es5Mode: true,
147150
googmodule: true,

src/util.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// ES6 maps and sets when running on node 4, which doesn't
1111
// support Iterators completely.
1212

13+
import * as path from 'path';
1314
import * as ts from 'typescript';
1415

1516
/**
@@ -62,3 +63,24 @@ export function hasModifierFlag(node: ts.Node, flag: ts.ModifierFlags): boolean
6263
export function isDtsFileName(fileName: string): boolean {
6364
return /\.d\.ts$/.test(fileName);
6465
}
66+
67+
/**
68+
* Determine the lowest-level common parent directory of the given list of files.
69+
*/
70+
export function getCommonParentDirectory(fileNames: string[]): string {
71+
const pathSplitter = /[\/\\]+/;
72+
const commonParent = fileNames[0].split(pathSplitter);
73+
for (let i = 1; i < fileNames.length; i++) {
74+
const thisPath = fileNames[i].split(pathSplitter);
75+
let j = 0;
76+
while (thisPath[j] === commonParent[j]) {
77+
j++;
78+
}
79+
commonParent.length = j; // Truncate without copying the array
80+
}
81+
if (commonParent.length === 0) {
82+
return '/';
83+
} else {
84+
return commonParent.join(path.sep);
85+
}
86+
}

test/decorator-annotator_test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('decorator-annotator', () => {
4545

4646
const transformerHost: tsickle.TsickleHost = {
4747
shouldSkipTsickleProcessing: (filePath) => !sources(sourceText).has(filePath),
48-
pathToModuleName: cliSupport.pathToModuleName,
48+
pathToModuleName: cliSupport.pathToModuleName.bind(null, '/'),
4949
shouldIgnoreWarningsForPath: (filePath) => false,
5050
fileNameToModuleId: (filePath) => filePath,
5151
transformDecorators: true,

test/e2e_node_kind_source_map_test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('source maps each node with transformer', () => {
2929
quux;`);
3030

3131
// Run tsickle+TSC to convert inputs to Closure JS files.
32-
const {files} = compileWithTransfromer(sources, sourceMapCompilerOptions);
32+
const {files} = compileWithTransfromer(sources, sourceMapCompilerOptions, process.cwd());
3333
const compiledJs = files.get('input.js')!;
3434
const sourceMap = getSourceMapWithName('input.js.map', files);
3535

test/es5processor_test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import * as cliSupport from '../src/cli_support';
1515
import * as es5processor from '../src/es5processor';
1616

1717
import * as testSupport from './test_support';
18+
import {getCommonParentDirectory} from '../src/util';
1819

1920
chaiUse(chaiDiff);
2021

@@ -24,7 +25,7 @@ describe('convertCommonJsToGoogModule', () => {
2425
const tsHost = ts.createCompilerHost(options);
2526
const host: es5processor.Es5ProcessorHost = {
2627
fileNameToModuleId: (fn) => fn,
27-
pathToModuleName: cliSupport.pathToModuleName,
28+
pathToModuleName: cliSupport.pathToModuleName.bind(null, process.cwd()),
2829
es5Mode: isES5,
2930
prelude,
3031
options: testSupport.compilerOptions,

test/test_support.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import * as cliSupport from '../src/cli_support';
1717
import * as es5processor from '../src/es5processor';
1818
import {BasicSourceMapConsumer, sourceMapTextToConsumer} from '../src/source_map_utils';
1919
import * as tsickle from '../src/tsickle';
20+
import {getCommonParentDirectory} from '../src/util';
2021

2122
/** Base compiler options to be customized and exposed. */
2223
export const baseCompilerOptions: ts.CompilerOptions = {
@@ -285,16 +286,18 @@ export function getSourceMapWithName(
285286
* downleveling and closurization.
286287
*/
287288
export function compileWithTransfromer(
288-
sources: Map<string, string>, compilerOptions: ts.CompilerOptions) {
289+
sources: Map<string, string>, compilerOptions: ts.CompilerOptions, rootPath?: string) {
289290
const fileNames = Array.from(sources.keys());
290291
const tsHost = createSourceCachingHost(sources, compilerOptions);
291292
const program = ts.createProgram(fileNames, compilerOptions, tsHost);
292293
expect(ts.getPreEmitDiagnostics(program))
293294
.lengthOf(0, tsickle.formatDiagnostics(ts.getPreEmitDiagnostics(program)));
294295

296+
const rootModulePath = rootPath ? rootPath : getCommonParentDirectory(fileNames);
297+
295298
const transformerHost: tsickle.TsickleHost = {
296299
shouldSkipTsickleProcessing: (filePath) => !sources.has(filePath),
297-
pathToModuleName: cliSupport.pathToModuleName,
300+
pathToModuleName: cliSupport.pathToModuleName.bind(null, rootModulePath),
298301
shouldIgnoreWarningsForPath: (filePath) => false,
299302
fileNameToModuleId: (filePath) => filePath,
300303
transformDecorators: true,

0 commit comments

Comments
 (0)