TypeScript Projects
The TypeScript project generator can be used to create a modern TypeScript library or application configured with best practices such as ECMAScript Modules (ESM), TypeScript project references, Vitest for running tests and ESLint for static analysis.
Generate a TypeScript Project
Section titled “Generate a TypeScript Project”You can generate a new TypeScript project in two ways:
- Install the Nx Console VSCode Plugin if you haven't already
- Open the Nx Console in VSCode
- Click
Generate (UI)in the "Common Nx Commands" section - Search for
@aws/nx-plugin - ts#project - Fill in the required parameters
- Click
Generate
pnpm nx g @aws/nx-plugin:ts#projectyarn nx g @aws/nx-plugin:ts#projectnpx nx g @aws/nx-plugin:ts#projectbunx nx g @aws/nx-plugin:ts#projectYou can also perform a dry-run to see what files would be changed
pnpm nx g @aws/nx-plugin:ts#project --dry-runyarn nx g @aws/nx-plugin:ts#project --dry-runnpx nx g @aws/nx-plugin:ts#project --dry-runbunx nx g @aws/nx-plugin:ts#project --dry-runOptions
Section titled “Options”| Parameter | Type | Default | Description |
|---|---|---|---|
| name Required | string | - | TypeScript project name |
| directory | string | packages | Parent directory where the library is placed. |
| subDirectory | string | - | The sub directory the lib is placed in. By default this is the library name. |
Generator Output
Section titled “Generator Output”The generator will create the following project structure in the <directory>/<name> directory:
Directorysrc TypeScript source code
- index.ts
- project.json Project configuration and build targets
- tsconfig.json Base TypeScript configuration for this project (extends workspace root tsconfig.base.json)
- tsconfig.lib.json TypeScript configuration for your library (your runtime or packaged source)
- tsconfig.spec.json TypeScript configuration for your tests
- vite.config.ts Configuration for Vitest
- eslint.config.mjs Configuration for ESLint
You will also notice some changes to the following files in your workspace root:
- nx.json Nx configuration is updated to configure the @nx/js/typescript plugin for your project
- tsconfig.base.json a TypeScript alias is set up for your project so that it can be imported by other projects in your workspace
- tsconfig.json a TypeScript project reference is added for your project
Writing TypeScript Source Code
Section titled “Writing TypeScript Source Code”Add your TypeScript code in the src directory.
ESM Import Syntax
Section titled “ESM Import Syntax”Since your TypeScript project is an ES Module, be sure to write your import statements with the correct ESM syntax, explicitly referencing the file extension:
import { sayHello } from './hello.js';Exporting for Other TypeScript Projects
Section titled “Exporting for Other TypeScript Projects”The entry point for your TypeScript project is src/index.ts. You can add exports here for anything you’d like other projects to be able to import:
export { sayHello } from './hello.js';export * from './algorithms/index.js';Importing your Library Code in Other Projects
Section titled “Importing your Library Code in Other Projects”TypeScript aliases for your project are configured in your workspace tsconfig.base.json, which allows you to reference your TypeScript project from other TypeScript projects:
import { sayHello } from ':my-scope/my-library';When you add an import statement for a new project in your workspace for the first time, you will likely see an error in your IDE similar to the below:
Import error
File '/path/to/my/workspace/packages/my-library/src/index.ts' is not under 'rootDir' '/path/to/my/workspace/packages/my-consumer'. 'rootDir' is expected to contain all source files. File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6059)File '/path/to/my/workspace/packages/my-library/src/index.ts' is not listed within the file list of project '/path/to/my/workspace/packages/my-consumer/tsconfig.lib.json'. Projects must list all files or use an 'include' pattern. File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6307)This is because a project reference has not yet been set up.
TypeScript projects are configured with the Nx TypeScript Sync generator out of the box, saving you from needing to manually configure the project reference. Simply run the following command and Nx will add the required configuration:
pnpm nx syncyarn nx syncnpx nx syncbunx nx syncAfter this, the error in your IDE should be gone and you are ready to use your library.
Dependencies
Section titled “Dependencies”You will notice that your TypeScript project does not have a package.json file, which might be unexpected if you are used to traditional TypeScript monorepos.
To add a dependency for any TypeScript package in your monorepo, simply add the dependency to the package.json in the root of your workspace. You can do this via the command line for your package manager:
pnpm add -w some-npm-packageyarn add some-npm-packagenpm install --legacy-peer-deps some-npm-packagebun install some-npm-packageThe dependency is then available for any of the TypeScript projects in your workspace to use.
Runtime Code
Section titled “Runtime Code”When you use your TypeScript project as runtime code (for example as the handler for an AWS Lambda function), it’s recommended that you use a tool such as Rolldown to bundle your project, since this can tree-shake to ensure that only the dependencies your project actually references are included.
You can achieve this by adding a target such as the following to your project.json file:
{ ... "targets": { ... "bundle": { "cache": true, "executor": "nx:run-commands", "outputs": ["{workspaceRoot}/dist/packages/my-library/bundle"], "options": { "command": "rolldown -c rolldown.config.ts" } }, },}And adding the rolldown.config.ts file as follows:
import { defineConfig } from 'rolldown';
export default defineConfig([ { input: 'src/index.ts', output: { file: '../../dist/packages/my-library/bundle/index.js', format: 'cjs', inlineDynamicImports: true, }, },]);Publishing to NPM
Section titled “Publishing to NPM”If you are publishing your TypeScript project to NPM, you must create a package.json file for it.
This must declare the dependencies that your project references. Since at build time your project will resolve dependencies installed via the workspace root package.json, it’s recommended to configure the Nx Dependency Checks ESLint Plugin to ensure that your published project’s package.json includes all dependencies you use in your project.
Building
Section titled “Building”Your TypeScript project is configured with a build target (defined in project.json), which you can run via:
pnpm nx run <project-name>:buildyarn nx run <project-name>:buildnpx nx run <project-name>:buildbunx nx run <project-name>:buildWhere <project-name> is the fully qualified name of your project.
The build target will compile, lint and test your project.
Build output can be found in the root dist folder in your workspace, inside a directory for your package and target, for example dist/packages/<my-library>/tsc
Testing
Section titled “Testing”Vitest is configured for testing your project.
Writing Tests
Section titled “Writing Tests”Tests should be written in .spec.ts or .test.ts files, co-located in your project’s src folder.
For example:
Directorysrc
- hello.ts Library source code
- hello.spec.ts Tests for hello.ts
Vitest provides Jest-like syntax for defining tests, with utilities such as describe, it, test and expect.
import { sayHello } from './hello.js';
describe('sayHello', () => {
it('should greet the caller', () => { expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!'); });
});For more details about how to write tests, and features such as mocking dependencies, refer to the Vitest documentation
Running Tests
Section titled “Running Tests”Tests will run as part of the build target for your project, but you can also run them separately by running the test target:
pnpm nx run <project-name>:testyarn nx run <project-name>:testnpx nx run <project-name>:testbunx nx run <project-name>:testYou can run an individual test or suite of tests using the -t flag:
pnpm nx run <project-name>:test -t 'sayHello'yarn nx run <project-name>:test -t 'sayHello'npx nx run <project-name>:test -t 'sayHello'bunx nx run <project-name>:test -t 'sayHello'Linting
Section titled “Linting”TypeScript projects use ESLint for linting, along with Prettier for formatting.
We recommend configuring ESLint in the workspace root eslint.config.mjs file, as changes to this will apply to all TypeScript projects in your workspace and ensure consistency.
Likewise, you can configure Prettier in the root .prettierrc file.
Running the Linter
Section titled “Running the Linter”To invoke the linter to check your project, you can run the lint target.
pnpm nx run <project-name>:lintyarn nx run <project-name>:lintnpx nx run <project-name>:lintbunx nx run <project-name>:lintFixing Lint Issues
Section titled “Fixing Lint Issues”The majority of linting or formatting issues can be fixed automatically. You can tell ESLint to fix lint issues by running with the --configuration=fix argument.
pnpm nx run <project-name>:lint --configuration=fixyarn nx run <project-name>:lint --configuration=fixnpx nx run <project-name>:lint --configuration=fixbunx nx run <project-name>:lint --configuration=fixSimilarly if you would like to fix all lint issues in all packages in your workspace, you can run:
pnpm nx run-many --target lint --all --configuration=fixyarn nx run-many --target lint --all --configuration=fixnpx nx run-many --target lint --all --configuration=fixbunx nx run-many --target lint --all --configuration=fix