npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

spire

v5.0.8

Published

Extensible CLI toolkit managment tool

Downloads

231

Readme

🗼 Spire

Extensible JavaScript toolbox management.

Motivation

Problem: Maintaining tools and configurations for linting, testing and building your code is hard. The more projects you have, the more time it takes to keep your setup consistent and up-to-date.

Solution: Spire is a pluggable CLI tool which allows you to abstract all of your tools and configurations into reusable plugins and presets. Think of it as “babel for infrastructure”.

Quick Start

  1. Install spire:
# yarn
yarn add --dev spire

# npm
npm install --save-dev spire
  1. Start using in your project:
# npx
npx spire --help

# yarn
yarn spire --help
  1. Depending on your tech stack, you can start using Spire as zero-config tool. See spire-config-default for a list of default tools and configuration section for how to customise it.

Configuration

Spire is based on config presets, which is the same concept for tools like Babel and ESLint. Configs are a set of predefined plugins and their options. Configs can also extend a chain of other configs. By default, Spire is shipped with spire-config-default.

Using a Custom Preset

To use your preferred configuration, install it as dev dependency and reference it by module name in extends property. To extend multiple configs, provide it as an array. You can also use individual plugins along with configs with plugins property.

{
  "name": "acme-project",
  "devDependencies": {
    "spire": "^3.0.0",
    "spire-config-acme": "^1.0.0"
  },
  "spire": {
    "extends": "spire-config-acme"
  }
}
module.exports = {
  extends: 'spire-config-acme',
};
{
  "extends": "spire-config-acme",
}

Using a Local Preset

Note: It is recommended to enable Local Presets only for development.

You can reference a Local Preset or plugin using <rootDir> placeholder which points to the current project directory:

{
  "spire": {
    "extends": "<rootDir>/spire-config.js",
    "plugins": ["<rootDir>/spire-plugin.js"]
  }
}

Passing Options

If the config preset or plugin you're using supports customisation, you can pass options to it:

{
  "spire": {
    "extends": [["spire-config-acme", { "fictional": false }]],
    "plugins": [["spire-plugin-acme", { "company": true }]]
  }
}

Guides

Writing a Config

A Config is a module which exports a function returning an object.

Example:

module.exports = (spire, options) => {
  return {
    extends: ['spire-config-first', 'spire-config-second'],
    plugins: ['spire-plugin'],
  };
};

You can dynamically change the behaviour of your preset based on options or spire APIs, but it's recommended to keep it explicit. Check spire-config-default for a reference.

Writing a Plugin

A Plugin is a key component of Spire. After it resolves the config, Spire accumulates all plugins in chronological order and runs them. A Plugin is a function returning an object:

Note: It is recommended to keep plugins scoped to a single feature or tool.

Example:

module.exports = (spire, options) => {
  return {
    name: 'my-awesome-tool',
    command: 'my-tool',
    description: 'run my awesome tool',
    async run({ logger }) {
      logger.log('Hi from my awesome tool!');
    },
  };
};

Check spire-plugin-clean, spire-plugin-doctoc and spire-plugin-eslint for more plugin examples.

Migrating to Spire

Identify your tools: To get started, gather a list of shared tools in your existing projects. This will help to identify which plugins you'll need.

Pick preset or plugin: Check if there's already a default or community plugin for that. Search for spire-plugin-* on npm for individual tools and spire-config-* for specific ecosystems and tech stacks. In case if there's no suitable option for your, check on how to write a custom plugin.

Make your own preset: If you find that an existing or default preset works for you, skip this step. If not, create a new module with a name matching spire-config-*. It can be specific for your personal projects, your company or a tech stack. Check writing a config for instructions on how to do this.

Migrate your projects: Once you've got a preset ready, go through your projects and setup Spire with it. Make sure to delete the dependencies it replaces. At this point you're done!

Using without Git

You do not need to have git installed to run spire itself. Be aware though that certain plugins might need to have git installed to work. For example the semantic-release and lerna-release plugin obviously need git because they create tags and commits.

Using in monorepos

It is recommended to install Spire on the root level of a monorepo and run all commands from there. The main motivation behind this is performance and consistency reasons. You can still though run commands in an indivudual package. Below is an example of how to run spire lint in a specific monorepo package:

  • With yarn workspaces:
    yarn workspace <pkg-name> spire lint
  • With lerna:
    npx lerna --scope <pkg-name> exec spire lint

API

CLI

Each plugin can extend a list of available commands and their options. The list below only includes basic commands.

  • npx spire --help Prints the list of available commands.
  • npx spire --version Prints the current version of Spire.
  • npx spire <cmd> Runs a specific command defined by plugins.
  • npx spire --debug <cmd> Outputs additional debug information.
  • (hidden) npx spire hook <name> Runs specific git or npm plugin hooks. Available hooks are postinstall, preuninstall, precommit and postmerge. Use this to test or debug your plugins.

spire

Spire is an object which is passed as the first argument to both configs and plugins.

context

Context is an object which is passed as the first argument to plugin hooks. It's designed to be read-only. If you want to pass some data futher, consider using spire.setState instead.

  • context
    • argv <Array<string>> Array of arguments Spire was called with. Defaults to process.argv.slice(2).
    • cli <Object> Instance of yargs for adding custom commands.
    • cwd <string> Directory Spire is executed in. Defaults to process.cwd().
    • env <Object> Set of environment variables. Defaults to process.env.
    • logger <Object> Instance of Signale. Use logger.debug() to print debug info which is only shown with --debug flag.
    • config <Object> Parsed and normalised config.
    • options <Object> Parsed yargs options. Available only after setup hook.

References

This project is inspired by the great work of JavaScript open source community (without particular order):

License

MIT © ResearchGate