Skip to content

Commit 6dcfead

Browse files
authored
v3: pnpm support (#1000)
* WIP fixing pnpm nested install strat * Add changeset * Pass (and log) cwd during background worker initialization * Log out the env * manually add the .pnpm/node_modules to NODE_PATH if in a pnpm repo * Remove supports color dep
1 parent ae839eb commit 6dcfead

File tree

8 files changed

+114
-605
lines changed

8 files changed

+114
-605
lines changed

.changeset/spicy-lamps-smoke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Fixing an issue with bundling @trigger.dev/core/v3 in dev when using pnpm

packages/cli-v3/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
"simple-git": "^3.19.0",
124124
"socket.io-client": "^4.7.4",
125125
"source-map-support": "^0.5.21",
126-
"supports-color": "^9.4.0",
127126
"terminal-link": "^3.0.0",
128127
"tiny-invariant": "^1.2.0",
129128
"tsconfig-paths": "^4.2.0",

packages/cli-v3/src/commands/dev.tsx

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ import { z } from "zod";
2525
import * as packageJson from "../../package.json";
2626
import { CliApiClient } from "../apiClient";
2727
import { CommonCommandOptions, commonOptions, wrapCommandAction } from "../cli/common.js";
28-
import { bundleDependenciesPlugin, workerSetupImportConfigPlugin } from "../utilities/build";
28+
import {
29+
bundleDependenciesPlugin,
30+
bundleTriggerDevCore,
31+
workerSetupImportConfigPlugin,
32+
} from "../utilities/build";
2933
import { chalkError, chalkGrey, chalkPurple, chalkTask, chalkWorker } from "../utilities/cliOutput";
3034
import { readConfig } from "../utilities/configFiles";
3135
import { readJSONFile } from "../utilities/fileSystem";
@@ -47,6 +51,7 @@ import {
4751
parseBuildErrorStack,
4852
parseNpmInstallError,
4953
} from "../utilities/deployErrors";
54+
import { findUp, pathExists } from "find-up";
5055

5156
let apiClient: CliApiClient | undefined;
5257

@@ -384,6 +389,7 @@ function useDev({
384389
__PROJECT_CONFIG__: JSON.stringify(config),
385390
},
386391
plugins: [
392+
bundleTriggerDevCore("workerFacade", config.tsconfigPath),
387393
bundleDependenciesPlugin(
388394
"workerFacade",
389395
(config.dependenciesToBundle ?? []).concat([/^@trigger.dev/]),
@@ -460,7 +466,7 @@ function useDev({
460466
const environmentVariablesResponse =
461467
await environmentClient.getEnvironmentVariables(config.project);
462468

463-
const processEnv = gatherProcessEnv();
469+
const processEnv = await gatherProcessEnv();
464470

465471
const backgroundWorker = new BackgroundWorker(fullPath, {
466472
projectConfig: config,
@@ -770,7 +776,7 @@ function createDuplicateTaskIdOutputErrorMessage(
770776
return `Duplicate ${chalkTask("task id")} detected:${duplicateTable}`;
771777
}
772778

773-
function gatherProcessEnv() {
779+
async function gatherProcessEnv() {
774780
const env = {
775781
NODE_ENV: process.env.NODE_ENV ?? "development",
776782
PATH: process.env.PATH,
@@ -781,11 +787,44 @@ function gatherProcessEnv() {
781787
NVM_BIN: process.env.NVM_BIN,
782788
LANG: process.env.LANG,
783789
TERM: process.env.TERM,
784-
NODE_PATH: process.env.NODE_PATH,
790+
NODE_PATH: await amendNodePathWithPnpmNodeModules(process.env.NODE_PATH),
785791
HOME: process.env.HOME,
786792
BUN_INSTALL: process.env.BUN_INSTALL,
787793
};
788794

789795
// Filter out undefined values
790796
return Object.fromEntries(Object.entries(env).filter(([key, value]) => value !== undefined));
791797
}
798+
799+
async function amendNodePathWithPnpmNodeModules(nodePath?: string): Promise<string | undefined> {
800+
const pnpmModulesPath = await findPnpmNodeModulesPath();
801+
802+
if (!pnpmModulesPath) {
803+
return nodePath;
804+
}
805+
806+
if (nodePath) {
807+
if (nodePath.includes(pnpmModulesPath)) {
808+
return nodePath;
809+
}
810+
811+
return `${nodePath}:${pnpmModulesPath}`;
812+
}
813+
814+
return pnpmModulesPath;
815+
}
816+
817+
async function findPnpmNodeModulesPath(): Promise<string | undefined> {
818+
return await findUp(
819+
async (directory) => {
820+
const pnpmModules = join(directory, "node_modules", ".pnpm", "node_modules");
821+
822+
const hasPnpmNodeModules = await pathExists(pnpmModules);
823+
824+
if (hasPnpmNodeModules) {
825+
return pnpmModules;
826+
}
827+
},
828+
{ type: "directory" }
829+
);
830+
}

packages/cli-v3/src/utilities/build.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,44 @@ import { extname, isAbsolute } from "node:path";
55
import tsConfigPaths from "tsconfig-paths";
66
import { logger } from "./logger";
77

8+
export function bundleTriggerDevCore(buildIdentifier: string, tsconfigPath?: string): Plugin {
9+
return {
10+
name: "trigger-bundle-core",
11+
setup(build) {
12+
build.onResolve({ filter: /.*/ }, (args) => {
13+
if (args.path !== "@trigger.dev/core/v3") {
14+
return undefined;
15+
}
16+
17+
const triggerSdkPath = require.resolve("@trigger.dev/sdk/v3", { paths: [process.cwd()] });
18+
19+
logger.debug(`[${buildIdentifier}][trigger-bundle-core] Resolved @trigger.dev/sdk/v3`, {
20+
...args,
21+
triggerSdkPath,
22+
});
23+
24+
const resolvedPath = require.resolve("@trigger.dev/core/v3", {
25+
paths: [triggerSdkPath],
26+
});
27+
28+
logger.debug(
29+
`[${buildIdentifier}][trigger-bundle-core] Externalizing @trigger.dev/core/v3`,
30+
{
31+
...args,
32+
triggerSdkPath,
33+
resolvedPath,
34+
}
35+
);
36+
37+
return {
38+
path: resolvedPath,
39+
external: false,
40+
};
41+
});
42+
},
43+
};
44+
}
45+
846
export function workerSetupImportConfigPlugin(configPath?: string): Plugin {
947
return {
1048
name: "trigger-worker-setup",

packages/cli-v3/src/utilities/initialBanner.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { spinner } from "@clack/prompts";
22
import chalk from "chalk";
3-
import supportsColor from "supports-color";
43
import type { Result } from "update-check";
54
import checkForUpdate from "update-check";
65
import pkg from "../../package.json";
@@ -52,7 +51,7 @@ export async function printStandloneInitialBanner(performUpdateCheck = true) {
5251
}
5352
}
5453

55-
logger.log(text + "\n" + (supportsColor.stdout ? chalkGrey("-".repeat(54)) : "-".repeat(54)));
54+
logger.log(text + "\n" + chalkGrey("-".repeat(54)));
5655
}
5756

5857
export function printDevBanner() {

packages/cli-v3/src/workers/dev/backgroundWorker.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,13 +319,20 @@ export class BackgroundWorker {
319319

320320
let resolved = false;
321321

322+
const cwd = dirname(this.path);
323+
324+
const fullEnv = {
325+
...this.params.env,
326+
...this.#readEnvVars(),
327+
};
328+
329+
logger.debug("Initializing worker", { path: this.path, cwd, fullEnv });
330+
322331
this.tasks = await new Promise<Array<TaskMetadataWithFilePath>>((resolve, reject) => {
323332
const child = fork(this.path, {
324333
stdio: [/*stdin*/ "ignore", /*stdout*/ "pipe", /*stderr*/ "pipe", "ipc"],
325-
env: {
326-
...this.params.env,
327-
...this.#readEnvVars(),
328-
},
334+
cwd,
335+
env: fullEnv,
329336
});
330337

331338
// Set a timeout to kill the child process if it doesn't respond
@@ -580,14 +587,17 @@ class TaskRunProcess {
580587
...(this.worker.debugOtel ? { OTEL_LOG_LEVEL: "debug" } : {}),
581588
};
582589

590+
const cwd = dirname(this.path);
591+
583592
logger.debug(`[${this.execution.run.id}] initializing task run process`, {
584593
env: fullEnv,
585594
path: this.path,
595+
cwd,
586596
});
587597

588598
this._child = fork(this.path, {
589599
stdio: [/*stdin*/ "ignore", /*stdout*/ "pipe", /*stderr*/ "pipe", "ipc"],
590-
cwd: dirname(this.path),
600+
cwd,
591601
env: fullEnv,
592602
execArgv: this.worker.debuggerOn
593603
? ["--inspect-brk", "--trace-uncaught", "--no-warnings=ExperimentalWarning"]

0 commit comments

Comments
 (0)