Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Bundler vs npm

Wei Lu
July 15, 2014

Bundler vs npm

Presented at Singapore Ruby meetup

Wei Lu

July 15, 2014
Tweet

More Decks by Wei Lu

Other Decks in Programming

Transcript

  1. Versioning gem ‘sinatra' gem 'sinatra', '1.4.5' gem 'sinatra', '>= 1.4.5’

    gem 'sinatra', '<= 1.4.5’ gem 'sinatra', '> 1.4.5’ gem 'sinatra', '< 1.4.5' gem 'sinatra', '~> 1.4.5’ "express" "express": "4.6.1" "express": ">=4.6.1" "express": "<=4.6.1" "express": ">4.6.1" "express": "<4.6.1" "express": "^4.6.1” "express": "~4.6.1"
  2. Semver MAJOR.MINOR.PATCH • MAJOR: backwards-incompatible API changes • MINOR: backwards-compatible

    functionality additions • PATCH: backwards-compatible bug fixes
  3. Semver ~> pessimistic operator • ~>1: >=1.0.0 <2.0.0 • ~>1.0:

    >=1.0.0 <2.0.0 • ~>1.2.3: >=1.2.3 <1.3.0 • ~>0.1: >=0.1.0 <1.0.0 • ~>0.1.3: >=0.1.3 <0.2.0 • ~>0.0.2: >=0.0.2 <0.1.0
  4. Semver ~ "reasonably close to” >= self < next significant

    digit + 1 • ~1: >=1.0.0 <2.0.0 • ~1.0: >=1.0.0 <1.1.0 • ~1.2.3: >=1.2.3 <1.3.0 ^ matches any version with the same first non-zero component starting at the specified version. • ^1: >=1.0.0 <2.0.0 • ^1.0: >=1.0.0 <2.0.0 • ^1.2.3: >=1.2.3 <2.0.0 • ^0.1: >=0.1.0 <0.2.0 • ^0.1.3: >=0.1.3 <0.2.0 • ^0.0.2: 0.0.2 • ~0.1: >=0.1.0 <0.2.0 • ~0.1.3: >=0.1.3 <0.2.0 • ~0.0.2: >=0.0.2 <0.1.0
  5. Dependency installation workflow add gem rubydramas to Gemfile bundle install!

    bundle show rubydramas! add spermy notation "~> 2.4.0" to Gemfile git add Gemfile*
  6. Dependency installation workflow Wouldn’t it be nice if bundlers does

    this? bundle install --save rubydramas! It already does this: bundle update rubydramas Idea designed by Joe Harrison from the Noun Project
  7. Breakage #1 1. Day 1, Dev A: npm install --save

    lovedrama 2. lovedrama ^1.2.0 snuck into package.json 3. Day 2, Dev B: npm install installs 1.4.0 If lovedrama doesn’t follow semver, stuff works for A breaks for B If lovedrama follows semver, B uses things that doesn’t exist for A. So stuff works for B breaks for A.*
  8. Breakage #2 1. lib lovedrama supports node 0.8 - 0.10.x

    2. lovedrama author introduces lib hdd as a dependency with npm install --save hdd 3. hdd ^1.0.0 snuck into package.json 4. lovedrama no longer supports node 0.8 The npm bundled with node 0.8 is unaware of ^. It breaks with No compatible version found
  9. Drama npm install --save default to ^ instead of ~

    Q: Should it be a major version bump for npm? A: ¯\_(ツ)_/¯
  10. Lock down dependency versions Why is it important? • Breakage

    #1: If lovedrama follows semver, B uses things that doesn’t exist for A. So stuff works for B breaks for A. • Production Deployment
  11. Lock down dependency versions Gemfile.lock • `bundle install` • check

    into version control rspec-core (2.14.7)! rspec-expectations (2.14.5)! diff-lcs (>= 1.1.3, < 2.0)! rspec-mocks (2.14.5)! rspec-rails (2.14.1)! actionpack (>= 3.0)! activemodel (>= 3.0)! activesupport (>= 3.0)! railties (>= 3.0)! rspec-core (~> 2.14.0)! rspec-expectations (~> 2.14.0)! rspec-mocks (~> 2.14.0)
  12. Lock down dependency versions Gemfile.lock • `bundle install` • check

    into version control npm-shrinkwrap.json • `npm shrinkwrap` • check into version control • breaks on peerDependency
  13. Single Root Namespace Yep If two different gems depend on

    different versions of the same dependency => fail
  14. Single Root Namespace Nope “the CommonJS Securable Module system lets

    you avoid dependency hell by modifying the require.paths at runtime, so that each package sees the version that it depends on”
  15. Resolving dependencies...! Bundler could not find compatible versions for gem

    "c" Single Root Namespace a! !"" b! #! $"" c@~1.0.21! $"" d! ! $"" c@~1.2.9! a! !"" b <-- depends on [email protected]! $"" d <-- depends on c@~1.2.9!
  16. Peer Dependencies {! "name": "winston-mail",! "peerDependencies": {! "winston": "<=0.6.3"! }!

    }! ! {! "dependencies": {! "winston": "0.6.2",! "winston-mail": "0.2.3"! }! } !"" [email protected]! $"" [email protected]!
  17. Peer Dependencies Breakage {! "name": "winston-mail",! "peerDependencies": {! "winston": ">=0.5.0

    <0.8.0"! }! }! ! {! "name": "foo",! "dependencies": {! "winston": "0.7.2",! "winston-mail": "0.2.7"! }! } [email protected] ! !"% [email protected] ! # $"" [email protected] invalid! $"" [email protected]
  18. Isaac Says… The only way to reasonably have peerDependencies and

    avoid the "psychedelic mess" is to implement a constraint solver But so far no one is stepping up to do that work (patch welcome!) and even if there was a courageous volunteer to take this on, it would take some time to get right, and be a rather big change requiring quite a bit of careful review.