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

metapak

v6.0.0

Published

Node modules authoring made easy.

Downloads

588

Readme

metapak

Node modules authoring made easy.

GitHub license Coverage Status

What's that?

metapak provides a set of tools to build your own meta npm packages easily.

A meta npm package takes advantage of npm lifecycle scripts to allow you to manage several similar npm packages/NodeJS projects in a simple and versioned way.

Here is a simple deck introducing it.

What is it good for?

Let's say you are the author of thousands of Node modules. Now, imagine you want, for all of them:

  • change your linter,
  • change your license,
  • change your CI provider,
  • add a README template system,
  • add a contributors guide,
  • setup git hooks.

This could look like a developer nightmare but with metapak you can manage that complexity by creating idempotent scripts to run on all your projects.

Features

Allows you to create a npm meta module to:

  • amend all your npm modules package.json globally, in a composable way (shared dependencies, utility scripts etc...),
  • add assets to all your projects without polluting your git history with insignificant changes,
  • automatically install git hooks so that all your coding flow are respected by your contributors.

metapak can handle several meta packages so that you can compose them easily and keep them small and focused on one concern.

Zero config for your contributors, nothing to install globally.

Usage

First create your own metapak module (you can look at mine to grasp its architecture).

You must name your module with the metapak- prefix in order to make it work.

Now, just define a configuration (named main here) you will be able to apply to all your NPM modules:

mkdir src
mkdir src/main

# Let's set the package.json of your modules
# Note this has to be an idempotent function
# (ie: same run same result)
echo "
module.exports = (packageConf) => {
  // Looks like i am the contributor of all
  // my modules ;)
  packageConf.author = 'Nicolas Froidure';

  // I mostly publish under MIT license,
  // let's default to it
  packageConf.license = 'MIT';

  // Let's add my handy scripts
  packageConf.scripts = packageConf.scripts || {};
  packageConf.scripts.lint = 'eslint';

  // And the MUST HAVE dependencies
  packageConf.dependencies = packageConf.dependencies || {};
  packageConf.dependencies.debug = '1.0.0';

  // And the MUST HAVE dev dependencies
  packageConf.devDependencies = packageConf.devDependencies || {};
  packageConf.devDependencies.eslint = '3.0.0';

  return packageConf;
}" > src/main/package.js

# Let's also add some common assets
# metapak will add/update for us
mkdir src/main/assets
# Adding the license
wget -O src/main/assets/LICENSE https://mit-license.org/license.txt
# Adding a git ignore file
# Note we replaced the dot of the file per _dot_
# This is due to a magic behavior of npm
# See: https://github.com/npm/npm/issues/15660
# metapak will rename it to .gitignore
echo "node_modules" > src/main/assets/_dot_gitignore

# And make some additions to them, like templating
echo "
module.exports = (file, packageConf) => {
  // Simple templating of the LICENSE
  // There is no glob matching or templating system
  // in metapak to let you choose the ones you like
  if(file.name === 'LICENSE') {
    file.data = file.data.replace(
      /<copyright holders>/g,
      'Nicolas Froidure'
    );
    return file;
  }
  return file;
};
" > src/main/assets.js

# Finally let's add my git hooks on it
echo "module.exports = (hooks, packageConf) => {
  hooks['pre-commit'] = hooks['pre-commit'] || [];

  // Ensure tests and linting are ok
  hooks['pre-commit'].push('npm run test && npm run lint || exit 1');

  // Ensure that metapak state is stable
  // Indeed, you do not want to commit
  // while metapak has some changes to do
  // doing so would create a gap between
  // you metapak module/config and the
  // repository contents
  hooks['pre-commit'].push('npm run metapak -- --safe || exit 1');
  return hooks;
};
" > src/main/hooks.js

For convenience, you can add a peer dependency to your metapak plugin to force a given metapak version:

{
  "peerDependencies": {
    "metapak": "^4.0.4"
  }
}

Now publish your package to npm and install it in all your repositories development dependencies with metapak:

npm i --save-dev metapak metapak-nfroidure

And declare the configuration to apply it:

{
  "version": "1.0.0",
  "metapak": {
    "configs": ["main"]
  }
  "scripts": {
    "metapak": "metapak"
  }
}

Now by running:

npm run metapak

All changes will apply automatically. If you are in a CI/CD context, you will take benefit to use npm run metapak -- --safe that will make the command fail if there is any change. It is useful to avoid commit unstable changes.

That's it! There is a lot of things you can set on all your projects like CI scripts, linters, tests configuration etc...

You can also create specific configs and combine them. Let's say I work for the Big Brother inc. and i want to add special behaviors for the modules I create at work:

mkdir src/bigbrother

# Let's add a package.json template
echo "
module.exports = (packageConf) => {
  // Lets proudly claim I work at BB inc.!
  packageConf.author = 'Nicolas Froidure (Big Brother inc.)';

  // Let's change the license
  packageConf.license = 'SEE LICENSE IN LICENSE.md';

  // Let's avoid loosing my job :D
  packageConf.private = true;

  return packageConf;
}" > src/bigbrother/package.js

# Simply override the default license
mkdir src/bigbrother/assets
echo "
Copyright Big Brother inc. All rights reserved.
" > src/bigbrother/assets/LICENSE.md

Now, just create a new version of your package, publish it and add this specific behavior by adding the following property to your Big Brother's projects:

{
  "version": "1.0.0",
  "metapak": {
    "configs": ["main", "bigbrother"]
  }
}

Note: You can use a built project for your metapak module but in this case, you will have to use the dist folder instead of the src one to put your configs. Assets remain in the src one so do not forget to bundle the src folder into your final NPM module.

Contributing

To contribute to Metapak, simply clone this repository and run the tests. To test the CLI, use:

node bin/metapak.js

Authors

License

MIT