njs-typescript-starter icon indicating copy to clipboard operation
njs-typescript-starter copied to clipboard

A starting template for developing njs (NGINX JavaScript) scripts for NGINX server in TypeScript.

= Njs TypeScript Starter :toc: macro :toc-title: :gh-name: jirutka/njs-typescript-starter // non-breakable hyphen :nb-: ‑ // links :Babel: link:https://babeljs.io[Babel] :ESLint: link:https://eslint.org[ESLint] :Mocha: link:https://mochajs.org[Mocha] :nginx-testing: link:https://github.com/jirutka/nginx-testing[nginx-testing] :Rollup: link:https://babeljs.io[Rollup] :yarn: link:https://yarnpkg.com/[yarn] :npm: link:https://docs.npmjs.com/cli/commands/npm/[npm]

A full-featured starting template for developing https://github.com/nginx/njs[njs] (NGINX JavaScript) scripts for https://nginx.org[NGINX] server in https://www.typescriptlang.org[TypeScript].

This template uses {Babel} and {Rollup} to compile TypeScript sources into a single JavaScript file for njs and {Mocha} with {nginx-testing} for running integration tests against NGINX sever.

[discrete] == Table of Contents

toc::[]

== Pre-requisites

To build and run this project locally you will need:

  • Linux system footnote:[It should work on any recent Linux distribution for x86_64, aarch64, or ppc64le architecture.], macOS footnote:[I’m not sure what is the lowest version you need. It should work both on Intel and M1.] or Windows Subsystem for Linux (WSL) footnote:[njs doesn’t support Windows, so integration tests won’t run on Windows out of the box. If you’re stuck with Windows, WSL is the easiest way to go.]
  • https://nodejs.org/en/download/package-manager/[Node.js] 18.12 or newer
  • {npm} (distributed with Node.js) or {yarn}

NOTE: You do not need Docker or other containerization tool for developing and testing njs scripts on Linux and macOS! See {nginx-testing} for more information.

== Getting Started

. Clone this repository: + [source, sh, subs="+attributes"] git clone --depth=1 https://github.com/{gh-name}.git cd

. Install dependencies: + [source, sh] npm install # or yarn install

. Build the project and run tests: + [source, sh] npm test

. Start nginx and project’s build in the watch mode: + [source, sh] npm run start

. Open http://127.0.0.1:8090/hello in the browser and now you should see the output of link:src/hello.ts[]: + .... Meow, world!

    ("`-''-/").___..--''"`-._
    `6_ 6  )   `-.  (     ).`-.__.`)
    (_Y_.)'  ._   )  `._ `. ``-..-'
  _..`--'_..-_/  /--'_.' ,'
  (il),-''  (li),'  ((!.-'

....

At least before publication of your project (e.g. on GitHub), do the following:

  • Change name, version, description, author, license (if you prefer a license other than MIT), homepage, bugs, and repository fields in link:package.json[] to reflect your project.
  • Add your name to link:LICENSE[] and/or change the license text if you prefer a license other than MIT. You don’t have to keep my name in the license.
  • Replace this README file. If you prefer Markdown to AsciiDoc, replace this file with README.md and remove scripts.prepublishOnly from link:package.json[].

== Project Structure

Files and directory structure of the project.

[%header] |=== | Path | Description

| link:.github/workflows/[] | Contains https://github.com/features/actions/[GitHub Actions] workflows.

| link:dist/[] | Contains the built JavaScript file for NGINX’s JS module.

| link:integration-tests/[integration{nb-}tests] | Contains your integration tests.

| lib/ | Contains type declarations generated from TypeScript sources in src/ directory.

| node_modules/ | Contains all your npm dependencies.

| link:src/[] | Contains your source code that will be compiled to the dist/ directory.

| link:src/tsconfig.json[] | Config settings for type checking your TypeScript source code that will be compiled for njs.

| link:.editorconfig[] | Defines very basic code style used in the project. See https://editorconfig.org[editorconfig.org] for more information.

| link:.eslintrc.js[] | {ESLint} config for linting your TypeScript and JavaScript files.

| link:.mocharc.js[] | {Mocha} config for integration tests.

| link:babel.config.js[] | {Babel} config for compiling TypeScript sources into plain JavaScript compatible with njs and Node.js.

| link:package.json[] | File that contains npm dependencies as well as <<Build Scripts, build scripts>>.

| package{nb-}lock.json | Describes the exact dependency tree that was generated, including exact versions and checksums of the installed packages. This file is automatically generated by {npm} when you run e.g. npm install. (https://docs.npmjs.com/cli/configuring-npm/package-lock-json[read more…])

| link:rollup.config.js[] | {Rollup} config for compiling and bundling your source code in src/ together with the dependencies into a single JavaScript file for NGINX JS module.

| link:tsconfig.json[] | Config settings for type checking code written in TypeScript or JavaScript that will be executed by Node.js (i.e. integration tests and JS configs).

| yarn.lock | If you use {yarn} instead of {npm}; this file has the same purpose as package-lock.json for npm. |===

NOTE: Some of the files and directories will be created after installing dependencies or building the project.

== Build Scripts

All the build steps are orchestrated via https://docs.npmjs.com/misc/scripts[npm scripts]. Npm scripts basically allow us to call (and chain) terminal commands via npm. If you open link:package.json[], you will see a scripts section with all the different scripts you can call. To call a script, simply run npm run <script-name> (or yarn <script-name>) from the command line.

Below is a list of all the scripts this template has available:

[%header, cols="m,d"] |=== | Npm{nbsp}Script | Description

| build | Compiles and bundles all source .ts files together with their dependencies into a single .js file in the dist directory. | clean | Cleans dist, lib, and node_modules/.cache directories. | lint | Runs both lint:eslint and lint:types in parallel. | lint:eslint | Runs {ESLint} linter on project files. | lint:types | Runs TypeScript type checker on project files. | start | Runs start-nginx and watch in parallel. | start{nb-}nginx | Starts nginx 1.24.x on port 8090 with config integration-tests/nginx.conf and reloads it on each change of the config file and files in dist/. | test | Runs all tests in the integration-tests directory using {Mocha} test runner. | watch | Same as build but continuously watches project’s .ts files and re-compiles when needed. |===

== Dependencies :npmjs-pkg: https://www.npmjs.com/package/

Project’s dependencies are specified in file link:package.json[], sections dependencies (runtime dependencies) and devDependencies (build-time dependencies). They are managed by {npm} or {yarn}.

The following is a list of devDependencies with their description.

  • {npmjs-pkg}/typescript[typescript] -- TypeScript compiler and type checker. Used for type checking the TypeScript sources. ** {npmjs-pkg}/njs-types[njs-types] -- TypeScript type definitions for njs. ** @types/* -- Packages that provide TypeScript types.

  • {npmjs-pkg}/@babel/core[@babel/core] -- A {Babel} compiler core. Babel is used to compile TypeScript sources into plain JavaScript compatible with njs and Node.js. ** {npmjs-pkg}/babel-preset-njs[babel-preset-njs] -- A {Babel} preset for transforming JavaScript code with modern language features into code compatible with njs. ** {npmjs-pkg}/@babel/preset-typescript[@babel/preset-typescript] -- A {Babel} preset to transform TypeScript code into plain JavaScript. It basically just strips the type annotations. ** {npmjs-pkg}/@babel/plugin-transform-modules-commonjs[@babel/plugin-transform-modules-commonjs] -- A {Babel} plugin to transform ES2015 modules into CommonJS modules. Used for running integration tests with Node.js. ** {npmjs-pkg}/@babel/register[@babel/register] -- A {Babel} require hook. Used for {Mocha} integration with TypeScript. ** {npmjs-pkg}/babel-register-ts[babel-register-ts] -- A @babel/register wrapper with additional .ts and .tsx extensions. Used for {Mocha} integration with TypeScript.

  • {npmjs-pkg}/rollup[rollup] -- A module bundler for JavaScript which compiles small pieces of code into a single JavaScript file. ** {npmjs-pkg}/@rollup/plugin-babel[@rollup/plugin-babel] -- A {Rollup} plugin for seamless integration between Rollup and {Babel}. ** {npmjs-pkg}/@rollup/plugin-commonjs[@rollup/plugin-commonjs] -- A {Rollup} plugin to convert CommonJS modules to ES6, so they can be included in a Rollup bundle. ** {npmjs-pkg}/@rollup/plugin-node-resolve[@rollup/plugin-node-resolve] -- A {Rollup} plugin which locates modules using the Node resolution algorithm, for using third party modules in node_modules. ** {npmjs-pkg}/rollup-plugin-add-git-msg[rollup-plugin-add-git-msg] -- A {Rollup} plugin that inserts git tag, commit hash, build date and copyright at top of the generated JS bundle.

  • {npmjs-pkg}/mocha[mocha] -- A flexible JavaScript test framework for Node.js. ** {npmjs-pkg}/mocha-suite-hooks[mocha-suite-hooks] -- Suite-level hooks for {Mocha}; allows to run hook before/after describe block.

  • {npmjs-pkg}/nginx-testing[nginx-testing] -- Support for integration/acceptance testing of nginx configuration.

  • {npmjs-pkg}/got[got] -- A human-friendly and powerful HTTP request library for Node.js. Used in integration tests. Do not update it to version 12.x (see https://github.com/{gh-name}/issues/3[#3])!

  • {npmjs-pkg}/eslint[eslint] -- {ESLint} is a tool for identifying and reporting on patterns found in JavaScript and TypeScript code. ** {npmjs-pkg}/@typescript-eslint/eslint-plugin[@typescript-eslint/eslint-plugin] -- A TypeScript plugin for {ESlint}. ** {npmjs-pkg}/@typescript-eslint/parser[@typescript-eslint/parser] -- An {ESLint} parser which leverages TypeScript ESTree to allow for ESLint to lint TypeScript source code.

  • {npmjs-pkg}/npm-run-all[npm-run-all] -- A CLI tool to run multiple npm-scripts in parallel or sequential. Used in npm scripts.

== License

This project is licensed under https://opensource.org/license/mit/[MIT License].