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.
Usage
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#project
yarn nx g @aws/nx-plugin:ts#project
npx nx g @aws/nx-plugin:ts#project
bunx nx g @aws/nx-plugin:ts#project
You can also perform a dry-run to see what files would be changed
pnpm nx g @aws/nx-plugin:ts#project --dry-run
yarn nx g @aws/nx-plugin:ts#project --dry-run
npx nx g @aws/nx-plugin:ts#project --dry-run
bunx nx g @aws/nx-plugin:ts#project --dry-run
Options
Parameter | Type | Default | Description |
---|---|---|---|
name required | string | - | Library 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
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
Add your TypeScript code in the src
directory.
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
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
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 sync
yarn nx sync
npx nx sync
bunx nx sync
After this, the error in your IDE should be gone and you are ready to use your library.
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-package
yarn add some-npm-package
npm install --legacy-peer-deps some-npm-package
bun install some-npm-package
The dependency is then available for any of the TypeScript projects in your workspace to use.
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 esbuild
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": "esbuild packages/my-library/src/index.ts --bundle --outfile=dist/packages/my-library/bundle/index.js --platform=node --format=cjs" } }, },}
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
Your TypeScript project is configured with a build
target (defined in project.json
), which you can run via:
pnpm nx run <project-name>:build
yarn nx run <project-name>:build
npx nx run <project-name>:build
bunx nx run <project-name>:build
Where <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
Vitest is configured for testing your project.
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
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>:test
yarn nx run <project-name>:test
npx nx run <project-name>:test
bunx nx run <project-name>:test
You 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
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
To invoke the linter to check your project, you can run the lint
target.
pnpm nx run <project-name>:lint
yarn nx run <project-name>:lint
npx nx run <project-name>:lint
bunx nx run <project-name>:lint
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=fix
yarn nx run <project-name>:lint --configuration=fix
npx nx run <project-name>:lint --configuration=fix
bunx nx run <project-name>:lint --configuration=fix
Similarly 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=fix
yarn nx run-many --target lint --all --configuration=fix
npx nx run-many --target lint --all --configuration=fix
bunx nx run-many --target lint --all --configuration=fix