Setting up a TypeScript project
To use TypeScript in our projects, we'll need the following prerequisites:
npm install --save-dev typescript
TypeScript can be a development dependency in our project, as shown above. There's no need to pollute the production environment or the system's global repository with TypeScript.
A build script invoking
tscand a correctly specified
mainentry point defined in the
package.json(pointing to the built code):
Type declarations for NodeJS, so we can take advantage of type-checking in all the features we'll use:
npm install --save-dev @types/node
TypeScript configuration file allowing
tscto understand the project layout and the features used in the project:
We are extending the
@apify/tsconfig, it contains the set of rules we believe are worth following.
To be able to use feature called Top level await, we will need to set the
targetcompiler options to
ES2022or above. This will make the project compile to ECMAScript Modules.tsconfig.json
Place the content above inside a
tsconfig.jsonin the root folder.
Also, to enjoy using the types in
jsconfig.jsonwith the same content and add
If we want to use one of the browser crawlers, we will also need to add
"lib": ["DOM"]to the compiler options.
Ensure that you have installed
npm install --save-dev @apify/tsconfig
Running the project with
ts-node for that, just install it as a dev dependency and add a new NPM script:
npm install --save-dev ts-node
As mentioned above, our project will be compiled to use ES Modules. Because of this, we need to use the
We use the
--transpileOnlyflag, this means the code will not be type-checked, which results in faster compilation. If you don't mind the added time and want to do the type checking, just remove this flag.
"start:dev": "ts-node-esm -T src/main.ts"
Running in production
dist, and we can use
node dist/main.js to run it.
"start:prod": "node dist/main.js"
Dockerfile we recommend using multi-stage build, so we don't install the dev dependencies like TypeScript in the final image:
# using multistage build, as we need dev deps to build the TS source code
FROM apify/actor-node:16 AS builder
# copy all files, install all dependencies (including dev deps) and build the project
COPY . ./
RUN npm install --include=dev \
&& npm run build
# create final image
# copy only necessary files
COPY /usr/src/app/package*.json ./
COPY /usr/src/app/dist ./dist
# install only prod deps
RUN npm --quiet set progress=false \
&& npm install --only=prod --no-optional
# run compiled code
CMD npm run start:prod
Putting it all together
Let's wrap it up to. In addition to the scripts we described above, we also need to set the
type: 'module' in the
package.json to be able to use the Top level await described above. For convenience, we will have 3
start scripts, the default one will be an alias to
start:dev, which is our
ts-node script that does not require compilation (nor type checking). The production script (
start:prod) is then used in the
Dockerfile, after explicit
npm run build call.
"start": "npm run start:dev",
"start:prod": "node dist/main.js",
"start:dev": "ts-node-esm -T src/main.ts",