rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

[RRFC] Build Google Wireit's script runner into npm

Open justinfagnani opened this issue 1 year ago • 6 comments

Motivation ("The Why")

There are a number of tools, and RRFCs (https://github.com/npm/rfcs/issues/190, https://github.com/npm/rfcs/issues/610 and https://github.com/npm/rfcs/issues/548, https://github.com/npm/rfcs/issues/691) that relate to running scripts in series, parallel, etc.

I opened https://github.com/npm/rfcs/issues/691 as a proposal to add pluggable script runners to npm to make using tools like Wireit easier. While I think that is a good idea, I honestly think that an even better solution is to build Wireit directly into npm, giving all npm uses the ability to define a graph of scripts and utilize caching, watch mode, and long-running services.

Wireit has a very robust feature set and implementation at this point, and has been designed to fit very seamlessly with the npm CLI's interface, configuration and workflow. It is not a tool that takes over and works over-top of npm, but one that tries to be as much of a part of npm as possible. As such, I think it should be quite easy to integrate with npm compared to tools that have their own CLI, config, and implementation (sometimes in non-JS languages).

Adding a full script graph with caching would solve all of the open issues around more powerful script running, and several issues that third-party tools cover now. For example, output caching can save significant build time for developers and CI. Services with watch mode make rebuilding and restarting servers on code changes (similar to nodemon) fast and seamless.

Example

It's probably best to view the Wireit repo for many examples of its features.

A basic Wireite configuration with dependencies between scripts looks like:

{
  "scripts": {
    "build": "wireit",
    "bundle": "wireit"
  },
  "wireit": {
    "build": {
      "command": "tsc"
    },
    "bundle": {
      "command": "rollup -c",
      "dependencies": ["build"]
    }
  }
}

Integrated into npm, this could look like:

{
  "scripts": {
    "build": "tsc",
    "bundle": {
      "command": "rollup -c",
      "dependencies": ["build"]
    }
  }
}

How

Current Behaviour

Currently, scripts are just strings with the command to run.

Desired Behaviour

I propose making scripts objects that describe their command, dependencies, inputs and output files (for caching) and more.

References

  • https://github.com/npm/rfcs/issues/190
  • https://github.com/npm/rfcs/issues/610
  • https://github.com/npm/rfcs/issues/548
  • https://github.com/npm/rfcs/issues/691

cc @aomarks, the author of Wireit

justinfagnani avatar Jul 07 '23 16:07 justinfagnani