Client-Side Packages

Domenic Denicola
Domenic DenicolaSoftware Engineer à Google Chrome
Client-Side Packages
Or, how I learned to stop worrying and love




                                              @DOMENIC
Domenic Denicola
› http://domenic.me
› https://github.com/domenic
› https://npmjs.org/~domenic
› http://slideshare.net/domenicdenicola


Things I’m doing:
› @esdiscuss on Twitter
› The Promises/A+ spec
› Creating truly RESTful APIs



                                          @DOMENIC
Modules



          @DOMENIC
Module systems express code dependencies
› 2000s state of the art:
  – One big file with carefully ordered functions, or
  – Many small files, and carefully ordered <script> tags
› Other languages solve this problem easily; in JS, until
  ES6, we have to solve it ourselves.
› We have two hacky solutions:
  – CommonJS modules
  – AMD modules
› CommonJS is better for code reuse.




                                                            @DOMENIC
CommonJS modules
› AMD:
define(['a', './b'], function (a, b) {
  return { c: 'd' };
});


› CommonJS:
var a = require('a');
var b = require('./b');

module.exports = { c: 'd' };




                                         @DOMENIC
The AMD configuration problem
› In require('a'), what does 'a' refer to?
  – AMD module called 'a' (per baseUrl config)
  – Some other AMD module (per map config)
  – Non-AMD code (per shim config)
  – AMD plugin (per plugin config)
  – A package’s main module (per packages config)


› In a CommonJS + npm system, the answer is always the
  main module for package 'a'.




                                                    @DOMENIC
The AMD dependency problem
› If Ember depends on RSVP.js, how does it express this in
  AMD?
  – require('rsvp') doesn’t cut it.
  – I know! We’ll use more config!
› Now your Ember-using project needs to know about
  Ember’s internal implementation details in order to make
  Ember’s require('rsvp') work, via configuration.
› This severely limits the extent to which library authors can
  bring in third-party code.
› Where did this 'rsvp' string come from anyway?

These are all problems to be solved by packages, but AMD
tries—and fails—to solve them at the module level.


                                                     @DOMENIC
AMD is not an advantage
› AMD tries to solve too many problems that are way
  beyond the level of a module system.
› CommonJS can solve all AMD use cases except cross-
  domain single-module loading.
› Using AMD cuts you off from consuming most module
  code out there.
› Your code is more universal with CommonJS. More tools
  consume it, and it’s easier to test.
› AMD users can use r.js to convert from CommonJS.




                                                 @DOMENIC
Enter Packages



                 @DOMENIC
Packages
› Modules let us reuse our own code.
› Packages let us reuse other people’s code.
› Examples of packages:
  – Backbone
  – Underscore
  – Sinon.JS
  – jQuery
  – jsdom
  – Express
› Packages have dependencies
  – E.g. Backbone depends on Underscore and jQuery




                                                     @DOMENIC
Packages as a unit of code reuse
› Packages are small, often one module.
› They can shuffle work off to their dependencies, allowing
  greater code reuse.
› If jQuery UI were composed of packages:
  – jqueryui-position depends on nothing
  – jqueryui-mouse depends on jqueryui-core, jqueryui-widget
  – jqueryui-autocomplete depends on core, widget, menu, position
  – etc.
› ―Download builders‖ are hacky and un-encapsulated ways
  of solving package management.
› Multi-thousand line modules belong in the 2000s.



                                                        @DOMENIC
Packages can be versioned independently
› When you separate functionality into small packages, you
  aren’t tied to monolithic, coordinated release cycles.
› By depending on small packages, you can get bug fixes
  and new features as soon as their authors publish them.
› Then users of your package get bug fixes, without you
  doing anything!
› Conventionally, we try to adhere to semantic versioning:
  – 0.x.y releases: unstable; upgrade at your peril.
  – 1.x.y and beyond:
    › Increasing ―patch version‖ y means bug fixes.
    › Increasing ―minor version‖ x means new features.
    › Increasing ―major version‖ means new API, breaking backward-compat.
  – So we can express dependencies as 0.1.2 or 2.x or 2.3.x to get
    the benefits of independent versioning.

                                                                @DOMENIC
Packages can be app-specific
› Each ―widget‖ can be a package.
  – Sidebar, header, currency table, news ticker, …
› Or you could have packages for business logic.
  – Financial calculations, market predictions, discount rules, …
› Or you can isolate hard problems in packages.
  – Talking to SMTP servers, traversing a RESTful API, rendering
    PDFs with JavaScript, sandboxing user input, …
› They can separate out cross-cutting concerns.
  – Number formatting, CSS theming, injecting logging and error
    handling, …
› They can even help with domain-driven design.
  – Encapsulating bounded contexts, exposing services, isolating a
    shared kernel, building an anticorruption layer, …


                                                           @DOMENIC
Packages with npm



                    @DOMENIC
What problems do we need to solve?
› Get code onto our computers
› Automatically install expressed dependencies
› Have a way for one package’s code to ―require‖ another
  package’s code.
› Make other peoples’ code available to you




                                                 @DOMENIC
npm stands for JavaScript package manager
› 26,000 packages and growing
› The emphasis on small packages means many work in the
  browser already.
› The npm registry is anarchic.
  – This makes package discovery tricky, but in balance is a big win.
  – Server code, browser code, even AMD code: it’s all welcome.
  – A single namespace means no enforced prefixing.
› npm packages follow a set of conventions that make your
  life easy.




                                                           @DOMENIC
What’s in an npm package?
› lib/
   – index.js
   – AuxiliaryClass.js
   – helpers.js
› test/
› LICENSE.txt
› README.md
› package.json
› .jshintrc, .gitignore, .npmignore, .travis.yml, …




                                                      @DOMENIC
package.json
{
    "name": "sinon-chai",
    "description": "Extends Chai with assertions for Sinon.JS.",
    "keywords": ["sinon", "chai", "testing", "spies", "stubs", "mocks"],
    "version": "2.3.1",
    "author": "Domenic Denicola <domenic@domenicdenicola.com>",
    "license": "WTFPL",
    "repository": {
      "type": "git",
      "url": "git://github.com/domenic/sinon-chai.git"
    },
    "main": "./lib/sinon-chai.js",
    ⋮



                                                                @DOMENIC
package.json
    ⋮
    "dependencies": {
      "sinon": ">= 1.5 <2"
    },
    "peerDependencies": {
      "chai": ">= 1.3.0 <2"
    },
    "devDependencies": {
      "coffee-script": "~1.6",
      "jshint": "~1.1",
      "mocha": "~1.7",
    },
    "scripts": {
      "test": "mocha",
      "lint": "jshint ./lib"
    }
}                                @DOMENIC
Packages are encapsulation boundaries
› Single point of entry API via the main module:
  – require("backbone")
  – require("underscore")
  – require("sinon-chai")
  – require("express")
› You don’t need to know about a package’s dependencies
  – Unlike AMD!
› You don’t need to know about a package’s strategy
  – Client-side MVC framework choice, templating engine, CSS
    precompiler, …




                                                       @DOMENIC
Packages are concern boundaries
› Their own license
› Their own readme
› Their own coding style and linting rules
› Their own compile-to-JS authoring language
› Their own tests and test style
› Their own author/owner/maintainer




                                               @DOMENIC
Dependencies



               @DOMENIC
npm dependency basics
› npm uses a global registry by default: https://npmjs.org
  – A CouchDB server: http://isaacs.ic.ht/_utils/
› It uses package.json to install dependencies




                                                    @DOMENIC
Dependencies are hierarchical
› Unlike some other package managers, there is no global shared
  ―DLL hell‖ of packages on your system.
› They get installed in a hierarchy of node_modules folders:


request@2.12.0
├─┬ form-data@0.0.3
│ ├── async@0.1.9
│ └─┬ combined-stream@0.0.3
│   └── delayed-stream@0.0.5
└── mime@1.2.7
request/node_modules/form-data
request/node_modules/form-data/node_modules/async
request/node_modules/form-
data/node_modules/async/node_modules/combined-stream
⋮


                                                        @DOMENIC
Git dependencies
› Dependencies can be Git URLs
› Useful for pointing to forked-and-patched versions of a
  library while you wait for your pull request to land.
› Useful for private Git servers.
› For GitHub, use "package": "user/repo#version" syntax.
› This allows an escape hatch from the central registry and
  its single namespace, if you’re into that.




                                                   @DOMENIC
Other important npm features
› npm dedupe: creates the minimal dependency tree that
  satisfies everyone’s versions
› npm link: symlinks, for local development
› The "scripts" field in package.json can give you arbitrary
  scripts which have access to your devDependencies.
  – npm run <scriptName>
  – npm test (shortcut for npm run test)
› Packages can have arbitrary metadata: it’s just JSON!




                                                     @DOMENIC
Private Code



               @DOMENIC
How can we use this without publishing?
› We can’t put proprietary code in the npm registry.
› But we’d still like to use the package concept, and npm’s
  features.
› There are hacks:
  – npm link
  – Using Git URLs entirely (this actually works pretty well).
› But, really we need our own registry!




                                                             @DOMENIC
Your own registry
› CouchDB is really good at replicating. So just do that!
› Then:
  npm install lab49-ip –reg http://npm.lab49.org


› You can use the publishConfig settings in package.json to
  make a given package automatically publish to your
  internal registry, instead of the public one.
› We’re working on ―fallback registries,‖ to obviate the
  replication step.




                                                     @DOMENIC
Packages, Client-Side



                        @DOMENIC
A note on CSS
› Just include it in your package!
› Don’t reference it from your JS, e.g. automatically inject it
  into the page.
› It shouldn’t matter whether the CSS is in
  node_modules/mywidget or in app/widgets.
› The application’s build tool will consume it, if the
  application author needs it; otherwise it sits inert.




                                                          @DOMENIC
Browserify!
› The best solution for bringing CommonJS modules and
  npm packages to the browser.
› Shims common (and not-so-common) Node APIs to give
  you access to many npm packages.
  – events, path, url, querystring, vm, http, crypto, zlib (!) and more…
› Understands npm’s node_modules structure.
› Has a flexible pipeline and vibrant ecosystem, for e.g.
  source map support or just-in-time bundle compilation
  when embedded in simple HTTP servers.
› Allows packages to declare source transforms and browser
  overrides in their package.json metadata.



                                                             @DOMENIC
Discovering client-side packages
› We trust packages most if they are validated by continuous
  integration, e.g. by Travis CI:




› We can trust client-side packages if they are validated by
  testling-ci:




                                                    @DOMENIC
Testling-ci setup
In package.json:
"testling": {
  "browsers": [
    "ie/7..10",
    "firefox/10..13", "firefox/nightly",
    "chrome/14..16", "chrome/canary",
    "safari/5.0.5..latest",
    "opera/10.6", ―opera/11.0", "opera/11.6",
    "iphone/6",
    "ipad/6",
    "android/4.2"
  },
  "harness": "mocha",
  "files": "test/tests.js―
}


                                                @DOMENIC
browserify.org/search




                        @DOMENIC
Demo
https://github.com/domenic/client-side-packages-demo




                                             @DOMENIC
› Make sure all your code is in
WHAT’S NEXT     CommonJS module format.
              › Then organize that code into
                packages.
              › Consume other peoples packages.
              › Start publishing to npm—or to a
                private registry.
              › Use browserify in your build process
                (or in your server).
              › Use testling-ci to encourage trust
                and discovery.




                                           @DOMENIC
1 sur 37

Recommandé

2013 04-02-server-side-backbone par
2013 04-02-server-side-backbone2013 04-02-server-side-backbone
2013 04-02-server-side-backboneSC5.io
10.4K vues25 diapositives
Web Technologies in Java EE 7 par
Web Technologies in Java EE 7Web Technologies in Java EE 7
Web Technologies in Java EE 7Lukáš Fryč
2.2K vues78 diapositives
Java presentation par
Java presentationJava presentation
Java presentationKaran Sareen
2.8K vues175 diapositives
Open Social Summit Korea par
Open Social Summit KoreaOpen Social Summit Korea
Open Social Summit KoreaArne Roomann-Kurrik
1.1K vues90 diapositives
Jalimo Slides Linuxtag2007 (English) par
Jalimo Slides Linuxtag2007 (English)Jalimo Slides Linuxtag2007 (English)
Jalimo Slides Linuxtag2007 (English)smancke
701 vues36 diapositives
Gwt ppt par
Gwt pptGwt ppt
Gwt pptMonica Bubna
1.4K vues52 diapositives

Contenu connexe

Tendances

GWT- Google Web Toolkit par
GWT- Google Web ToolkitGWT- Google Web Toolkit
GWT- Google Web ToolkitMomentum Design Lab
2.6K vues11 diapositives
J2EE Struts with Hibernate Framework par
J2EE Struts with Hibernate FrameworkJ2EE Struts with Hibernate Framework
J2EE Struts with Hibernate Frameworkmparth
575 vues17 diapositives
Java & J2EE Struts with Hibernate Framework par
Java & J2EE Struts with Hibernate FrameworkJava & J2EE Struts with Hibernate Framework
Java & J2EE Struts with Hibernate FrameworkMohit Belwal
11.4K vues101 diapositives
Jsf2 html5-jazoon par
Jsf2 html5-jazoonJsf2 html5-jazoon
Jsf2 html5-jazoonRoger Kitain
5.8K vues37 diapositives
Introduction To J Boss Seam par
Introduction To J Boss SeamIntroduction To J Boss Seam
Introduction To J Boss Seamashishkulkarni
2.5K vues21 diapositives
Geneva Jug (30th March, 2010) - Maven par
Geneva Jug (30th March, 2010) - MavenGeneva Jug (30th March, 2010) - Maven
Geneva Jug (30th March, 2010) - MavenArnaud Héritier
1.3K vues138 diapositives

Tendances(20)

J2EE Struts with Hibernate Framework par mparth
J2EE Struts with Hibernate FrameworkJ2EE Struts with Hibernate Framework
J2EE Struts with Hibernate Framework
mparth575 vues
Java & J2EE Struts with Hibernate Framework par Mohit Belwal
Java & J2EE Struts with Hibernate FrameworkJava & J2EE Struts with Hibernate Framework
Java & J2EE Struts with Hibernate Framework
Mohit Belwal11.4K vues
Lecture java basics par eleksdev
Lecture   java basicsLecture   java basics
Lecture java basics
eleksdev3.7K vues
As7 web services - JUG Milan April 2012 par alepalin
As7 web services - JUG Milan April 2012As7 web services - JUG Milan April 2012
As7 web services - JUG Milan April 2012
alepalin574 vues
Kandroid for nhn_deview_20131013_v5_final par NAVER D2
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_final
NAVER D22.9K vues
Easy as pie creating widgets for ibm connections par LetsConnect
Easy as pie   creating widgets for ibm connectionsEasy as pie   creating widgets for ibm connections
Easy as pie creating widgets for ibm connections
LetsConnect781 vues
AD111 -- Harnessing the Power of Server-Side JavaScript and Other Advanced XP... par ddrschiw
AD111 -- Harnessing the Power of Server-Side JavaScript and Other Advanced XP...AD111 -- Harnessing the Power of Server-Side JavaScript and Other Advanced XP...
AD111 -- Harnessing the Power of Server-Side JavaScript and Other Advanced XP...
ddrschiw2.3K vues
Java EE 6 & GlassFish 3 par Arun Gupta
Java EE 6 & GlassFish 3Java EE 6 & GlassFish 3
Java EE 6 & GlassFish 3
Arun Gupta3.2K vues
GR8Conf 2011: Adopting Grails par GR8Conf
GR8Conf 2011: Adopting GrailsGR8Conf 2011: Adopting Grails
GR8Conf 2011: Adopting Grails
GR8Conf660 vues
WordPress and Zend Framework Integration with Vulnero par Andrew Kandels
WordPress and Zend Framework Integration with VulneroWordPress and Zend Framework Integration with Vulnero
WordPress and Zend Framework Integration with Vulnero
Andrew Kandels3.5K vues

En vedette

Real World Windows 8 Apps in JavaScript par
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptDomenic Denicola
2.1K vues15 diapositives
ES6 is Nigh par
ES6 is NighES6 is Nigh
ES6 is NighDomenic Denicola
8K vues56 diapositives
Creating Truly RESTful APIs par
Creating Truly RESTful APIsCreating Truly RESTful APIs
Creating Truly RESTful APIsDomenic Denicola
17K vues19 diapositives
The Final Frontier par
The Final FrontierThe Final Frontier
The Final FrontierDomenic Denicola
2.7K vues31 diapositives
jQuery Anti-Patterns for Performance & Compression par
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
25.2K vues68 diapositives
Using Objects to Organize your jQuery Code par
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery CodeRebecca Murphey
20.5K vues23 diapositives

En vedette(20)

Real World Windows 8 Apps in JavaScript par Domenic Denicola
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScript
Domenic Denicola2.1K vues
jQuery Anti-Patterns for Performance & Compression par Paul Irish
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish25.2K vues
Using Objects to Organize your jQuery Code par Rebecca Murphey
Using Objects to Organize your jQuery CodeUsing Objects to Organize your jQuery Code
Using Objects to Organize your jQuery Code
Rebecca Murphey20.5K vues
JavaScript - new features in ECMAScript 6 par Solution4Future
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
Solution4Future21.8K vues
ES6 - Next Generation Javascript par Ramesh Nair
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
Ramesh Nair12.3K vues
jQuery Proven Performance Tips & Tricks par Addy Osmani
jQuery Proven Performance Tips & TricksjQuery Proven Performance Tips & Tricks
jQuery Proven Performance Tips & Tricks
Addy Osmani175.6K vues
ES2015 (ES6) Overview par hesher
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
hesher22.4K vues
Learning jQuery in 30 minutes par Simon Willison
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
Simon Willison53.4K vues

Similaire à Client-Side Packages

I Just Want to Run My Code: Waypoint, Nomad, and Other Things par
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsMichael Lange
35 vues57 diapositives
Node js meetup par
Node js meetupNode js meetup
Node js meetupAnsuman Roy
275 vues37 diapositives
Overview of Node JS par
Overview of Node JSOverview of Node JS
Overview of Node JSJacob Nelson
3.7K vues50 diapositives
Demystifying Containerization Principles for Data Scientists par
Demystifying Containerization Principles for Data ScientistsDemystifying Containerization Principles for Data Scientists
Demystifying Containerization Principles for Data ScientistsDr Ganesh Iyer
198 vues92 diapositives
CD in kubernetes using helm and ksonnet. Stas Kolenkin par
CD in kubernetes using helm and ksonnet. Stas KolenkinCD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas KolenkinDataArt
568 vues64 diapositives
Php Dependency Management with Composer ZendCon 2017 par
Php Dependency Management with Composer ZendCon 2017Php Dependency Management with Composer ZendCon 2017
Php Dependency Management with Composer ZendCon 2017Clark Everetts
670 vues87 diapositives

Similaire à Client-Side Packages(20)

I Just Want to Run My Code: Waypoint, Nomad, and Other Things par Michael Lange
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
Michael Lange35 vues
Demystifying Containerization Principles for Data Scientists par Dr Ganesh Iyer
Demystifying Containerization Principles for Data ScientistsDemystifying Containerization Principles for Data Scientists
Demystifying Containerization Principles for Data Scientists
Dr Ganesh Iyer198 vues
CD in kubernetes using helm and ksonnet. Stas Kolenkin par DataArt
CD in kubernetes using helm and ksonnet. Stas KolenkinCD in kubernetes using helm and ksonnet. Stas Kolenkin
CD in kubernetes using helm and ksonnet. Stas Kolenkin
DataArt568 vues
Php Dependency Management with Composer ZendCon 2017 par Clark Everetts
Php Dependency Management with Composer ZendCon 2017Php Dependency Management with Composer ZendCon 2017
Php Dependency Management with Composer ZendCon 2017
Clark Everetts670 vues
Deploying Perl apps on dotCloud par daoswald
Deploying Perl apps on dotCloudDeploying Perl apps on dotCloud
Deploying Perl apps on dotCloud
daoswald2.5K vues
Настройка окружения для кросскомпиляции проектов на основе docker'a par corehard_by
Настройка окружения для кросскомпиляции проектов на основе docker'aНастройка окружения для кросскомпиляции проектов на основе docker'a
Настройка окружения для кросскомпиляции проектов на основе docker'a
corehard_by174 vues
Pilot Tech Talk #10 — Practical automation by Kamil Cholewiński par Pilot
Pilot Tech Talk #10 — Practical automation by Kamil CholewińskiPilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot180 vues
Node js (runtime environment + js library) platform par Sreenivas Kappala
Node js (runtime environment + js library) platformNode js (runtime environment + js library) platform
Node js (runtime environment + js library) platform
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP par Dana Luther
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHPHands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Dana Luther408 vues
Packaging perl (LPW2010) par p3castro
Packaging perl (LPW2010)Packaging perl (LPW2010)
Packaging perl (LPW2010)
p3castro2.1K vues
From development environments to production deployments with Docker, Compose,... par Jérôme Petazzoni
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK par StorageOS
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UKStorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK
StorageOS, Storage for Containers Shouldn't Be Annoying at Container Camp UK
StorageOS499 vues
Intro to Node.js (v1) par Chris Cowan
Intro to Node.js (v1)Intro to Node.js (v1)
Intro to Node.js (v1)
Chris Cowan1.5K vues
Dependencies Managers in C/C++. Using stdcpp 2014 par biicode
Dependencies Managers in C/C++. Using stdcpp 2014Dependencies Managers in C/C++. Using stdcpp 2014
Dependencies Managers in C/C++. Using stdcpp 2014
biicode4.4K vues
Containers, Docker, and Microservices: the Terrific Trio par Jérôme Petazzoni
Containers, Docker, and Microservices: the Terrific TrioContainers, Docker, and Microservices: the Terrific Trio
Containers, Docker, and Microservices: the Terrific Trio
Jérôme Petazzoni17.7K vues
LXC, Docker, and the future of software delivery | LinuxCon 2013 par dotCloud
LXC, Docker, and the future of software delivery | LinuxCon 2013LXC, Docker, and the future of software delivery | LinuxCon 2013
LXC, Docker, and the future of software delivery | LinuxCon 2013
dotCloud12.8K vues

Plus de Domenic Denicola

The State of JavaScript (2015) par
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)Domenic Denicola
24K vues34 diapositives
ES6 in Real Life par
ES6 in Real LifeES6 in Real Life
ES6 in Real LifeDomenic Denicola
5.5K vues21 diapositives
Streams for the Web par
Streams for the WebStreams for the Web
Streams for the WebDomenic Denicola
7.4K vues38 diapositives
After Return of the Jedi par
After Return of the JediAfter Return of the Jedi
After Return of the JediDomenic Denicola
2.7K vues24 diapositives
The State of JavaScript par
The State of JavaScriptThe State of JavaScript
The State of JavaScriptDomenic Denicola
4.2K vues48 diapositives
How to Win Friends and Influence Standards Bodies par
How to Win Friends and Influence Standards BodiesHow to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesDomenic Denicola
1.5K vues34 diapositives

Plus de Domenic Denicola(10)

Dernier

Business Analyst Series 2023 - Week 4 Session 7 par
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7DianaGray10
126 vues31 diapositives
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti... par
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...ShapeBlue
98 vues29 diapositives
Network Source of Truth and Infrastructure as Code revisited par
Network Source of Truth and Infrastructure as Code revisitedNetwork Source of Truth and Infrastructure as Code revisited
Network Source of Truth and Infrastructure as Code revisitedNetwork Automation Forum
52 vues45 diapositives
The Role of Patterns in the Era of Large Language Models par
The Role of Patterns in the Era of Large Language ModelsThe Role of Patterns in the Era of Large Language Models
The Role of Patterns in the Era of Large Language ModelsYunyao Li
80 vues65 diapositives
The Power of Heat Decarbonisation Plans in the Built Environment par
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built EnvironmentIES VE
69 vues20 diapositives
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue par
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlueShapeBlue
103 vues23 diapositives

Dernier(20)

Business Analyst Series 2023 - Week 4 Session 7 par DianaGray10
Business Analyst Series 2023 -  Week 4 Session 7Business Analyst Series 2023 -  Week 4 Session 7
Business Analyst Series 2023 - Week 4 Session 7
DianaGray10126 vues
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti... par ShapeBlue
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...
DRaaS using Snapshot copy and destination selection (DRaaS) - Alexandre Matti...
ShapeBlue98 vues
The Role of Patterns in the Era of Large Language Models par Yunyao Li
The Role of Patterns in the Era of Large Language ModelsThe Role of Patterns in the Era of Large Language Models
The Role of Patterns in the Era of Large Language Models
Yunyao Li80 vues
The Power of Heat Decarbonisation Plans in the Built Environment par IES VE
The Power of Heat Decarbonisation Plans in the Built EnvironmentThe Power of Heat Decarbonisation Plans in the Built Environment
The Power of Heat Decarbonisation Plans in the Built Environment
IES VE69 vues
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue par ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
2FA and OAuth2 in CloudStack - Andrija Panić - ShapeBlue
ShapeBlue103 vues
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... par James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson156 vues
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online par ShapeBlue
KVM Security Groups Under the Hood - Wido den Hollander - Your.OnlineKVM Security Groups Under the Hood - Wido den Hollander - Your.Online
KVM Security Groups Under the Hood - Wido den Hollander - Your.Online
ShapeBlue181 vues
NTGapps NTG LowCode Platform par Mustafa Kuğu
NTGapps NTG LowCode Platform NTGapps NTG LowCode Platform
NTGapps NTG LowCode Platform
Mustafa Kuğu365 vues
Developments to CloudStack’s SDN ecosystem: Integration with VMWare NSX 4 - P... par ShapeBlue
Developments to CloudStack’s SDN ecosystem: Integration with VMWare NSX 4 - P...Developments to CloudStack’s SDN ecosystem: Integration with VMWare NSX 4 - P...
Developments to CloudStack’s SDN ecosystem: Integration with VMWare NSX 4 - P...
ShapeBlue154 vues
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas... par Bernd Ruecker
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
iSAQB Software Architecture Gathering 2023: How Process Orchestration Increas...
Bernd Ruecker50 vues
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive par Network Automation Forum
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLiveAutomating a World-Class Technology Conference; Behind the Scenes of CiscoLive
Automating a World-Class Technology Conference; Behind the Scenes of CiscoLive
State of the Union - Rohit Yadav - Apache CloudStack par ShapeBlue
State of the Union - Rohit Yadav - Apache CloudStackState of the Union - Rohit Yadav - Apache CloudStack
State of the Union - Rohit Yadav - Apache CloudStack
ShapeBlue253 vues
Data Integrity for Banking and Financial Services par Precisely
Data Integrity for Banking and Financial ServicesData Integrity for Banking and Financial Services
Data Integrity for Banking and Financial Services
Precisely78 vues
How to Re-use Old Hardware with CloudStack. Saving Money and the Environment ... par ShapeBlue
How to Re-use Old Hardware with CloudStack. Saving Money and the Environment ...How to Re-use Old Hardware with CloudStack. Saving Money and the Environment ...
How to Re-use Old Hardware with CloudStack. Saving Money and the Environment ...
ShapeBlue123 vues
DRBD Deep Dive - Philipp Reisner - LINBIT par ShapeBlue
DRBD Deep Dive - Philipp Reisner - LINBITDRBD Deep Dive - Philipp Reisner - LINBIT
DRBD Deep Dive - Philipp Reisner - LINBIT
ShapeBlue140 vues
CloudStack Managed User Data and Demo - Harikrishna Patnala - ShapeBlue par ShapeBlue
CloudStack Managed User Data and Demo - Harikrishna Patnala - ShapeBlueCloudStack Managed User Data and Demo - Harikrishna Patnala - ShapeBlue
CloudStack Managed User Data and Demo - Harikrishna Patnala - ShapeBlue
ShapeBlue94 vues

Client-Side Packages

  • 1. Client-Side Packages Or, how I learned to stop worrying and love @DOMENIC
  • 2. Domenic Denicola › http://domenic.me › https://github.com/domenic › https://npmjs.org/~domenic › http://slideshare.net/domenicdenicola Things I’m doing: › @esdiscuss on Twitter › The Promises/A+ spec › Creating truly RESTful APIs @DOMENIC
  • 3. Modules @DOMENIC
  • 4. Module systems express code dependencies › 2000s state of the art: – One big file with carefully ordered functions, or – Many small files, and carefully ordered <script> tags › Other languages solve this problem easily; in JS, until ES6, we have to solve it ourselves. › We have two hacky solutions: – CommonJS modules – AMD modules › CommonJS is better for code reuse. @DOMENIC
  • 5. CommonJS modules › AMD: define(['a', './b'], function (a, b) { return { c: 'd' }; }); › CommonJS: var a = require('a'); var b = require('./b'); module.exports = { c: 'd' }; @DOMENIC
  • 6. The AMD configuration problem › In require('a'), what does 'a' refer to? – AMD module called 'a' (per baseUrl config) – Some other AMD module (per map config) – Non-AMD code (per shim config) – AMD plugin (per plugin config) – A package’s main module (per packages config) › In a CommonJS + npm system, the answer is always the main module for package 'a'. @DOMENIC
  • 7. The AMD dependency problem › If Ember depends on RSVP.js, how does it express this in AMD? – require('rsvp') doesn’t cut it. – I know! We’ll use more config! › Now your Ember-using project needs to know about Ember’s internal implementation details in order to make Ember’s require('rsvp') work, via configuration. › This severely limits the extent to which library authors can bring in third-party code. › Where did this 'rsvp' string come from anyway? These are all problems to be solved by packages, but AMD tries—and fails—to solve them at the module level. @DOMENIC
  • 8. AMD is not an advantage › AMD tries to solve too many problems that are way beyond the level of a module system. › CommonJS can solve all AMD use cases except cross- domain single-module loading. › Using AMD cuts you off from consuming most module code out there. › Your code is more universal with CommonJS. More tools consume it, and it’s easier to test. › AMD users can use r.js to convert from CommonJS. @DOMENIC
  • 9. Enter Packages @DOMENIC
  • 10. Packages › Modules let us reuse our own code. › Packages let us reuse other people’s code. › Examples of packages: – Backbone – Underscore – Sinon.JS – jQuery – jsdom – Express › Packages have dependencies – E.g. Backbone depends on Underscore and jQuery @DOMENIC
  • 11. Packages as a unit of code reuse › Packages are small, often one module. › They can shuffle work off to their dependencies, allowing greater code reuse. › If jQuery UI were composed of packages: – jqueryui-position depends on nothing – jqueryui-mouse depends on jqueryui-core, jqueryui-widget – jqueryui-autocomplete depends on core, widget, menu, position – etc. › ―Download builders‖ are hacky and un-encapsulated ways of solving package management. › Multi-thousand line modules belong in the 2000s. @DOMENIC
  • 12. Packages can be versioned independently › When you separate functionality into small packages, you aren’t tied to monolithic, coordinated release cycles. › By depending on small packages, you can get bug fixes and new features as soon as their authors publish them. › Then users of your package get bug fixes, without you doing anything! › Conventionally, we try to adhere to semantic versioning: – 0.x.y releases: unstable; upgrade at your peril. – 1.x.y and beyond: › Increasing ―patch version‖ y means bug fixes. › Increasing ―minor version‖ x means new features. › Increasing ―major version‖ means new API, breaking backward-compat. – So we can express dependencies as 0.1.2 or 2.x or 2.3.x to get the benefits of independent versioning. @DOMENIC
  • 13. Packages can be app-specific › Each ―widget‖ can be a package. – Sidebar, header, currency table, news ticker, … › Or you could have packages for business logic. – Financial calculations, market predictions, discount rules, … › Or you can isolate hard problems in packages. – Talking to SMTP servers, traversing a RESTful API, rendering PDFs with JavaScript, sandboxing user input, … › They can separate out cross-cutting concerns. – Number formatting, CSS theming, injecting logging and error handling, … › They can even help with domain-driven design. – Encapsulating bounded contexts, exposing services, isolating a shared kernel, building an anticorruption layer, … @DOMENIC
  • 14. Packages with npm @DOMENIC
  • 15. What problems do we need to solve? › Get code onto our computers › Automatically install expressed dependencies › Have a way for one package’s code to ―require‖ another package’s code. › Make other peoples’ code available to you @DOMENIC
  • 16. npm stands for JavaScript package manager › 26,000 packages and growing › The emphasis on small packages means many work in the browser already. › The npm registry is anarchic. – This makes package discovery tricky, but in balance is a big win. – Server code, browser code, even AMD code: it’s all welcome. – A single namespace means no enforced prefixing. › npm packages follow a set of conventions that make your life easy. @DOMENIC
  • 17. What’s in an npm package? › lib/ – index.js – AuxiliaryClass.js – helpers.js › test/ › LICENSE.txt › README.md › package.json › .jshintrc, .gitignore, .npmignore, .travis.yml, … @DOMENIC
  • 18. package.json { "name": "sinon-chai", "description": "Extends Chai with assertions for Sinon.JS.", "keywords": ["sinon", "chai", "testing", "spies", "stubs", "mocks"], "version": "2.3.1", "author": "Domenic Denicola <domenic@domenicdenicola.com>", "license": "WTFPL", "repository": { "type": "git", "url": "git://github.com/domenic/sinon-chai.git" }, "main": "./lib/sinon-chai.js", ⋮ @DOMENIC
  • 19. package.json ⋮ "dependencies": { "sinon": ">= 1.5 <2" }, "peerDependencies": { "chai": ">= 1.3.0 <2" }, "devDependencies": { "coffee-script": "~1.6", "jshint": "~1.1", "mocha": "~1.7", }, "scripts": { "test": "mocha", "lint": "jshint ./lib" } } @DOMENIC
  • 20. Packages are encapsulation boundaries › Single point of entry API via the main module: – require("backbone") – require("underscore") – require("sinon-chai") – require("express") › You don’t need to know about a package’s dependencies – Unlike AMD! › You don’t need to know about a package’s strategy – Client-side MVC framework choice, templating engine, CSS precompiler, … @DOMENIC
  • 21. Packages are concern boundaries › Their own license › Their own readme › Their own coding style and linting rules › Their own compile-to-JS authoring language › Their own tests and test style › Their own author/owner/maintainer @DOMENIC
  • 22. Dependencies @DOMENIC
  • 23. npm dependency basics › npm uses a global registry by default: https://npmjs.org – A CouchDB server: http://isaacs.ic.ht/_utils/ › It uses package.json to install dependencies @DOMENIC
  • 24. Dependencies are hierarchical › Unlike some other package managers, there is no global shared ―DLL hell‖ of packages on your system. › They get installed in a hierarchy of node_modules folders: request@2.12.0 ├─┬ form-data@0.0.3 │ ├── async@0.1.9 │ └─┬ combined-stream@0.0.3 │ └── delayed-stream@0.0.5 └── mime@1.2.7 request/node_modules/form-data request/node_modules/form-data/node_modules/async request/node_modules/form- data/node_modules/async/node_modules/combined-stream ⋮ @DOMENIC
  • 25. Git dependencies › Dependencies can be Git URLs › Useful for pointing to forked-and-patched versions of a library while you wait for your pull request to land. › Useful for private Git servers. › For GitHub, use "package": "user/repo#version" syntax. › This allows an escape hatch from the central registry and its single namespace, if you’re into that. @DOMENIC
  • 26. Other important npm features › npm dedupe: creates the minimal dependency tree that satisfies everyone’s versions › npm link: symlinks, for local development › The "scripts" field in package.json can give you arbitrary scripts which have access to your devDependencies. – npm run <scriptName> – npm test (shortcut for npm run test) › Packages can have arbitrary metadata: it’s just JSON! @DOMENIC
  • 27. Private Code @DOMENIC
  • 28. How can we use this without publishing? › We can’t put proprietary code in the npm registry. › But we’d still like to use the package concept, and npm’s features. › There are hacks: – npm link – Using Git URLs entirely (this actually works pretty well). › But, really we need our own registry! @DOMENIC
  • 29. Your own registry › CouchDB is really good at replicating. So just do that! › Then: npm install lab49-ip –reg http://npm.lab49.org › You can use the publishConfig settings in package.json to make a given package automatically publish to your internal registry, instead of the public one. › We’re working on ―fallback registries,‖ to obviate the replication step. @DOMENIC
  • 31. A note on CSS › Just include it in your package! › Don’t reference it from your JS, e.g. automatically inject it into the page. › It shouldn’t matter whether the CSS is in node_modules/mywidget or in app/widgets. › The application’s build tool will consume it, if the application author needs it; otherwise it sits inert. @DOMENIC
  • 32. Browserify! › The best solution for bringing CommonJS modules and npm packages to the browser. › Shims common (and not-so-common) Node APIs to give you access to many npm packages. – events, path, url, querystring, vm, http, crypto, zlib (!) and more… › Understands npm’s node_modules structure. › Has a flexible pipeline and vibrant ecosystem, for e.g. source map support or just-in-time bundle compilation when embedded in simple HTTP servers. › Allows packages to declare source transforms and browser overrides in their package.json metadata. @DOMENIC
  • 33. Discovering client-side packages › We trust packages most if they are validated by continuous integration, e.g. by Travis CI: › We can trust client-side packages if they are validated by testling-ci: @DOMENIC
  • 34. Testling-ci setup In package.json: "testling": { "browsers": [ "ie/7..10", "firefox/10..13", "firefox/nightly", "chrome/14..16", "chrome/canary", "safari/5.0.5..latest", "opera/10.6", ―opera/11.0", "opera/11.6", "iphone/6", "ipad/6", "android/4.2" }, "harness": "mocha", "files": "test/tests.js― } @DOMENIC
  • 37. › Make sure all your code is in WHAT’S NEXT CommonJS module format. › Then organize that code into packages. › Consume other peoples packages. › Start publishing to npm—or to a private registry. › Use browserify in your build process (or in your server). › Use testling-ci to encourage trust and discovery. @DOMENIC

Notes de l'éditeur

  1. Intro: units of code reuse.FunctionsModulesPackages
  2. I work at Lab49 in NYC with smart people.
  3. “Code dependency” is a very low-level thing. Functions express code dependencies too; modules are only slightly higher level than that (and sometimes at the same level)AMD is definitely better than nothing, so I won’t fault you for using it. But as you’ll see, it’s the worse option for apps that need true code reuse.
  4. AMD has leaned on excessive configuration to solve problems that are best solved by a package management system/In a CommonJS system alone, require(&apos;a&apos;) is meaningless---because module systems are just about files!
  5. Large projects will always want to break themselves up into reusable pieces at a larger level than just modules. Third party dependencies are a great example. But how do you express that kind of dependency in AMD?
  6. Problems beyond a module system: that’s why the config exists. Shims, baseUrls, packages, maps… Especially plugins. Modules should just be files!So. These problems should not be solved at the module level. Where should they be solved?
  7. By using CommonJS, we’ve solved one level of code reuse, without overstretching
  8. I mean “our own code” very literally---I think without packages, you can’t scale beyond a single person.
  9. Can you imagine not having to go back to their site, re-input what you had before, click the new box, download the file, overwrite the last one, and check it into source control (even though it’s not code you authored)?
  10. The first two are solved by the package manager, a command-line program.The third is solved by mapping package names to their main modules.The fourth is solved by a central registry.
  11. 26K is important, because package ecosystems are heavily empowered by network effects. Small packages can still be powerful in an ecosystem like that.
  12. You can have a header widget coded in Backbone and Stylus, while your folder list widget uses jQuery UI sortable and SASS.The single entry-point API makes it easy to create simple interfaces and contracts, e.g. “exposes a render method that returns a document fragment” or similar.
  13. npm test = a universal format for testing packages, no matter how they were authored
  14. Let’s get this out of the way.
  15. Npm gets packages onto your computer; browserify gets them from their into your browser.
  16. This is the .travis.yml for client-side packages.You can use “harness” OR anything that outputs tap
  17. You want to reuse code? Do these things.