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

Commit a593c42

Browse files
committed
Run npm install and build after generating a bundle
1 parent b2b3b9f commit a593c42

File tree

6 files changed

+65
-17
lines changed

6 files changed

+65
-17
lines changed

src/generate/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import * as chalk from "chalk";
33
import * as path from "path";
44
import * as fs from "fs";
55
import { logger } from "../utils/log";
6-
import { directoryExists, findNodeCGDirectory, getNodeCGIODirectory } from "../utils/fs";
6+
import { directoryExists, executeCommand, findNodeCGDirectory, getNodeCGIODirectory } from "../utils/fs";
77
import { ProductionInstallation, readInstallInfo } from "../utils/installation";
88
import { corePackages, getServiceClientName } from "../nodecgIOVersions";
99
import { GenerationOptions, promptGenerationOpts } from "./prompt";
1010
import * as defaultTsConfigJson from "./tsconfig.json";
1111
import CodeBlockWriter from "code-block-writer";
12+
import { runNpmBuild, runNpmInstall } from "../utils/npm";
1213

1314
export const yellowInstallCommand = chalk.yellow("nodecg-io install");
1415
const yellowGenerateCommand = chalk.yellow("nodecg-io generate");
@@ -73,8 +74,13 @@ async function generateBundle(
7374
await generatePackageJson(bundlePath, opts);
7475
await generateTsConfig(bundlePath);
7576
await generateExtension(bundlePath, opts, install);
77+
logger.info("Generated bundle successfully.");
7678

77-
// TODO: perform npm install and first build
79+
logger.info("Installing dependencies...");
80+
await runNpmInstall(bundlePath, false);
81+
82+
logger.info("Compiling bundle...");
83+
await runNpmBuild(bundlePath);
7884
}
7985

8086
async function generatePackageJson(bundlePath: string, opts: GenerationOptions): Promise<void> {
@@ -152,7 +158,7 @@ async function generateExtension(
152158
writer.blankLine();
153159

154160
writer
155-
.write(`${svc.camelCase}?.onAvailable(async (${svc.camelCase}Client) =>`)
161+
.write(`${svc.camelCase}?.onAvailable(async (${svc.camelCase}Client) => `)
156162
.inlineBlock(() => {
157163
writer.writeLine(`nodecg.log.info("${svc.name} client has been updated.")`);
158164
writer.writeLine(`// You can now use the ${svc.name} client here.`);

src/install/development.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { DevelopmentInstallation, writeInstallInfo } from "../utils/installation
77
import { logger } from "../utils/log";
88
import * as path from "path";
99
import * as glob from "glob";
10+
import { runNpmBuild, runNpmInstall } from "../utils/npm";
1011

1112
type CloneRepository = "nodecg-io" | "nodecg-io-docs";
1213
const nodecgIOCloneURL = "https://github.com/codeoverflow-org/nodecg-io.git";
@@ -176,14 +177,14 @@ function getGitCommitHash(dir: string): Promise<string> {
176177
async function installNPMDependencies(nodecgIODir: string) {
177178
logger.info("Installing npm dependencies and bootstrapping...");
178179

179-
await executeCommand("npm", ["install"], nodecgIODir);
180+
await runNpmInstall(nodecgIODir, false);
180181
await executeCommand("npm", ["run", "bootstrap"], nodecgIODir);
181182

182183
logger.info("Installed npm dependencies and bootstrapped.");
183184
}
184185

185186
async function buildTypeScript(nodecgIODir: string, concurrency: number) {
186187
logger.info("Compiling nodecg-io...");
187-
await executeCommand("npm", ["run", "build", "--", "--concurrency", concurrency.toString()], nodecgIODir);
188+
await runNpmBuild(nodecgIODir, "--", "concurrency", concurrency.toString());
188189
logger.success("Compiled nodecg-io.");
189190
}

src/install/production.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ async function createSymlinks(pkgs: NpmPackage[], nodecgIODir: string): Promise<
149149
*/
150150
async function installNpmDependencies(pkgs: NpmPackage[], nodecgIODir: string): Promise<void> {
151151
await writeWorkspacePackageJson(pkgs, nodecgIODir);
152-
await runNpmInstall(nodecgIODir);
152+
await runNpmInstall(nodecgIODir, true);
153153
}
154154

155155
/**

src/utils/npm.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,20 @@ export async function downloadNpmPackage(pkg: NpmPackage, nodecgIODir: string):
150150
/**
151151
* Installs npm production dependencies in the passed path by running npm install --prod in the directory.
152152
* @param path the path where a package.json is present
153+
* @param prod whether to only install production dependencies or also devDependencies.
153154
*/
154-
export async function runNpmInstall(path: string): Promise<void> {
155-
await executeCommand("npm", ["install", "--prod"], path);
155+
export async function runNpmInstall(path: string, prod: boolean): Promise<void> {
156+
const prodArg = prod ? ["--prod"] : [];
157+
await executeCommand("npm", ["install", ...prodArg], path);
158+
}
159+
160+
/**
161+
* Compiles the TypeScript code of a package by running executing the npm script called "build".
162+
* @param path the path in which the package is located.
163+
* @param args additional arguments that are passed to npm.
164+
*/
165+
export async function runNpmBuild(path: string, ...args: string[]): Promise<void> {
166+
await executeCommand("npm", ["run", "build", ...args], path);
156167
}
157168

158169
/**

test/install/production.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ describe("installPackages", () => {
9898
expect(packageJson["workspaces"]).toStrictEqual(packages.map((p) => p.path));
9999
});
100100

101-
test("should install dependencies", async () => {
101+
test("should install prod dependencies", async () => {
102102
await installPackages(packages, createInstall(), nodecgIODir);
103103
expect(npmInstallMock).toHaveBeenCalled();
104-
expect(npmInstallMock).toHaveBeenCalledWith(nodecgIODir);
104+
expect(npmInstallMock).toHaveBeenCalledWith(nodecgIODir, true);
105105
});
106106

107107
test("should revert changes if npm install fails", async () => {

test/utils/npm/pkgManagement.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,49 @@
11
import { createFsFromVolume, vol } from "memfs";
2-
import { createNpmSymlinks, getSubPackages, removeNpmPackage, runNpmInstall } from "../../../src/utils/npm";
2+
import {
3+
createNpmSymlinks,
4+
getSubPackages,
5+
removeNpmPackage,
6+
runNpmBuild,
7+
runNpmInstall,
8+
} from "../../../src/utils/npm";
39
import { tempDir, corePkg, fsRoot, twitchChatPkg, dashboardPkg } from "../../testUtils";
410
import * as fsUtils from "../../../src/utils/fs";
511
import * as path from "path";
612

713
jest.mock("fs", () => createFsFromVolume(vol));
814
afterEach(() => vol.reset());
915

16+
const npmCommand = "npm";
17+
const execMock = jest.spyOn(fsUtils, "executeCommand").mockResolvedValue();
18+
19+
afterEach(() => execMock.mockClear());
20+
1021
describe("runNpmInstall", () => {
11-
test("should execute npm install", async () => {
12-
const spy = jest.spyOn(fsUtils, "executeCommand").mockResolvedValue();
13-
await runNpmInstall(fsRoot);
14-
expect(spy).toHaveBeenCalled();
15-
expect(spy.mock.calls[0][0]).toBe("npm");
16-
expect(spy.mock.calls[0][1][0]).toBe("install");
22+
test("should execute npm install --prod when installing prod only", async () => {
23+
await runNpmInstall(fsRoot, true);
24+
expect(execMock).toHaveBeenCalled();
25+
expect(execMock.mock.calls[0][0]).toBe(npmCommand);
26+
expect(execMock.mock.calls[0][1][0]).toBe("install");
27+
expect(execMock.mock.calls[0][1][1]).toBe("--prod");
28+
expect(execMock.mock.calls[0][2]).toBe(fsRoot);
29+
});
30+
31+
test("should execute npm install when installing prod and dev", async () => {
32+
await runNpmInstall(fsRoot, false);
33+
expect(execMock).toHaveBeenCalled();
34+
expect(execMock.mock.calls[0][0]).toBe(npmCommand);
35+
expect(execMock.mock.calls[0][1][0]).toBe("install");
36+
expect(execMock.mock.calls[0][1].length).toBe(1);
37+
});
38+
});
39+
40+
describe("runNpmBuild", () => {
41+
test("should execute install script with passed arguments", async () => {
42+
await runNpmBuild(fsRoot, "arg");
43+
expect(execMock).toHaveBeenCalled();
44+
expect(execMock.mock.calls[0][0]).toBe(npmCommand);
45+
expect(execMock.mock.calls[0][1][1]).toBe("build");
46+
expect(execMock.mock.calls[0][1][2]).toBe("arg"); // Custom arg from above
1747
});
1848
});
1949

0 commit comments

Comments
 (0)