Skip to content

Commit

Permalink
chore(test): validate that requiring TS from ESM works
Browse files Browse the repository at this point in the history
  • Loading branch information
aduh95 committed May 18, 2023
1 parent 3adeb7a commit b10d614
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ require('./myFile.ts'); // works
### Limitations

- You can't import `.ts` files from ESM. If you want to use ESM syntax, you have
convert the file to TS and use `.ts` file extension.
convert the file to TS and use `.ts` file extension, or use
[`createRequire`](https://nodejs.org/api/module.html#modulecreaterequirefilename).
- By default, we only support `.js` and `.ts` file extensions.
- Windows would only support the `node -r @transloadit/ts-fly …` form, as the
executable is a POSIX shell script.
Expand Down
80 changes: 80 additions & 0 deletions test/esmEntryPoint.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Buffer } from 'node:buffer';
import { fileURLToPath } from 'node:url';
import { join } from 'node:path';
import { once } from 'node:events';
import { spawn } from 'node:child_process';
import { platform, tmpdir } from 'node:os';
import assert from 'node:assert';
import fs from 'node:fs/promises';

const ROOT_DIR = new URL('../', import.meta.url);
const { bin } = JSON.parse(
await fs.readFile(new URL('./package.json', ROOT_DIR), 'utf-8'),
);

const tmpDir = await fs.mkdtemp(join(tmpdir(), 'tsen-test-'));

await Promise.all([
fs.writeFile(
join(tmpDir, 'entryPoint.mjs'),
`#!${
// macOS doesn't support shebangs pointing at scripts for some reason
(platform() === 'darwin' ? '/usr/bin/env ' : '') +
fileURLToPath(new URL(bin, ROOT_DIR))
}\n
'use strict';
import {createRequire} from 'node:module';
const require = createRequire(import.meta.url);
await 'top-level';
console.log('require', require('./require.ts'));
import('./dynamic.ts').then(module => console.log('dynamic TS', Object.keys(module)), console.error);
import('./dynamic.mjs').then(module => console.log('dynamic ESM', Object.keys(module)), console.error);
\n`,
'ascii',
),

fs.writeFile(join(tmpDir, 'require.ts'), 'export const a = 1'),
fs.writeFile(join(tmpDir, 'reexported.js'), 'exports.c = 1'),

fs.writeFile(
join(tmpDir, 'dynamic.ts'),
`"use strict";
export default 1;
export const a = 1;
export const b = 1;
export * from "./reexported.js";
\n`,
),

fs.writeFile(
join(tmpDir, 'dynamic.mjs'),
`
export default 1;
export const a = 1;
export const b = 1;
export * from "./reexported.js";
\n`,
),
]);

await Promise.all([fs.chmod(join(tmpDir, 'entryPoint.mjs'), 0o777)]);

try {
const cp = spawn(join(tmpDir, 'entryPoint.mjs'));

const [exitStatus, stdoutArray, stderrArray] = await Promise.all([
once(cp, 'exit'),
cp.stdout.toArray(),
cp.stderr.toArray(),
]);

const stdout = Buffer.concat(stdoutArray).toString('utf-8');
const stderr = Buffer.concat(stderrArray).toString('utf-8');

assert.match(stdout, /^require \{ a: 1 \}$/m);
assert.match(stderr, /Unknown file extension ".ts"/);
assert.match(stdout, /^dynamic ESM \[ 'a', 'b', 'c', 'default' \]$/m);
assert.deepStrictEqual(exitStatus, [0, null]);
} finally {
await fs.rm(tmpDir, { recursive: true, force: true });
}

0 comments on commit b10d614

Please sign in to comment.