Skip to content

Commit b7de3bf

Browse files
committed
feat(turbo-utils): convert package to dual ESM/CommonJS build
This commit converts turbo-utils from a TypeScript-only package to a dual ESM/CommonJS package with proper build outputs, addressing compatibility requirements across different module systems. Key changes: - Package.json: Added "type": "module" and dual export configuration with separate entry points for ESM, CommonJS, and TypeScript declarations - Build system: Implemented three-stage build process (ESM, CJS, types) with corresponding TypeScript configurations - Import statements: Updated all relative imports to include .js extensions for ESM compatibility - Module handling: Fixed imports for packages like tar, fast-glob, and picocolors to work with ESM - Jest configuration: Added module name mapping to handle .js extension resolution in tests - TypeScript configs: Created separate tsconfig files for ESM (tsconfig.json), CommonJS (tsconfig.cjs.json), and type declarations (tsconfig.types.json) Build outputs: - dist/esm/: ES module build for modern environments - dist/cjs/: CommonJS build for Node.js compatibility - dist/types/: TypeScript declaration files The package now supports both import and require syntax while maintaining backward compatibility through the dual export system.
1 parent 6c0b9d5 commit b7de3bf

File tree

13 files changed

+94
-39
lines changed

13 files changed

+94
-39
lines changed

packages/turbo-utils/jest.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const config = {
77
transformIgnorePatterns: ["/node_modules/(?!(ansi-regex)/)"],
88
verbose: process.env.RUNNER_DEBUG === "1",
99
silent: process.env.RUNNER_DEBUG !== "1",
10+
moduleNameMapper: {
11+
"^(\\./.+)\\.js$": "$1",
12+
},
1013
} as const satisfies Config;
1114

1215
export default config;

packages/turbo-utils/package.json

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,24 @@
1515
"bugs": {
1616
"url": "https://github.com/vercel/turborepo/issues"
1717
},
18-
"module": "src/index.ts",
19-
"main": "src/index.ts",
20-
"types": "src/index.ts",
18+
"type": "module",
19+
"main": "dist/cjs/index.js",
20+
"module": "dist/esm/index.js",
21+
"types": "dist/types/index.d.ts",
22+
"exports": {
23+
".": {
24+
"types": "./dist/types/index.d.ts",
25+
"import": "./dist/esm/index.js",
26+
"require": "./dist/cjs/index.js",
27+
"default": "./dist/esm/index.js"
28+
}
29+
},
2130
"scripts": {
31+
"build": "pnpm build:esm && pnpm build:cjs && pnpm build:types && pnpm post-build",
32+
"post-build": "echo '{ \"type\": \"commonjs\" }' > dist/cjs/package.json",
33+
"build:esm": "tsc -p tsconfig.json",
34+
"build:cjs": "tsc -p tsconfig.cjs.json",
35+
"build:types": "tsc -p tsconfig.types.json",
2236
"test": "jest",
2337
"lint": "eslint src/",
2438
"check-types": "tsc --noEmit",

packages/turbo-utils/src/createProject.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import path from "node:path";
22
import retry from "async-retry";
33
import picocolors from "picocolors";
44
import fs from "fs-extra";
5-
import * as logger from "./logger";
5+
import * as logger from "./logger.js";
66
import {
77
downloadAndExtractExample,
88
downloadAndExtractRepo,
99
getRepoInfo,
1010
existsInRepo,
1111
hasRepo,
1212
type RepoInfo,
13-
} from "./examples";
14-
import { isWriteable } from "./isWriteable";
15-
import { isFolderEmpty } from "./isFolderEmpty";
16-
import type { PackageJson } from "./types";
13+
} from "./examples.js";
14+
import { isWriteable } from "./isWriteable.js";
15+
import { isFolderEmpty } from "./isFolderEmpty.js";
16+
import type { PackageJson } from "./types.js";
1717

1818
function isErrorLike(err: unknown): err is { message: string } {
1919
return (

packages/turbo-utils/src/examples.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { promisify } from "node:util";
33
import { join } from "node:path";
44
import { tmpdir } from "node:os";
55
import { createWriteStream, promises as fs } from "node:fs";
6-
import { x as extract } from "tar";
6+
import tar from "tar";
77
import got from "got";
88

9+
const { x: extract } = tar;
10+
911
const pipeline = promisify(Stream.pipeline);
1012

1113
export interface RepoInfo {

packages/turbo-utils/src/getTurboConfigs.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from "node:fs";
22
import path from "node:path";
33
import yaml from "js-yaml";
4-
import { sync } from "fast-glob";
4+
import glob from "fast-glob";
55
import JSON5 from "json5";
66
import type {
77
BaseSchemaV1,
@@ -10,9 +10,11 @@ import type {
1010
BaseSchemaV2,
1111
PipelineV2,
1212
} from "@turbo/types";
13-
import * as logger from "./logger";
14-
import { getTurboRoot } from "./getTurboRoot";
15-
import type { PackageJson, PNPMWorkspaceConfig } from "./types";
13+
import * as logger from "./logger.js";
14+
import { getTurboRoot } from "./getTurboRoot.js";
15+
import type { PackageJson, PNPMWorkspaceConfig } from "./types.js";
16+
17+
const { sync } = glob;
1618

1719
const ROOT_GLOB = "{turbo.json,turbo.jsonc}";
1820
const ROOT_WORKSPACE_GLOB = "package.json";

packages/turbo-utils/src/getTurboRoot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Schema } from "@turbo/types";
22
import { findRootSync } from "@manypkg/find-root";
33
import json5 from "json5";
4-
import { searchUp } from "./searchUp";
4+
import { searchUp } from "./searchUp.js";
55

66
interface Options {
77
cache?: boolean;

packages/turbo-utils/src/index.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
// utils
2-
export { getTurboRoot } from "./getTurboRoot";
2+
export { getTurboRoot } from "./getTurboRoot.js";
33
export {
44
getTurboConfigs,
55
getWorkspaceConfigs,
66
forEachTaskDef,
7-
} from "./getTurboConfigs";
8-
export { searchUp } from "./searchUp";
7+
} from "./getTurboConfigs.js";
8+
export { searchUp } from "./searchUp.js";
99
export {
1010
getAvailablePackageManagers,
1111
getPackageManagersBinPaths,
12-
} from "./managers";
13-
export { isFolderEmpty } from "./isFolderEmpty";
14-
export { validateDirectory } from "./validateDirectory";
12+
} from "./managers.js";
13+
export { isFolderEmpty } from "./isFolderEmpty.js";
14+
export { validateDirectory } from "./validateDirectory.js";
1515
export {
1616
isUrlOk,
1717
getRepoInfo,
1818
hasRepo,
1919
existsInRepo,
2020
downloadAndExtractRepo,
2121
downloadAndExtractExample,
22-
} from "./examples";
23-
export { isWriteable } from "./isWriteable";
24-
export { createProject, DownloadError } from "./createProject";
25-
export { convertCase } from "./convertCase";
22+
} from "./examples.js";
23+
export { isWriteable } from "./isWriteable.js";
24+
export { createProject, DownloadError } from "./createProject.js";
25+
export { convertCase } from "./convertCase.js";
2626

27-
export * as logger from "./logger";
27+
export * as logger from "./logger.js";
2828

2929
// types
30-
export type { RepoInfo } from "./examples";
30+
export type { RepoInfo } from "./examples.js";
3131
export type {
3232
TurboConfig,
3333
TurboConfigs,
3434
WorkspaceConfig,
35-
} from "./getTurboConfigs";
36-
export * from "./types";
35+
} from "./getTurboConfigs.js";
36+
export * from "./types.js";

packages/turbo-utils/src/logger.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
import {
2-
reset,
3-
bold as pcBold,
4-
underline as pcUnderline,
5-
gray,
6-
dim,
7-
} from "picocolors";
1+
import pc from "picocolors";
82
import ora from "ora";
93
import gradient from "gradient-string";
104

5+
const { reset, bold: pcBold, underline: pcUnderline, gray, dim } = pc;
6+
117
const BLUE = "#0099F7";
128
const RED = "#F11712";
139
const YELLOW = "#FFFF00";

packages/turbo-utils/src/managers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os from "node:os";
22
import type { Options } from "execa";
33
import execa from "execa";
4-
import type { PackageManager } from "./types";
4+
import type { PackageManager } from "./types.js";
55

66
async function exec(command: string, args: Array<string> = [], opts?: Options) {
77
// run the check from tmpdir to avoid corepack conflicting -

packages/turbo-utils/src/validateDirectory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from "node:path";
22
import fs from "fs-extra";
33
import picocolors from "picocolors";
4-
import { isFolderEmpty } from "./isFolderEmpty";
4+
import { isFolderEmpty } from "./isFolderEmpty.js";
55

66
export function validateDirectory(directory: string): {
77
valid: boolean;

0 commit comments

Comments
 (0)