The npm workflow
EnterJS, 2016-06-16
Who is this guy?
Laurie Voss
CTO,
@seldo
Calibration
What are we talking about?
- Basics of npm
- Building a project
- Sharing a project
- Managing dependencies
- Managing project lifecycle
- Automation with npm
Why use npm?
npm modularity
Front end development is embracing modularity
Apps can be packages
The npm workflow
Hold. Up.
npm basics
Part 1
npm architecture
Where downloads come from
What about GitHub?
npm does not* download packages from GitHub
* not usually, and not by default
The registry can host private packages
npm Enterprise
Building a project
Part 2
npm install -g npm
npm install -g npm@lts
or
npm init
npm init --yes
Scopes
npm init --scope=myusername npm install @myusername/mypackage var x = require('@myusername/mypackage')
~/.npm-init.js
and PromZard
npm init can be re-run
Avoiding editing package.json
> npm install --save > npm install -S > npm install --save-dev > npm install -D
Skip devDependencies in production
> npm install --production
bundledDependencies
Offline* Installs
* mostly
npm install --cache-min 999999
npm config set cache-min 60
Install only from local cache
Check metadata less aggressively
Run scripts
npm start npm stop npm restart npm test
{
"name": "@seldo/some-package",
"version": "1.0.0",
...
"scripts": {
"test": "mocha ./test/*.js",
"start": "node ./index.js"
}
}
Run scripts get devDependencies
in path
Publishing
npm publish npm publish --access=public npm publish --access=restricted
Part 3: sharing a project
SemVer
Semantic Versioning
2.15.58
Breaking
major
Feature
minor
Fix
patch
SemVer reduces friction
Versioning
npm version major npm version minor npm version patch
npm version major -m "bump to version %s"
SemVer is a promise
not a guarantee
Shrinkwrap
(...but...)
npm install clingwrap -g
Maybe try
Multiple users
npm Organizations
npm team npm access
npm team
npm team create <scope:team> npm team destroy <scope:team> npm team add <scope:team> <user> npm team rm <scope:team> <user> npm team ls <scope:team>
npm access
npm access grant read-only <scope:team> [package] npm access grant read-write <scope:team> [package] npm access revoke <scope:team> [package] npm access ls-packages [user|scope|scope:team] npm access ls-collaborators [package [user]]
Multiple packages
npm link
Part 4: managing dependencies
npm link: how-to
npm link
In your package "@myuser/bob":
In your other package, which requires "@myuser/bob":
npm link @myuser/bob
Multiple current versions
npm publish --tag npm dist-tag
npm publish --tag
npm publish --tag <tag> npm install <pkg>@<tag>
Try it out:
npm install npm@next
to try out next week's release
npm dist-tag
npm dist-tag add <pkg>@<version> <tag> npm dist-tag rm <tag> npm dist-tag ls <package>
npm install --tag
npm unpublish
(you may have heard about this one recently)
npm unpublish <pkg>@<version>
npm deprecate
npm deprecate <pkg>[@<version>] <message>
npm deprecate bob@1.0.1 "Breaks everything"
e.g.
Keep projects up to date
npm outdated npm update
Package Current Wanted Latest Location domutils 1.3.0 1.3.0 1.5.1 @npm/testnpm handlebars 1.3.0 1.3.0 4.0.5 @npm/testnpm hbsfy 1.3.2 1.3.2 2.7.0 @npm/testnpm
Run scripts, again
npm run $anything
"npmcheckversion": "node ./internals/scripts/npmcheckversion.js",
"preinstall": "npm run npmcheckversion",
"prebuild": "npm run test && npm run build:clean",
"build:clean": "rimraf ./build/*",
"build": "cross-env NODE_ENV=production webpack --config internals/webpack/webpack.prod.babel.js --color -p",
"analyze": "node ./internals/scripts/analyze.js",
"start": "cross-env NODE_ENV=development node server",
"start:tunnel": "cross-env NODE_ENV=development ENABLE_TUNNEL=true node server",
"start:production": "npm run build && npm run start:prod",
"start:prod": "cross-env NODE_ENV=production node server",
"pagespeed": "node ./internals/scripts/pagespeed.js",
"presetup": "npm i chalk",
"setup": "node ./internals/scripts/setup.js",
"clean": "shjs ./internals/scripts/clean.js",
"generate": "plop --plopfile internals/generators/index.js",
"lint": "npm run lint:js && npm run lint:css",
"lint:js": "eslint . --ignore-path .gitignore --ignore-pattern internals/scripts",
"lint:css": "stylelint ./app/**/*.css",
"lint:staged": "lint-staged",
"pretest": "npm run lint",
Don't read this. Just remember "there were lots of examples".
Part 5: managing project lifecycle
Run script environment
npm_package_name npm_package_version npm_package_dependencies_request npm_package_dependencies_express npm_config_node_version npm_config_registry
console.log(process.env.npm_package_name)
e.g.
Package configuration variables
{
"name": "@seldo/mypackage",
"config": {
"port": "80"
}
}
console.log(npm_package_config_port) > 80 > npm config set @seldo/mypackage:port 8080 console.log(npm_package_config_port) > 8080
Lifecycle hooks
publish: prepublish, publish, postpublish install: preinstall, install, postinstall uninstall: preuninstall, uninstall, postuninstall version: preversion, version, postversion test: pretest, test, posttest stop: prestop, stop, poststop start: prestart, start, poststart restart: prerestart, restart, postrestart
.npmrc
per-project: /path/to/my/project/.npmrc
per-user: ~/.npmrc
global: $PREFIX/etc/npmrc
built-in: /path/to/npm/npmrc
.npmrc auth
//registry.npmjs.org/:_authToken=00000000-0000-0000-0000-000000000000
Looks like:
//registry.npmjs.org/:_authToken={$NPM_TOKEN}
For CI, try:
More details:
Automation with npm
Part 6
The wombat CLI
npm install wombat -g
Webhooks
Fired after every:
- publish
- tag
- star
wombat hook add
wombat hook add @myco/package https://my.co/myhook some-secret
3 types of webhook
wombat hook add somepackage wombat hook add @myco/package wombat hook add @myco wombat hook add --type=owner @anyuser
Packages:
Scopes:
Users:
More wombat hook
wombat hook ls wombat hook update <hook-id> https://new.co new-secret wombat hook rm <hook-id>
Listening for webhooks
npm-hook-receiver
var makeReceiver = require('npm-hook-receiver');
var server = makeReceiver({
secret: 'my-secret',
mount: '/hook'
});
server.on('package:publish', function(package)
{
console.log(`${package.name} was updated!`);
});
Why webhooks?
Lets you build the features we're missing.
Some early hook apps
The non-npm workflow
Babel
Transpile all the things!
Webpack
and
Browserify
Greenkeeper
greenkeeper.io
"npm outdated" as a service!
Node Security Project
npm install nsp -g
nsp check
Recap!
architecture
npm update
npm init
auto saving
.npm-init.js
devDependencies
bundledDependencies
offline installs
run scripts
publishing
SemVer
npm version
shrinkwrap
npm team
npm access
npm link
dist-tags
unpublish
deprecate
outdated
lifecycle events
.npmrc files
webhooks
...and more!
The bigger picture
npm wants to make your life easier
The web is
coming to npm
Really, it's been here for some time.
npm: the registry for
- node
- jQuery
- Grunt
- Gulp
- Ionic
- Cordova
- Nodebots
- Babel
- Atom
- TypeScript 2
- Angular
- Ember
- React
- Several thousand web frameworks
- More!
npm you
What can npm do for you?
Publish your apps to npm
Hook into your automation.
The more we know, the more we can help.
Coming soon: add-ons
Making the registry do more for you:
- security scanning
- license auditing
- code quality metrics
npm is just
getting started
One last thing
For lesbian, gay, bisexual, transgender, and queer people of all kinds in tech.
(this is nothing to do with npm)
Thank you!
npm you
Follow me on Twitter for no reason!
@seldo
Good questions get t-shirts!
EnterJS
By seldo
EnterJS
- 6,190