0
# Node.js Projects
1
2
Node.js projects with package management, testing frameworks, and JavaScript tooling. Provides comprehensive setup for Node.js applications and libraries with modern development tools.
3
4
## Capabilities
5
6
### NodeProject Class
7
8
Base Node.js project with npm/yarn package management and integrated tooling ecosystem.
9
10
```typescript { .api }
11
/**
12
* Node.js project with npm/yarn package management and tooling
13
* Base class for JavaScript and TypeScript projects
14
*/
15
class NodeProject extends GitHubProject {
16
constructor(options: NodeProjectOptions);
17
18
/** Package.json management */
19
readonly package: NodePackage;
20
/** Jest testing framework (if enabled) */
21
readonly jest?: Jest;
22
/** Prettier code formatting (if enabled) */
23
readonly prettier?: Prettier;
24
/** Biome linting and formatting (if enabled) */
25
readonly biome?: Biome;
26
/** Code bundling system (always available) */
27
readonly bundler: Bundler;
28
/** Dependency upgrade automation */
29
readonly upgradeWorkflow?: UpgradeDependencies;
30
/** Package manager type (npm, yarn, pnpm, bun) */
31
readonly packageManager: NodePackageManager;
32
/** Node.js version requirement */
33
readonly nodeVersion?: string;
34
/** Package installation command */
35
readonly installCommand: string;
36
/** Package run command prefix */
37
readonly runScriptCommand: string;
38
/** The .npmignore file */
39
readonly npmignore?: IgnoreFile;
40
/** The .npmrc file */
41
readonly npmrc: NpmConfig;
42
/** Component that sets up mergify for merging approved pull requests */
43
readonly autoMerge?: AutoMerge;
44
/** The PR build GitHub workflow */
45
readonly buildWorkflow?: BuildWorkflow;
46
/** Package publisher (deprecated - use release.publisher) */
47
readonly publisher?: Publisher;
48
/** Release management */
49
readonly release?: Release;
50
/** Minimum node version required by this package */
51
readonly minNodeVersion?: string;
52
/** Maximum node version supported by this package */
53
readonly maxNodeVersion?: string;
54
/** Build output directory for npm tarballs */
55
readonly artifactsDirectory: string;
56
/** Location of npm tarball after build */
57
readonly artifactsJavascriptDirectory: string;
58
/** Deprecated - use package.allowLibraryDependencies */
59
readonly allowLibraryDependencies: boolean;
60
/** Deprecated - use package.entrypoint */
61
readonly entrypoint: string;
62
/** Deprecated - use package.manifest */
63
readonly manifest: any;
64
65
/** Add binary executables to package.json */
66
addBins(bins: Record<string, string>): void;
67
/** Set npm script command */
68
setScript(name: string, command: string): void;
69
/** Add multiple npm scripts */
70
addScripts(scripts: Record<string, string>): void;
71
/** Remove npm script */
72
removeScript(name: string): void;
73
/** Check if script exists (deprecated) */
74
hasScript(name: string): boolean;
75
/** Add compile command (deprecated) */
76
addCompileCommand(...commands: string[]): void;
77
/** Add test command (deprecated) */
78
addTestCommand(...commands: string[]): void;
79
/** Set package.json fields directly */
80
addFields(fields: Record<string, any>): void;
81
/** Add keywords to package.json */
82
addKeywords(...keywords: string[]): void;
83
/** Add dependencies */
84
addDeps(...deps: string[]): void;
85
/** Add development dependencies */
86
addDevDeps(...deps: string[]): void;
87
/** Add peer dependencies */
88
addPeerDeps(...deps: string[]): void;
89
/** Add bundled dependencies */
90
addBundledDeps(...deps: string[]): void;
91
/** Add patterns to .npmignore */
92
addPackageIgnore(pattern: string): void;
93
/** Render workflow setup steps */
94
renderWorkflowSetup(options?: RenderWorkflowSetupOptions): JobStep[];
95
/** Get shell command to run a task */
96
runTaskCommand(task: Task): string;
97
/** The job ID of the build workflow */
98
readonly buildWorkflowJobId?: string;
99
}
100
101
interface NodeProjectOptions extends GitHubProjectOptions, NodePackageOptions, ReleaseProjectOptions {
102
/** License copyright owner */
103
copyrightOwner?: string;
104
/** Copyright years for LICENSE file */
105
copyrightPeriod?: string;
106
/** Projen version to install */
107
projenVersion?: string;
108
/** Install projen as devDependency */
109
projenDevDependency?: boolean;
110
111
/** Define GitHub workflow for building PRs */
112
buildWorkflow?: boolean;
113
/** Options for PR build workflow */
114
buildWorkflowOptions?: BuildWorkflowOptions;
115
/** Deprecated - use buildWorkflowOptions.mutableBuild */
116
mutableBuild?: boolean;
117
118
/** Enable codecov integration */
119
codeCov?: boolean;
120
/** Codecov token secret name */
121
codeCovTokenSecret?: string;
122
123
/** Deprecated - renamed to release */
124
releaseWorkflow?: boolean;
125
/** Add release management */
126
release?: boolean;
127
/** Main release branch name */
128
defaultReleaseBranch: string;
129
130
/** Workflow bootstrap steps */
131
workflowBootstrapSteps?: JobStep[];
132
/** Git identity for workflows */
133
workflowGitIdentity?: GitIdentity;
134
/** Automatically release to npm */
135
releaseToNpm?: boolean;
136
/** Node version for GitHub Actions workflows */
137
workflowNodeVersion?: string;
138
/** Enable package cache in workflows */
139
workflowPackageCache?: boolean;
140
141
/** Use dependabot for dependency upgrades */
142
dependabot?: boolean;
143
/** Dependabot options */
144
dependabotOptions?: DependabotOptions;
145
/** Use tasks/workflows for dependency upgrades */
146
depsUpgrade?: boolean;
147
/** Dependency upgrade options */
148
depsUpgradeOptions?: UpgradeDependenciesOptions;
149
/** Auto-approve deps upgrade PRs */
150
autoApproveUpgrades?: boolean;
151
152
/** Enable .npmignore file */
153
npmignoreEnabled?: boolean;
154
/** Configuration for .npmignore */
155
npmIgnoreOptions?: IgnoreFileOptions;
156
/** Deprecated - use project.addPackageIgnore */
157
npmignore?: string[];
158
159
/** Include GitHub pull request template */
160
pullRequestTemplate?: boolean;
161
/** Contents of pull request template */
162
pullRequestTemplateContents?: string[];
163
164
/** Setup Prettier */
165
prettier?: boolean;
166
/** Prettier options */
167
prettierOptions?: PrettierOptions;
168
169
/** Additional .gitignore entries */
170
gitignore?: string[];
171
172
/** Setup Jest unit tests */
173
jest?: boolean;
174
/** Jest options */
175
jestOptions?: JestOptions;
176
177
/** Generate .projenrc.js */
178
projenrcJs?: boolean;
179
/** Options for .projenrc.js */
180
projenrcJsOptions?: ProjenrcOptions;
181
182
/** Bundler options */
183
bundlerOptions?: BundlerOptions;
184
185
/** Build artifacts directory */
186
artifactsDirectory?: string;
187
/** Produce npm tarball */
188
package?: boolean;
189
190
/** Deprecated - use buildWorkflowOptions.workflowTriggers */
191
buildWorkflowTriggers?: Triggers;
192
193
/** License checker configuration */
194
checkLicenses?: LicenseCheckerOptions;
195
196
/** Setup Biome */
197
biome?: boolean;
198
/** Biome options */
199
biomeOptions?: BiomeOptions;
200
}
201
202
enum NodePackageManager {
203
NPM = "npm",
204
YARN = "yarn",
205
YARN_CLASSIC = "yarn_classic",
206
YARN2 = "yarn2",
207
YARN_BERRY = "yarn_berry",
208
PNPM = "pnpm",
209
BUN = "bun"
210
}
211
212
enum AutoRelease {
213
/** Automatically bump & release for every commit to main */
214
EVERY_COMMIT = "every-commit",
215
/** Automatically bump & release on a daily basis */
216
DAILY = "daily"
217
}
218
219
interface BuildWorkflowOptions extends BuildWorkflowCommonOptions {
220
/** Update files during builds to PR branches */
221
mutableBuild?: boolean;
222
}
223
224
interface RenderWorkflowSetupOptions {
225
/** Configure install step in workflow setup */
226
installStepConfiguration?: JobStepConfiguration;
227
/** Should package lockfile be updated */
228
mutable?: boolean;
229
}
230
```
231
232
**Basic Node.js Project Example:**
233
234
```typescript
235
import { NodeProject, NodePackageManager } from "projen";
236
237
const project = new NodeProject({
238
name: "my-node-app",
239
defaultReleaseBranch: "main",
240
241
// Package information
242
description: "My awesome Node.js application",
243
keywords: ["nodejs", "api", "express"],
244
license: "MIT",
245
author: "Jane Developer",
246
authorEmail: "jane@example.com",
247
248
// Package manager
249
packageManager: NodePackageManager.YARN,
250
nodeVersion: ">=16.0.0",
251
252
// Dependencies
253
deps: [
254
"express@^4.18.0",
255
"cors@^2.8.5",
256
"helmet@^6.0.0",
257
],
258
devDeps: [
259
"@types/express",
260
"@types/cors",
261
"nodemon",
262
],
263
264
// Tooling
265
jest: true,
266
prettier: true,
267
});
268
269
// Add custom scripts
270
project.package.addScript("start", "node dist/index.js");
271
project.package.addScript("dev", "nodemon src/index.js");
272
project.package.addScript("build", "echo 'No build step for plain JS'");
273
```
274
275
### Jest Testing Framework
276
277
Comprehensive testing setup with Jest including coverage and reporting.
278
279
```typescript { .api }
280
/**
281
* Jest testing framework configuration
282
* Provides unit testing, integration testing, and coverage reporting
283
*/
284
class Jest extends Component {
285
constructor(project: NodeProject, options?: JestOptions);
286
287
/** Jest configuration object */
288
readonly config: any;
289
/** Test task */
290
readonly testTask: Task;
291
/** Watch test task */
292
readonly watchTask: Task;
293
/** Coverage task */
294
readonly coverageTask: Task;
295
/** Jest configuration file */
296
readonly file: JsonFile;
297
298
/** Add Jest configuration */
299
addConfig(key: string, value: any): void;
300
/** Add test pattern */
301
addTestMatch(pattern: string): void;
302
/** Add setup file */
303
addSetupFile(file: string): void;
304
/** Add setup file after environment */
305
addSetupFilesAfterEnv(file: string): void;
306
/** Add module name mapping */
307
addModuleNameMapping(pattern: string, replacement: string): void;
308
/** Add ignore pattern */
309
addIgnorePattern(pattern: string): void;
310
/** Add watch path ignore pattern */
311
addWatchIgnorePattern(pattern: string): void;
312
/** Add reporter */
313
addReporter(reporter: JestReporter | string): void;
314
/** Add transform */
315
addTransform(pattern: string, transformer: string | Transform): void;
316
/** Add test environment option */
317
addTestEnvironmentOptions(key: string, value: any): void;
318
/** Discover test match patterns for directories */
319
static discoverTestMatchPatternsForDirs(dirs: string[], options?: JestDiscoverTestMatchPatternsForDirsOptions): string[];
320
}
321
322
interface JestOptions {
323
/** Jest version */
324
jestVersion?: string;
325
/** Jest configuration object */
326
jestConfig?: JestConfigOptions;
327
/** Preserve default Jest reporter when additional reporters are added */
328
preserveDefaultReporters?: boolean;
329
/** Ignore patterns for Jest */
330
ignorePatterns?: string[];
331
/** Update snapshot behavior */
332
updateSnapshot?: UpdateSnapshot;
333
/** CI environment settings */
334
ci?: boolean;
335
/** Coverage collection */
336
coverage?: boolean;
337
/** Maximum worker threads */
338
maxWorkers?: string;
339
/** Extra CLI options */
340
extraCliOptions?: string[];
341
}
342
343
interface JestConfigOptions {
344
/** Automatically clear mock calls and instances */
345
clearMocks?: boolean;
346
/** Coverage collection enabled */
347
collectCoverage?: boolean;
348
/** Paths from which to collect coverage */
349
collectCoverageFrom?: string[];
350
/** Coverage directory */
351
coverageDirectory?: string;
352
/** Coverage path ignore patterns */
353
coveragePathIgnorePatterns?: string[];
354
/** Coverage reporters */
355
coverageReporters?: string[];
356
/** Coverage threshold */
357
coverageThreshold?: CoverageThreshold;
358
/** Display name for the test */
359
displayName?: string | { name: string; color: string };
360
/** Error on deprecated features */
361
errorOnDeprecated?: boolean;
362
/** Force coverage collection from ignored files */
363
forceCoverageMatch?: string[];
364
/** Global setup module */
365
globalSetup?: string;
366
/** Global teardown module */
367
globalTeardown?: string;
368
/** Global variables */
369
globals?: Record<string, any>;
370
/** Haste configuration */
371
haste?: HasteConfig;
372
/** Maximum number of concurrent workers */
373
maxWorkers?: number | string;
374
/** Module directories */
375
moduleDirectories?: string[];
376
/** Module file extensions */
377
moduleFileExtensions?: string[];
378
/** Module name mapper */
379
moduleNameMapper?: Record<string, string>;
380
/** Module paths */
381
modulePaths?: string[];
382
/** Notify of test results */
383
notify?: boolean;
384
/** Preset configuration */
385
preset?: string;
386
/** Prettier path */
387
prettierPath?: string;
388
/** Projects configuration */
389
projects?: string[];
390
/** Reporters configuration */
391
reporters?: (string | JestReporter)[];
392
/** Reset mocks between tests */
393
resetMocks?: boolean;
394
/** Reset modules between tests */
395
resetModules?: boolean;
396
/** Restore mocks between tests */
397
restoreMocks?: boolean;
398
/** Root directory */
399
rootDir?: string;
400
/** Additional root directories */
401
roots?: string[];
402
/** Setup files */
403
setupFiles?: string[];
404
/** Setup files after environment */
405
setupFilesAfterEnv?: string[];
406
/** Snapshot serializers */
407
snapshotSerializers?: string[];
408
/** Test environment */
409
testEnvironment?: string;
410
/** Test environment options */
411
testEnvironmentOptions?: Record<string, any>;
412
/** Test match patterns */
413
testMatch?: string[];
414
/** Test path ignore patterns */
415
testPathIgnorePatterns?: string[];
416
/** Test results processor */
417
testResultsProcessor?: string;
418
/** Test runner */
419
testRunner?: string;
420
/** Test timeout */
421
testTimeout?: number;
422
/** Transform configuration */
423
transform?: Record<string, string | Transform>;
424
/** Transform ignore patterns */
425
transformIgnorePatterns?: string[];
426
/** Unmocked module path patterns */
427
unmockedModulePathPatterns?: string[];
428
/** Verbose output */
429
verbose?: boolean;
430
/** Watch path ignore patterns */
431
watchPathIgnorePatterns?: string[];
432
}
433
434
class Transform {
435
constructor(transformer: string, options?: Record<string, any>);
436
437
/** Transform file path */
438
readonly file: string;
439
/** Transform options */
440
readonly options?: Record<string, any>;
441
}
442
443
class WatchPlugin {
444
constructor(plugin: string, options?: Record<string, any>);
445
446
/** Watch plugin file path */
447
readonly file: string;
448
/** Watch plugin options */
449
readonly options?: Record<string, any>;
450
}
451
452
interface JestDiscoverTestMatchPatternsForDirsOptions {
453
/** File extensions to include */
454
fileExtensions?: string[];
455
}
456
457
enum UpdateSnapshot {
458
NEVER = "never",
459
NEW = "new",
460
ALL = "all"
461
}
462
463
interface HasteConfig {
464
/** Enable Haste module system */
465
enableSymlinks?: boolean;
466
/** Force node filesystem API */
467
forceNodeFilesystemAPI?: boolean;
468
/** Haste implementation module path */
469
hasteImplModulePath?: string;
470
/** Platforms supported by Haste */
471
platforms?: string[];
472
/** Throw on missing module */
473
throwOnModuleCollision?: boolean;
474
}
475
476
class JestReporter {
477
constructor(reporter: string, options?: Record<string, any>);
478
479
/** Reporter file path */
480
readonly file: string;
481
/** Reporter options */
482
readonly options?: Record<string, any>;
483
}
484
485
interface CoverageThreshold {
486
global?: {
487
branches?: number;
488
functions?: number;
489
lines?: number;
490
statements?: number;
491
};
492
}
493
```
494
495
**Jest Configuration Example:**
496
497
```typescript
498
import { NodeProject } from "projen";
499
500
const project = new NodeProject({
501
name: "jest-example",
502
jest: true,
503
jestOptions: {
504
jestConfig: {
505
testMatch: [
506
"<rootDir>/src/**/__tests__/**/*.ts",
507
"<rootDir>/src/**/*.test.ts",
508
],
509
collectCoverage: true,
510
coverageDirectory: "coverage",
511
coverageReporters: ["text", "lcov", "html"],
512
coverageThreshold: {
513
global: {
514
branches: 80,
515
functions: 80,
516
lines: 80,
517
statements: 80,
518
},
519
},
520
testEnvironment: "node",
521
},
522
},
523
});
524
525
// Customize Jest configuration
526
if (project.jest) {
527
project.jest.addSetupFilesAfterEnv("<rootDir>/test/setup.js");
528
project.jest.addModuleNameMapping("^@/(.*)$", "<rootDir>/src/$1");
529
}
530
```
531
532
### Prettier Formatting
533
534
Prettier code formatting with customizable style rules.
535
536
```typescript { .api }
537
/**
538
* Prettier code formatting configuration
539
* Ensures consistent code style across the project
540
*/
541
class Prettier extends Component {
542
static of(project: Project): Prettier | undefined;
543
544
constructor(project: NodeProject, options?: PrettierOptions);
545
546
/** Prettier configuration file */
547
readonly file: JsonFile;
548
/** Prettier ignore file */
549
readonly ignoreFile: IgnoreFile;
550
/** Prettier configuration object */
551
readonly config: PrettierSettings;
552
/** Format task */
553
readonly formatTask: Task;
554
555
/** Add Prettier configuration */
556
addConfig(key: string, value: any): void;
557
/** Add ignore pattern */
558
addIgnorePattern(pattern: string): void;
559
/** Add prettier override */
560
addOverride(override: PrettierOverride): void;
561
}
562
563
interface PrettierOptions {
564
/** Prettier settings */
565
settings?: PrettierSettings;
566
/** Ignore patterns */
567
ignorePatterns?: string[];
568
/** Prettier overrides */
569
overrides?: PrettierOverride[];
570
/** Write prettier configuration as YAML */
571
yaml?: boolean;
572
}
573
574
interface PrettierSettings {
575
/** Print width */
576
printWidth?: number;
577
/** Tab width */
578
tabWidth?: number;
579
/** Use tabs instead of spaces */
580
useTabs?: boolean;
581
/** Semicolons */
582
semi?: boolean;
583
/** Single quotes */
584
singleQuote?: boolean;
585
/** Quote properties */
586
quoteProps?: QuoteProps;
587
/** Trailing commas */
588
trailingComma?: TrailingComma;
589
/** Bracket spacing */
590
bracketSpacing?: boolean;
591
/** Arrow function parentheses */
592
arrowParens?: ArrowParens;
593
/** Bracket same line */
594
bracketSameLine?: boolean;
595
/** Embedded language formatting */
596
embeddedLanguageFormatting?: EmbeddedLanguageFormatting;
597
/** HTML whitespace sensitivity */
598
htmlWhitespaceSensitivity?: HTMLWhitespaceSensitivity;
599
/** Insert pragma */
600
insertPragma?: boolean;
601
/** JSX single quote */
602
jsxSingleQuote?: boolean;
603
/** Parser to use */
604
parser?: string;
605
/** Prose wrap */
606
proseWrap?: ProseWrap;
607
/** Range end */
608
rangeEnd?: number;
609
/** Range start */
610
rangeStart?: number;
611
/** Require pragma */
612
requirePragma?: boolean;
613
/** Vue indent script and style */
614
vueIndentScriptAndStyle?: boolean;
615
/** Line ending */
616
endOfLine?: EndOfLine;
617
}
618
619
interface PrettierOverride {
620
/** Files to apply override to */
621
files: string[];
622
/** Excluded files */
623
excludeFiles?: string[];
624
/** Override options */
625
options?: PrettierSettings;
626
}
627
628
enum ArrowParens {
629
ALWAYS = "always",
630
AVOID = "avoid"
631
}
632
633
enum EmbeddedLanguageFormatting {
634
AUTO = "auto",
635
OFF = "off"
636
}
637
638
enum EndOfLine {
639
AUTO = "auto",
640
LF = "lf",
641
CRLF = "crlf",
642
CR = "cr"
643
}
644
645
enum HTMLWhitespaceSensitivity {
646
CSS = "css",
647
STRICT = "strict",
648
IGNORE = "ignore"
649
}
650
651
enum ProseWrap {
652
ALWAYS = "always",
653
NEVER = "never",
654
PRESERVE = "preserve"
655
}
656
657
enum QuoteProps {
658
AS_NEEDED = "as-needed",
659
CONSISTENT = "consistent",
660
PRESERVE = "preserve"
661
}
662
663
enum TrailingComma {
664
NONE = "none",
665
ES5 = "es5",
666
ALL = "all"
667
}
668
```
669
670
### Biome Integration
671
672
Biome is an alternative to ESLint and Prettier that provides fast linting and formatting.
673
674
```typescript { .api }
675
/**
676
* Biome linting and formatting configuration
677
* Fast alternative to ESLint + Prettier
678
*/
679
class Biome extends Component {
680
static of(project: Project): Biome | undefined;
681
682
constructor(project: NodeProject, options?: BiomeOptions);
683
684
/** Biome configuration file */
685
readonly file: JsonFile;
686
/** Biome configuration object */
687
readonly config: BiomeConfiguration;
688
/** Check task for linting */
689
readonly checkTask: Task;
690
/** Format task for formatting */
691
readonly formatTask: Task;
692
693
/** Add configuration to Biome */
694
addConfig(config: Partial<BiomeConfiguration>): void;
695
/** Add ignore pattern */
696
addIgnorePattern(pattern: string): void;
697
}
698
699
interface BiomeOptions {
700
/** Biome configuration */
701
config?: Partial<BiomeConfiguration>;
702
/** Biome version */
703
version?: string;
704
}
705
706
interface BiomeConfiguration {
707
/** Schema reference */
708
$schema?: string;
709
/** Organize imports settings */
710
organizeImports?: { enabled?: boolean };
711
/** Linter configuration */
712
linter?: LinterConfiguration;
713
/** Formatter configuration */
714
formatter?: FormatterConfiguration;
715
/** JavaScript configuration */
716
javascript?: JsConfiguration;
717
/** Files configuration */
718
files?: FilesConfiguration;
719
/** JSON configuration */
720
json?: JsonConfiguration;
721
/** CSS configuration */
722
css?: CssConfiguration;
723
/** VCS configuration */
724
vcs?: VcsConfiguration;
725
}
726
```
727
728
### Code Bundling
729
730
Code bundling with esbuild for Node.js projects.
731
732
```typescript { .api }
733
/**
734
* Code bundling system for Node.js projects
735
* Supports esbuild for fast bundling
736
*/
737
class Bundler extends Component {
738
constructor(project: NodeProject, options?: BundlerOptions);
739
740
/** Bundle task */
741
readonly bundleTask: Task;
742
/** Watch bundle task */
743
readonly watchTask?: Task;
744
/** Pre-bundle task */
745
readonly preBundleTask: Task;
746
/** Post-bundle task */
747
readonly postBundleTask: Task;
748
/** Available bundles */
749
readonly bundles: Bundle[];
750
751
/** Add bundle configuration */
752
addBundle(bundleId: string, options: AddBundleOptions): Bundle;
753
/** Execute bundle with options */
754
executeBundle(bundleId: string, options: BundlingOptions): void;
755
}
756
757
interface BundlerOptions {
758
/** Add bundle for project itself */
759
addToPreBundleTask?: boolean;
760
}
761
762
interface Bundle {
763
/** Bundle identifier */
764
readonly bundleid: string;
765
/** Entry point file */
766
readonly entrypoint: string;
767
/** Output directory */
768
readonly outdir: string;
769
/** External modules */
770
readonly externals: string[];
771
/** Runtime dependencies to bundle */
772
readonly runtimeDependencies?: string[];
773
}
774
775
interface BundlingOptions {
776
/** Entry point file */
777
entrypoint: string;
778
/** Output directory */
779
outdir: string;
780
/** External modules not to bundle */
781
externals?: string[];
782
/** Runtime dependencies to include */
783
runtimeDependencies?: string[];
784
/** Bundle executable files */
785
executable?: boolean;
786
/** Watch mode */
787
watch?: boolean;
788
/** Preserve symlinks */
789
preserveSymlinks?: boolean;
790
/** TSConfig file to use */
791
tsconfig?: string;
792
/** Loader configuration */
793
loaders?: Record<string, string>;
794
/** Log level */
795
logLevel?: BundleLogLevel;
796
/** Keep names for functions and classes */
797
keepNames?: boolean;
798
/** Source map mode */
799
sourcemap?: SourceMapMode;
800
/** Source root */
801
sourcesContent?: boolean;
802
/** Banner text */
803
banner?: string;
804
/** Footer text */
805
footer?: string;
806
/** Character set */
807
charset?: Charset;
808
/** Minify output */
809
minify?: boolean;
810
/** Target environment */
811
target?: string;
812
/** Platform target */
813
platform?: string;
814
/** Main fields for resolution */
815
mainFields?: string[];
816
/** Conditions for resolution */
817
conditions?: string[];
818
/** Define constants */
819
define?: Record<string, string>;
820
/** Tree shaking */
821
treeShaking?: boolean;
822
/** Code splitting */
823
splitting?: boolean;
824
/** Output format */
825
format?: string;
826
/** Asset names */
827
assetNames?: string;
828
/** Chunk names */
829
chunkNames?: string;
830
/** Entry names */
831
entryNames?: string;
832
/** Inject code */
833
inject?: string[];
834
/** Esbuild version */
835
esbuildVersion?: string;
836
/** Docker image for bundling */
837
dockerImage?: string;
838
}
839
840
interface AddBundleOptions extends BundlingOptions {
841
/** When to run the bundle task */
842
runBundleTask?: RunBundleTask;
843
}
844
845
enum RunBundleTask {
846
/** Run during pre-bundle phase */
847
PRE_BUNDLE = "pre-bundle",
848
/** Run during post-bundle phase */
849
POST_BUNDLE = "post-bundle",
850
/** Run manually */
851
MANUAL = "manual"
852
}
853
854
enum SourceMapMode {
855
DEFAULT = "default",
856
EXTERNAL = "external",
857
INLINE = "inline",
858
BOTH = "both"
859
}
860
861
enum Charset {
862
ASCII = "ascii",
863
UTF8 = "utf8"
864
}
865
866
enum BundleLogLevel {
867
SILENT = "silent",
868
ERROR = "error",
869
WARNING = "warning",
870
INFO = "info",
871
DEBUG = "debug",
872
VERBOSE = "verbose"
873
}
874
```
875
876
**Complete Node.js Project Example:**
877
878
```typescript
879
import { NodeProject, NodePackageManager } from "projen";
880
881
const project = new NodeProject({
882
name: "complete-node-project",
883
defaultReleaseBranch: "main",
884
885
// Project metadata
886
description: "A complete Node.js project with all features",
887
keywords: ["nodejs", "typescript", "api"],
888
license: "Apache-2.0",
889
author: "Development Team",
890
authorEmail: "dev@company.com",
891
repository: "https://github.com/company/complete-node-project.git",
892
893
// Package manager and Node version
894
packageManager: NodePackageManager.YARN,
895
nodeVersion: ">=18.0.0",
896
897
// Dependencies
898
deps: [
899
"express@^4.18.0",
900
"cors@^2.8.5",
901
"helmet@^6.0.0",
902
"dotenv@^16.0.0",
903
],
904
devDeps: [
905
"@types/express",
906
"@types/cors",
907
"nodemon",
908
"supertest",
909
"@types/supertest",
910
],
911
912
// Testing with Jest
913
jest: true,
914
jestOptions: {
915
jestConfig: {
916
collectCoverage: true,
917
coverageDirectory: "coverage",
918
testEnvironment: "node",
919
setupFilesAfterEnv: ["<rootDir>/test/setup.js"],
920
},
921
},
922
923
// Formatting with Prettier
924
prettier: true,
925
prettierOptions: {
926
settings: {
927
singleQuote: true,
928
trailingComma: TrailingComma.ES5,
929
tabWidth: 2,
930
},
931
},
932
933
// Bundling
934
bundlerOptions: {
935
addToPreBundleTask: true,
936
},
937
938
// Dependency upgrades
939
depsUpgrade: true,
940
});
941
942
// Add custom bundle
943
project.bundler.addBundle("api", {
944
entrypoint: "src/index.js",
945
outdir: "dist",
946
format: "cjs",
947
minify: true,
948
platform: "node",
949
});
950
951
// Custom tasks
952
project.addTask("start:dev", {
953
description: "Start development server",
954
exec: "nodemon src/index.js",
955
});
956
957
project.addTask("start:prod", {
958
description: "Start production server",
959
exec: "node dist/index.js",
960
});
961
962
// Custom package.json fields
963
project.package.addField("engines", {
964
node: ">=18.0.0",
965
yarn: ">=1.22.0",
966
});
967
968
project.package.addScript("docker:build", "docker build -t my-app .");
969
project.package.addScript("docker:run", "docker run -p 3000:3000 my-app");
970
```
971
972
## Types
973
974
### Node.js-Specific Types
975
976
```typescript { .api }
977
/** License checker for dependency licenses */
978
class LicenseChecker extends Component {
979
constructor(project: NodeProject, options: LicenseCheckerOptions);
980
981
/** License check task */
982
readonly task: Task;
983
}
984
985
interface LicenseCheckerOptions {
986
/** Allowed SPDX license identifiers */
987
allow?: string[];
988
/** Prohibited SPDX license identifiers */
989
deny?: string[];
990
/** Check production dependencies only */
991
production?: boolean;
992
/** Path to output file */
993
outputFile?: string;
994
}
995
996
/** Upgrade dependencies automation */
997
class UpgradeDependencies extends Component {
998
constructor(project: NodeProject, options?: UpgradeDependenciesOptions);
999
1000
/** Upgrade workflow */
1001
readonly workflow?: GitHubWorkflow;
1002
/** Upgrade task */
1003
readonly upgradeTask: Task;
1004
/** List of container images that will be upgraded */
1005
readonly containerImages: string[];
1006
1007
/** Add package to exclude from upgrades */
1008
addExclude(...packageNames: string[]): void;
1009
/** Add package to include in upgrades */
1010
addInclude(...packageNames: string[]): void;
1011
}
1012
1013
interface UpgradeDependenciesOptions {
1014
/** Include package names to upgrade */
1015
include?: string[];
1016
/** Exclude package names from upgrade */
1017
exclude?: string[];
1018
/** Workflow options */
1019
workflowOptions?: UpgradeDependenciesWorkflowOptions;
1020
/** Upgrade schedule */
1021
scheduleOptions?: UpgradeDependenciesScheduleOptions;
1022
/** Task step options */
1023
taskStepOptions?: TaskStepOptions;
1024
/** Target branch for pull requests */
1025
target?: string;
1026
/** Create a GitHub issue when upgrade fails */
1027
createGitHubIssue?: boolean;
1028
/** Labels for issues created on upgrade failure */
1029
gitHubIssueLabels?: string[];
1030
/** Title for pull requests */
1031
pullRequestTitle?: string;
1032
/** Semantic commit type for commits */
1033
semanticCommit?: string;
1034
/** Exclude packages matching these patterns */
1035
ignorePatterns?: string[];
1036
/** Include prerelease versions */
1037
includePrereleases?: boolean;
1038
}
1039
1040
/** NPM configuration file (.npmrc) */
1041
class NpmConfig extends Component {
1042
constructor(project: NodeProject, options?: NpmConfigOptions);
1043
1044
/** Add configuration entry */
1045
addConfig(name: string, value: string): void;
1046
/** Add registry configuration */
1047
addRegistry(url: string, scope?: string): void;
1048
}
1049
1050
interface NpmConfigOptions {
1051
/** Omit empty values */
1052
omitEmpty?: boolean;
1053
}
1054
1055
interface PackageJson {
1056
name: string;
1057
version: string;
1058
description?: string;
1059
main?: string;
1060
scripts?: Record<string, string>;
1061
dependencies?: Record<string, string>;
1062
devDependencies?: Record<string, string>;
1063
peerDependencies?: Record<string, string>;
1064
optionalDependencies?: Record<string, string>;
1065
bundledDependencies?: string[];
1066
keywords?: string[];
1067
author?: string | AuthorInfo;
1068
license?: string;
1069
repository?: string | RepositoryInfo;
1070
bugs?: string | BugsInfo;
1071
homepage?: string;
1072
engines?: Record<string, string>;
1073
}
1074
1075
interface AuthorInfo {
1076
name: string;
1077
email?: string;
1078
url?: string;
1079
}
1080
1081
interface RepositoryInfo {
1082
type: string;
1083
url: string;
1084
directory?: string;
1085
}
1086
1087
interface BugsInfo {
1088
url?: string;
1089
email?: string;
1090
}
1091
```