Skip to content

Commit

Permalink
Preserve require() calls for nodejs builtin modules
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 576169055
  • Loading branch information
tsjs-language-eng authored and copybara-github committed Oct 24, 2023
1 parent d5c2921 commit bf98f0c
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/googmodule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,88 @@ export function extractModuleMarker(
return literalTypeOfSymbol(localSymbol);
}

// node -p "require('module').builtinModules"
const NODEJS_BUILTIN_MODULES = [
'_http_agent',
'_http_client',
'_http_common',
'_http_incoming',
'_http_outgoing',
'_http_server',
'_stream_duplex',
'_stream_passthrough',
'_stream_readable',
'_stream_transform',
'_stream_wrap',
'_stream_writable',
'_tls_common',
'_tls_wrap',
'assert',
'assert/strict',
'async_hooks',
'buffer',
'child_process',
'cluster',
'console',
'constants',
'crypto',
'dgram',
'diagnostics_channel',
'dns',
'dns/promises',
'domain',
'events',
'fs',
'fs/promises',
'http',
'http2',
'https',
'inspector',
'module',
'net',
'os',
'path',
'path/posix',
'path/win32',
'perf_hooks',
'process',
'punycode',
'querystring',
'readline',
'readline/promises',
'repl',
'stream',
'stream/consumers',
'stream/promises',
'stream/web',
'string_decoder',
'sys',
'timers',
'timers/promises',
'tls',
'trace_events',
'tty',
'url',
'util',
'util/types',
'v8',
'vm',
'wasi',
'worker_threads',
'zlib',
];

// Possible patterns:
// - "fs" (\w+)
// - "node:fs" (node:\w+)
// - "fs/promises" (\w+/\w+)
// - "node:fs/promises" (node:\w+/\w+)
const NODEJS_BUILTIN_PATTERN = /^(?:node:)?(\w+(?:\/\w+)?)$/;
function isNodeJSBuiltin(specifier: string): boolean {
const match = specifier.match(NODEJS_BUILTIN_PATTERN);
return match !== null && NODEJS_BUILTIN_MODULES.includes(match[1]);
}

/** Internal TypeScript APIs on ts.Declaration. */
declare interface InternalTsDeclaration {
locals?: ts.SymbolTable;
Expand Down Expand Up @@ -706,6 +788,7 @@ export function commonJsToGoogmoduleTransformer(
newIdent: ts.Identifier|undefined): ts.Statement|null {
const importedUrl = extractRequire(call);
if (!importedUrl) return null;
if (isNodeJSBuiltin(importedUrl.text)) return null;
// if importPathToGoogNamespace reports an error, it has already been
// reported when originally transforming the file to JS (e.g. to produce
// the goog.requireType call). Side-effect imports generate no
Expand Down
40 changes: 40 additions & 0 deletions test/googmodule_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,46 @@ describe('convertCommonJsToGoogModule', () => {
`));
});

describe('nodejs builtin imports', () => {
it('converts builtin imports to require (not goog.require)', () => {
const before = `
import {readFile as a} from 'fs';
import {readFile as b} from 'fs/promises';
import {readFile as c} from 'node:fs';
import {readFile as d} from 'node:fs/promises';
console.log(a, b, c, d);
`;

expectCommonJs('a.ts', before, false).toBe(outdent(`
goog.module('a');
var module = module || { id: 'a.ts' };
goog.require('tslib');
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const node_fs_1 = require("node:fs");
const promises_2 = require("node:fs/promises");
console.log(fs_1.readFile, promises_1.readFile, node_fs_1.readFile, promises_2.readFile);
`));
});

it('allows a trailing slash as an escape hatch', () => {
const before = `
import {readFile as a} from 'fs/';
import {readFile as b} from 'fs/promises/';
console.log(a, b);
`;

expectCommonJs('a.ts', before, false).toBe(outdent(`
goog.module('a');
var module = module || { id: 'a.ts' };
goog.require('tslib');
const fs_1 = goog.require('fs');
const promises_1 = goog.require('fs.promises');
console.log(fs_1.readFile, promises_1.readFile);
`));
});
});

describe('dynamic import', () => {
it('handles dynamic imports', () => {
const before = `
Expand Down

0 comments on commit bf98f0c

Please sign in to comment.