A skeleton for getting started with NPM packages.
Getting started (things you have to do)
To get the gist of what this does, try running
npm install # this also runs `npm prepublish` behind the scenes.
then look at the generated files in the root of the project. To customize to your needs, follow the following steps:
package.jsonwith the details of your package (name, description, etc), replacing things that are
ALL-CAPSwith your own things.
- Add dependencies as needed into the
- Open and customize
scripts/build-global.sh(read the comments there).
- Open and customize
scripts/clean.sh(read the comments there).
- Open and customize
.gitignore(read the comments there).
- Optionally customize
.npmignore(it's empty by default).
npm installto install dependencies and dev-dependencies.
npm run cleanat any point to clean automatically-built files (caused by
npm prepublish, and
npm publish, for example).
- Write code inside the
srcfolder using ES2015 modules and/or syntax (ES2016 language features are not yet supported, TODO), with index.js being the main file (the file that gets evaluated when someone runs
- Once you've written your package code, run
npm prepublishmanually which compiles everything to CommonJS format in the root of the project, and also builds a global.js file.
- To test your package, you can use
npm link your-package-name(see the docs) to link your package into a test project for local testing.
- When you're ready to publish, just make sure you update the
versionfield of your
These are just rough guidelines, and are flexible. It's up to you to modify this to your needs (for example, add gulp or grunt, or use Webpack to watch file changes, etc). It's just a starting point.
One of the goals of this skeleton is to let you get started making a package
that builds itself out-of-the-box for NPM when you run
npm publish, and that
supports various end-user workflows like Browserify+NPM, Webpack+NPM, JSPM (by
Guy Bedford, who leads efforts on things like loading modules over
Bower+RequireJS (yes, we can! Bower still has hundreds of thousands of
downloads per week), and a global build (a build system without a build system
that many people still use
The package skeleton is made with generic the latest standardized features in
mind (such as the source of the package in the
src folder using ES2015 (ES6)
Modules, included scripts for building to various other module formats, and the
latest released ecmascript language features via Babel) that let the package be
consumed in workflows we haven't considered.
Some things explained:
- package.json includes scripts to build to AMD, CJS, and UMD modules formats (we write our package code in ES2015 (ES6) module format).
- Source files live in the
srcfolder, with index.js as the main entrypoint to the package.
- On prepublish to NPM, files are built to CJS format into the root of the
package, then published. Prepublish only uses the
build-cjsscript, and the other scripts are there in case someone wants to make use of them, for convenience (for example, someone might have a custom RequireJS workflow, and can use the build-amd script to get AMD files). The clean script removes the build files after prepublish, or manually if needed.
- The package is published with both the built CJS files in the root and the
original source files in the
srcfolder to maximize coverage of use cases. Some people will require the root files directly, using Webpack or Browserify, or perhaps even natively in some Node.js-based app. We publish the
srcfolder intact so that people who use JSPM can set
srcand JSPM will set that folder as the root of the package once it is installed. Other people might like to set an alias in Webpack to the
srcfolder in order to use the original ES2015 source modules. Basically, let's let people do what they want. Other people might just like to use the original ES6 source modules in some other ES2015-module-compatible system.
babelifyin case someone configures Browserify to use the
srcfolder's ES2015 modules instead of the root's CommonJS ones. There's no harm done including it.
- There are some extra fields in
package.jsonfor JSPM and Bower. Bower is still TODO.
babel-runtimepackage is a runtime dependency, which simply includes some function helpers like those used to create prototype-based classes in ES5, etc. The
--optionalruntime option in the
build-*scripts tells babel not to include helper functions in each and every file, instead using
requireto get the helpers from a single source. It's a good thing to have the runtime in order to eliminate duplicate helper code in your output files.
formatproperty helps some build systems. F.e., JSPM doesn't have to make a guess as to the format of the modules.
globalfields help in some cases too.
Basically, the idea is to maximize coverage of the most notable workflows and use cases.
- Upgrade to Babel 6.x
- Support not-yet-completed experimental language features (ES7/ES2016 at the time of writing).
Open an issue or PR if you have any ideas! :]