简体   繁体   中英

How to run a single typescript file with Nx

I have a Nx Node project that uses pre-processed summary stats files. These stats files require a lot of processing and rarely need to be generated. However, once they are generated the primary Node app runs quickly.

I want a pre-processing step that can be run manually to generate these stats assets. I want to use Nx's typescript, prettier and linting support to write the code to generate these stats files. But creating a whole Node Nx library for each processing step seems like a lot of unnecessary infrastructure.

There is an option to run custom commands: https://nx.dev/latest/node/executors/run-commands-builder . I want to do this with a Typescript file but the documentation only shows shell commands or combining pre-existing Nx commands. AFAICT I can't just point this to a typescript file.

Question is:

  1. Can I run a custom command to trigger a single typescript file?
  2. Is it more idiomatic to just create a whole Node library for each file that generates these stats?

Thanks

You don't have to create a separate library for each. If they all fit within the category of "generate my preprocessed stats" then they can (maybe should) go together.

As for triggering a single TypeScript file, TypeScript files are not meant to be triggered. Instead, we compile them into JS and run the JS files using Node. In general, this translates to the following commands:

  1. Run tsc to compile your TypeScript files.
  2. Run node <your-main-file>.js to execute your JS file(s).

Compilation

Command Description
tsc index.ts Compile a single file named index.ts in the current directory.
tsc *.ts Compile all TypeScript files in the current directory.
tsc --project tsconfig.stats-type1.json or
tsc --project tsconfig.stats-type2.json or
...
Compile according to the specified config file from the current directory.

The last example shows how you could have several tsconfig.json files in your library, one for each stats type, in order to create different variations of your compilation according to your needs.

See tsc CLI options for more info.

Execution

After that, depending on where you told tsc to output your files to, pass the created file to node .

In case you want to run more than one file in a single command, there are a few ways to do that. One would be creating a main file which imports and calls functions from all other files.

Good luck.

I've came across to a similar use case as yours: I've a NX app that needs some sort of scripts to run (not always, so I can't put them in some utility in the app). Those scripts don't need to be transpiled to js, but I want to use all the utils and libs in my nx monorepo.

My solution was to create a script folder inside my app and exclude it from the build process, then on the workspace.json (or project.json) I added this target:

{
  "run-script": {
    "executor": "@nrwl/workspace:run-commands",
    "configurations": {
      "my-script": {
        "commands": [
          "ts-node apps/path/to/my/script.ts"
        ]
      }
    }
  }
}

and I can run it using the command:

nx run my-project:run-script:my-script

Executing the compiled version of the script avoids a lot of pain if you have specialized tsconfig files and dependent libraries used by the script. Executing the following:

nx g @nrwl/workspace:run-commands run-script --project my-project --command 'node dist/apps/my-project/main.js'

Creates a command that uses the javascript compilation of the script bypassing all of the typescript configuration. It produces the following in apps/my-project/project.json

    "run-script": {
      "executor": "@nrwl/workspace:run-commands",
      "outputs": [],
      "options": {
        "command": "node dist/apps/my-project/main.js"
      }
    }

Which can then be executed by:

nx run my-project:run-script

Thanks to alessiopremoli and Dharman for pointing me in the right direction.

After six months I'm back to this issue and both my old answer and the other added in the meantime don't work for my (new) case: I have to run a script with specific imports from the nx monorepo. After digging through the updates I've come up with a new solution.

The main idea is to store your app / lib related scripts in a sub-folder of the project folder to which they're related and then add to the workspace.json or project.json a specific build command for this folder, something like:

{
    "_build_scripts": {
        "executor": "@nrwl/node:build",
        "outputs": [
            "{options.outputPath}"
        ],
        "options": {
            "outputPath": "dist/libs/my-project-path",
            "tsConfig": "libs/my-project-path/tsconfig.lib.json",
            "packageJson": "libs/my-project-path/package.json",
            "main": "libs/my-project-path/scripts/myscript.ts",
            "assets": ["if needed"]
        }
    }
}

then you can set up your run script command, always in the workspace.json or project.json :

{
  "run-script": {
    "executor": "@nrwl/workspace:run-commands",
    "configurations": {
      "my-script": {
        "commands": [
          "./node_modules/.bin/nx run my-project:_build_script",
          "node dist/my-project-path/main.js"
        ],
        "parallel": false
      }
    }
  }
}

Two things to keep in mind: parallel set to false is mandatory, you need the build step before executing the script; in my case, before the node main.js I had to cd in the directory since fs was reading some files resolving paths incompatible with the monorepo root.

In the end you can run:

npx nx run my-project:run-script:my-script

I had a similar situation where I wanted to run a nx node app once to perform a task and output the result. I appended this to my app's targets:

// project.json

{
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "apps/app-name/src",
  "projectType": "application",
  "targets": {
    ...
    "run": {
      "executor": "@nrwl/workspace:run-commands",
      "options": {
        "commands": [
          "nx run app-name:build:production",
          "node dist/apps/app-name/main.js"
        ]
      }
    }
  },
  "tags": []
}

Then to run the app once: nx run app-name:run

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM