{"id":15570195,"url":"https://github.com/nfroidure/metapak","last_synced_at":"2025-05-06T18:05:46.155Z","repository":{"id":16840808,"uuid":"78930041","full_name":"nfroidure/metapak","owner":"nfroidure","description":"NPM meta package","archived":false,"fork":false,"pushed_at":"2024-12-04T12:16:33.000Z","size":1280,"stargazers_count":26,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-06T18:05:42.226Z","etag":null,"topics":["javascript","nodejs","npm","package","yarn"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nfroidure.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["nfroidure"]}},"created_at":"2017-01-14T09:00:33.000Z","updated_at":"2024-12-04T12:16:35.000Z","dependencies_parsed_at":"2024-06-18T21:19:05.997Z","dependency_job_id":"e3db6c3e-80d2-4104-880e-009efa113205","html_url":"https://github.com/nfroidure/metapak","commit_stats":{"total_commits":153,"total_committers":3,"mean_commits":51.0,"dds":0.5032679738562091,"last_synced_commit":"9cecc4e8b6262c1117646d90ab003541726dc9f6"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfroidure%2Fmetapak","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfroidure%2Fmetapak/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfroidure%2Fmetapak/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nfroidure%2Fmetapak/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nfroidure","download_url":"https://codeload.github.com/nfroidure/metapak/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252741373,"owners_count":21797027,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","nodejs","npm","package","yarn"],"created_at":"2024-10-02T17:41:33.923Z","updated_at":"2025-05-06T18:05:46.090Z","avatar_url":"https://github.com/nfroidure.png","language":"TypeScript","funding_links":["https://github.com/sponsors/nfroidure"],"categories":[],"sub_categories":[],"readme":"[//]: # ( )\n[//]: # (This file is automatically generated by a `metapak`)\n[//]: # (module. Do not change it  except between the)\n[//]: # (`content:start/end` flags, your changes would)\n[//]: # (be overridden.)\n[//]: # ( )\n# metapak\n\u003e Node modules authoring made easy.\n\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/metapak/blob/main/LICENSE)\n[![Coverage Status](https://coveralls.io/repos/github/nfroidure/metapak/badge.svg?branch=main)](https://coveralls.io/github/nfroidure/metapak?branch=main)\n\n\n[//]: # (::contents:start)\n\n## What's that?\n\n`metapak` provides a set of tools to build your own meta npm packages easily.\n\nA meta npm package takes advantage of npm\n[lifecycle scripts](https://docs.npmjs.com/misc/scripts) to allow you to manage\nseveral similar npm packages/NodeJS projects in a simple and versioned way.\n\nHere is a [simple deck](https://slides.com/nfroidure/meta-npm-packages/live#/)\nintroducing it.\n\n## What is it good for?\n\nLet's say you are the author of thousands of Node modules. Now, imagine you\nwant, for all of them:\n\n- change your linter,\n- change your license,\n- change your CI provider,\n- add a README template system,\n- add a contributors guide,\n- setup git hooks.\n\nThis could look like a developer nightmare but with `metapak` you can manage\nthat complexity by creating idempotent scripts to run on all your projects.\n\n## Features\n\nAllows you to create a npm meta module to:\n\n- amend all your npm modules `package.json` globally, in a composable way\n  (shared dependencies, utility scripts etc...),\n- add assets to all your projects without polluting your git history with\n  insignificant changes,\n- automatically install git hooks so that all your coding flow are respected by\n  your contributors.\n\n`metapak` can handle several meta packages so that you can compose them easily\nand keep them small and focused on one concern.\n\nZero config for your contributors, nothing to install globally.\n\n## Usage\n\nFirst create your own `metapak` module (you can look\n[at mine](https://github.com/nfroidure/metapak-nfroidure) to grasp its\narchitecture).\n\nYou **must** name your module with the `metapak-` prefix in order to make it\nwork.\n\nNow, just define a configuration (named `main` here) you will be able to apply\nto all your NPM modules:\n\n```sh\nmkdir src\nmkdir src/main\n\n# Let's set the package.json of your modules\n# Note this has to be an idempotent function\n# (ie: same run same result)\necho \"\nmodule.exports = (packageConf) =\u003e {\n  // Looks like i am the contributor of all\n  // my modules ;)\n  packageConf.author = 'Nicolas Froidure';\n\n  // I mostly publish under MIT license,\n  // let's default to it\n  packageConf.license = 'MIT';\n\n  // Let's add my handy scripts\n  packageConf.scripts = packageConf.scripts || {};\n  packageConf.scripts.lint = 'eslint';\n\n  // And the MUST HAVE dependencies\n  packageConf.dependencies = packageConf.dependencies || {};\n  packageConf.dependencies.debug = '1.0.0';\n\n  // And the MUST HAVE dev dependencies\n  packageConf.devDependencies = packageConf.devDependencies || {};\n  packageConf.devDependencies.eslint = '3.0.0';\n\n  return packageConf;\n}\" \u003e src/main/package.js\n\n# Let's also add some common assets\n# metapak will add/update for us\nmkdir src/main/assets\n# Adding the license\nwget -O src/main/assets/LICENSE https://mit-license.org/license.txt\n# Adding a git ignore file\n# Note we replaced the dot of the file per _dot_\n# This is due to a magic behavior of npm\n# See: https://github.com/npm/npm/issues/15660\n# metapak will rename it to .gitignore\necho \"node_modules\" \u003e src/main/assets/_dot_gitignore\n\n# And make some additions to them, like templating\necho \"\nmodule.exports = (file, packageConf) =\u003e {\n  // Simple templating of the LICENSE\n  // There is no glob matching or templating system\n  // in metapak to let you choose the ones you like\n  if(file.name === 'LICENSE') {\n    file.data = file.data.replace(\n      /\u003ccopyright holders\u003e/g,\n      'Nicolas Froidure'\n    );\n    return file;\n  }\n  return file;\n};\n\" \u003e src/main/assets.js\n\n# Finally let's add my git hooks on it\necho \"module.exports = (hooks, packageConf) =\u003e {\n  hooks['pre-commit'] = hooks['pre-commit'] || [];\n\n  // Ensure tests and linting are ok\n  hooks['pre-commit'].push('npm run test \u0026\u0026 npm run lint || exit 1');\n\n  // Ensure that metapak state is stable\n  // Indeed, you do not want to commit\n  // while metapak has some changes to do\n  // doing so would create a gap between\n  // you metapak module/config and the\n  // repository contents\n  hooks['pre-commit'].push('npm run metapak -- --safe || exit 1');\n  return hooks;\n};\n\" \u003e src/main/hooks.js\n```\n\nFor convenience, you can add a peer dependency to your metapak plugin to force a\ngiven metapak version:\n\n```json\n{\n  \"peerDependencies\": {\n    \"metapak\": \"^4.0.4\"\n  }\n}\n```\n\nNow publish your package to npm and install it in all your repositories\ndevelopment dependencies with metapak:\n\n```\nnpm i --save-dev metapak metapak-nfroidure\n```\n\nAnd declare the configuration to apply it:\n\n```json\n{\n  \"version\": \"1.0.0\",\n  \"metapak\": {\n    \"configs\": [\"main\"]\n  }\n  \"scripts\": {\n    \"metapak\": \"metapak\"\n  }\n}\n```\n\nNow by running:\n\n```sh\nnpm run metapak\n```\n\nAll changes will apply automatically. If you are in a CI/CD context, you will\ntake benefit to use `npm run metapak -- --safe` that will make the command fail\nif there is any change. It is useful to avoid commit unstable changes.\n\nThat's it! There is a lot of things you can set on all your projects like CI\nscripts, linters, tests configuration etc...\n\nYou can also create specific configs and combine them. Let's say I work for the\nBig Brother inc. and i want to add special behaviors for the modules I create at\nwork:\n\n```sh\nmkdir src/bigbrother\n\n# Let's add a package.json template\necho \"\nmodule.exports = (packageConf) =\u003e {\n  // Lets proudly claim I work at BB inc.!\n  packageConf.author = 'Nicolas Froidure (Big Brother inc.)';\n\n  // Let's change the license\n  packageConf.license = 'SEE LICENSE IN LICENSE.md';\n\n  // Let's avoid loosing my job :D\n  packageConf.private = true;\n\n  return packageConf;\n}\" \u003e src/bigbrother/package.js\n\n# Simply override the default license\nmkdir src/bigbrother/assets\necho \"\nCopyright Big Brother inc. All rights reserved.\n\" \u003e src/bigbrother/assets/LICENSE.md\n```\n\nNow, just create a new version of your package, publish it and add this specific\nbehavior by adding the following property to your Big Brother's projects:\n\n```\n{\n  \"version\": \"1.0.0\",\n  \"metapak\": {\n    \"configs\": [\"main\", \"bigbrother\"]\n  }\n}\n```\n\n**Note:** You can use a built project for your `metapak` module but in this\ncase, you will have to use the `dist` folder instead of the `src` one to put\nyour configs. Assets remain in the `src` one so do not forget to bundle the\n`src` folder into your final NPM module.\n\n## Contributing\n\nTo contribute to Metapak, simply clone this repository and run the tests. To\ntest the CLI, use:\n\n```sh\nnode bin/metapak.js\n```\n\n[//]: # (::contents:end)\n\n# Authors\n- [Nicolas Froidure](http://insertafter.com/en/index.html)\n\n# License\n[MIT](https://github.com/nfroidure/metapak/blob/main/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnfroidure%2Fmetapak","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnfroidure%2Fmetapak","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnfroidure%2Fmetapak/lists"}