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

Saving Sprockets

Saving Sprockets

Richard Schneeman

May 06, 2016
Tweet

More Decks by Richard Schneeman

Other Decks in Programming

Transcript

  1. Type to enter
    text
    Saving
    Sprockets

    View Slide

  2. 2016
    @schneems
    Saving
    Sprockets

    View Slide

  3. View Slide

  4. View Slide

  5. Why does
    sprockets
    need saving?

    View Slide

  6. May 2011

    View Slide

  7. Major
    Feature of
    Rails 3.1

    View Slide

  8. Sprockets is
    the asset
    pipeline

    View Slide

  9. Sprockets
    came first

    View Slide

  10. BTW

    View Slide

  11. They
    Call me
    @Schneems

    View Slide

  12. Sounds like
    “schnapps”

    View Slide

  13. Ruby
    “Hero”

    View Slide

  14. Ruby
    “Hero”

    View Slide

  15. View Slide

  16. All likeness to
    Disney owned
    properties
    totally
    coincidental

    View Slide

  17. And/or
    parody

    View Slide

  18. (Please don’t
    sue me)

    View Slide

  19. Lawyers

    View Slide

  20. Call me by my
    real name

    View Slide

  21. DHH

    View Slide

  22. No need to
    look like Indy
    to maintain
    OSS

    View Slide

  23. He’s my
    Sprockets
    Spirit Animal

    View Slide

  24. From 2011
    to
    2016

    View Slide

  25. 51 million
    downloads

    View Slide

  26. Rails has 65
    million

    View Slide

  27. One developer
    responsible
    for 2,027
    commits

    View Slide

  28. 68%
    Sprockets

    View Slide

  29. ♥♥♥

    View Slide

  30. 68%
    Sprockets
    0.9%
    Rails

    View Slide

  31. 51 million
    downloads
    1 developer

    View Slide

  32. One day, Josh
    left

    View Slide

  33. What should
    we do?

    View Slide

  34. Abandon
    Sprockets?

    View Slide

  35. What are the
    problems?

    View Slide

  36. You can’t fix
    what you
    can’t define

    View Slide

  37. A re-write
    assumes we
    know better

    View Slide

  38. we don’t

    View Slide

  39. Assets are
    easy, edge
    cases are
    hard

    View Slide

  40. Established
    API

    View Slide

  41. How many of
    you maintain
    code?

    View Slide

  42. How many of
    you want to
    maintain it
    forever?

    View Slide

  43. View Slide

  44. Losing
    maintainers
    is inevitable

    View Slide

  45. It’s not
    always
    expected

    View Slide

  46. View Slide

  47. View Slide

  48. 2014

    View Slide

  49. When we lose
    a maintainer
    it hurts

    View Slide

  50. How do we
    cope with
    losing a
    maintainer?

    View Slide

  51. Denial

    View Slide

  52. “They’ll come
    back”

    View Slide

  53. Anger

    View Slide

  54. “Leaving is so
    selfish”

    View Slide

  55. “That was a
    pretty jerk
    thing to do”

    View Slide

  56. Bargaining

    View Slide

  57. “Maybe if we
    hire them to
    work on it full
    time…”

    View Slide

  58. Acceptance

    View Slide

  59. “They’re not
    coming back”

    View Slide

  60. “Who will
    take this
    over?”

    View Slide

  61. Rule 1)

    View Slide

  62. A maintainer
    does not OWE
    you anything

    View Slide

  63. “I deserve an
    explanation

    View Slide

  64. Not even an
    explanation

    View Slide

  65. Leaving a
    project is a
    personal
    decision

    View Slide

  66. Josh didn’t
    want to talk
    about it

    View Slide

  67. We should
    respect what
    they’ve done

    View Slide

  68. Rule 2)

    View Slide

  69. You OWE a
    maintainer
    respect

    View Slide

  70. “But I HATE
    software

    View Slide

  71. Critique
    software
    without
    demonizing the
    creators

    View Slide

  72. I’m going to
    critique the
    crap out of
    Sprockets

    View Slide

  73. Critique
    don’t
    Criticize

    View Slide

  74. View Slide

  75. You are not
    your software

    View Slide

  76. You are not
    your khakis

    View Slide

  77. Josh gave
    years of his
    life

    View Slide

  78. HUNDREDS
    of closed
    issues

    View Slide

  79. To @josh
    Thanks for
    making
    Sprockets

    View Slide

  80. Rule 3)

    View Slide

  81. Words
    without
    actions are
    empty

    View Slide

  82. Be actionable

    View Slide

  83. Not Helping

    View Slide

  84. View Slide

  85. “ES6 support
    is great…

    View Slide

  86. “looks like
    they don’t have
    async/await
    support yet

    View Slide

  87. “I need those
    because of

    View Slide

  88. Ask

    View Slide

  89. Is this
    comment
    adding
    anything?

    View Slide

  90. Hyperbole
    breeds
    burnout

    View Slide

  91. Be honest

    View Slide

  92. Be productive

    View Slide

  93. View Slide

  94. View Slide

  95. Complaining
    accomplishes
    nothing

    View Slide

  96. How do we
    keep a
    maintainer
    longer?

    View Slide

  97. How to stay
    as a
    maintainer
    longer?

    View Slide

  98. Back up

    View Slide

  99. Do we want
    mantainers to
    stay?

    View Slide

  100. Mic Drop

    View Slide

  101. Graceful
    handoff

    View Slide

  102. Almost every
    day I say
    “this is
    insane”

    View Slide

  103. 6 hours of my
    life later, I
    say “this is
    genius”

    View Slide

  104. Maintainers
    are historians

    View Slide

  105. Maintainers
    bring
    context

    View Slide

  106. Good commit
    messages

    View Slide

  107. Good PR
    messages

    View Slide

  108. Well written
    CHANGELOG
    entries

    View Slide

  109. Don’t compare
    to having
    someone who
    was there

    View Slide

  110. A story is
    worth 1000
    commit
    messages

    View Slide

  111. You can’t ask
    a commit
    message a
    question

    View Slide


  112. Did you
    also
    consider…

    View Slide


  113. LOL I’m a
    commit
    message

    View Slide

  114. Keep
    maintainers
    longer by
    giving them
    what they want

    View Slide

  115. Respect

    View Slide

  116. Help

    View Slide

  117. “I don’t have
    time to help

    View Slide

  118. “Gahhhhhh
    fix all the
    things for
    me!!!!!!!!!

    View Slide

  119. 5 minutes to
    check snap-
    faceta-
    foursquare-
    tagram?

    View Slide

  120. 5 minutes to
    help

    View Slide

  121. Contribute to
    docs

    View Slide

  122. Read the
    guides

    View Slide

  123. Fix typos

    View Slide

  124. Did you find
    surprising
    behavior?

    View Slide

  125. Was your
    behavior
    documented?

    View Slide

  126. Add it to the
    guide

    View Slide

  127. 5 minutes to
    help

    View Slide

  128. Submit bug
    reports

    View Slide

  129. SRSLY
    We don’t
    know if it’s
    broken

    View Slide

  130. 5 minutes to
    help

    View Slide

  131. View Slide

  132. Ask common
    questions

    View Slide

  133. “Was this
    working
    previously?

    View Slide

  134. Would you
    rather a
    maintainer
    spent time
    fixing bugs?

    View Slide

  135. or

    View Slide

  136. Asking for
    minutiae in
    issue
    comments?

    View Slide

  137. Give a
    minute, save
    a minute

    View Slide

  138. If you don’t
    who will?

    View Slide

  139. Exposes you
    to different
    parts of the
    project

    View Slide

  140. Helps you
    grow as a
    developer

    View Slide

  141. 10 minutes to
    help

    View Slide

  142. Include a
    example app
    that reproduces
    the problem

    View Slide

  143. OMG
    example apps
    are amazing

    View Slide

  144. “First run
    $ rails new”

    View Slide

  145. View Slide

  146. Could not
    reproduce

    View Slide

  147. “Oh, yeah
    try…”

    View Slide

  148. View Slide

  149. Could not
    reproduce

    View Slide

  150. View Slide

  151. “Can you
    try…”

    View Slide

  152. View Slide

  153. Instead

    View Slide

  154. “Here’s an
    app that
    reproduces
    the problem”

    View Slide

  155. github.com/
    /
    ExampleApp

    View Slide

  156. Give a
    minute, save
    a minute

    View Slide

  157. Challenge
    make 1
    example app
    this year

    View Slide

  158. 30 minutes to
    help?

    View Slide

  159. Try fixing a/
    your bug

    View Slide

  160. Timebox it

    View Slide

  161. Guaranteed
    to learn
    something

    View Slide

  162. Read other
    people’s code

    View Slide

  163. Navigating
    and
    debugging
    are skills

    View Slide

  164. Navigating
    and debugging
    are marketable
    skills

    View Slide

  165. View Slide

  166. Go the extra
    mile

    View Slide

  167. How do we
    make
    transition
    easier?

    View Slide

  168. What is a
    maintainer?

    View Slide

  169. Someone who
    knows the
    stories

    View Slide

  170. Someone who
    takes 5
    minutes

    View Slide

  171. Someone who
    takes 10
    minutes

    View Slide

  172. Someone who
    takes 30
    minutes

    View Slide

  173. To help

    View Slide

  174. Helping
    preserves
    history

    View Slide

  175. Helping is the
    answer to
    keeping
    maintainers

    View Slide

  176. Helping is the
    answer to
    creating
    maintainers

    View Slide

  177. How do we
    foster a a
    culture for
    helping?

    View Slide

  178. Previously

    View Slide

  179. What do
    maintainers
    want?

    View Slide

  180. Now

    View Slide

  181. What do
    helpers want?

    View Slide

  182. DOCS

    View Slide

  183. Sane
    Code

    View Slide

  184. They want
    what regular
    users want

    View Slide

  185. A good
    developer UX

    View Slide

  186. Non-magical
    code

    View Slide

  187. Backwards
    compatibility

    View Slide

  188. Good
    deprecations

    View Slide

  189. Reliable
    Tests

    View Slide

  190. DOCS

    View Slide

  191. $ yard doc lib/
    [warn]: In file `README.md':248: Cannot resolve link to ExecJS
    from text:
    [warn]: {ExecJS}...
    [warn]: In file `README.md':439: Cannot resolve link to Tilt
    from text:
    [warn]: {Tilt}...
    [warn]: In file `README.md':248: Cannot resolve link to ExecJS
    from text:
    [warn]: {ExecJS}...
    [warn]: In file `README.md':439: Cannot resolve link to Tilt
    from text:
    [warn]: {Tilt}...
    [warn]: In file `lib/sprockets/unloaded_asset.rb':62: Cannot
    resolve link to type: from text:
    [warn]: ...{type: ”application/javascript“}...
    Files: 70
    Modules: 30 ( 10 undocumented)
    Classes: 48 ( 25 undocumented)
    Constants: 50 ( 32 undocumented)
    Methods: 405 ( 72 undocumented)
    73.92% documented

    View Slide

  192. Sprockets
    methods are
    documented

    View Slide

  193. Method docs
    are like unit
    tests

    View Slide

  194. Don’t tell the
    whole story

    View Slide

  195. Easy to get
    out of sync
    with reality

    View Slide

  196. View Slide

  197. A README
    tells a story

    View Slide

  198. Like an
    integration
    test

    View Slide

  199. $ wc -w README.md
    2619 README.md

    View Slide

  200. Sprockets
    tells a LONG
    story

    View Slide

  201. Helpers love
    docs

    View Slide

  202. Sprockets
    has docs

    View Slide

  203. Y U NO
    HELPERS
    SPROCKETS?

    View Slide

  204. Design
    Research

    View Slide

  205. User Stories

    View Slide

  206. Consider the
    people using
    your
    “product”

    View Slide

  207. Introducing

    View Slide

  208. Pedro

    View Slide

  209. Likes long
    walks on the
    beach

    View Slide

  210. Favorite food
    is bagel bites

    View Slide

  211. Building the
    next UBER for
    goldfish

    View Slide

  212. Rails user

    View Slide

  213. Cares only
    about the
    user level
    interface

    View Slide

  214. //= require “foo.js”

    View Slide

  215. Pat

    View Slide

  216. Addicted to
    ES6

    View Slide

  217. Loves to fly
    fish

    View Slide

  218. Plugin
    developer

    View Slide

  219. Did you know
    sprockets has
    plugins?

    View Slide

  220. Called
    Processors

    View Slide

  221. Cares about
    the processor
    interface

    View Slide

  222. def self.call(input)
    data = input[:data]
    # …
    end

    View Slide

  223. Diana

    View Slide

  224. Has a dog
    named
    Exception

    View Slide

  225. Hates
    mustard

    View Slide

  226. Rails
    Developer

    View Slide

  227. I.e. people
    building an
    asset pipeline

    View Slide

  228. Cares about
    Low level
    interface

    View Slide

  229. env = Sprockets::Environment.new(".")
    env.gzip = false

    View Slide

  230. Different
    people need
    different docs

    View Slide

  231. Don’t make
    me hunt
    down docs

    View Slide

  232. sprockets/
    guides

    View Slide

  233. Building an
    Asset
    Processing
    Framework

    View Slide

  234. End User
    Asset
    Generation

    View Slide

  235. Extending
    Sprockets

    View Slide

  236. Makes it
    easier for devs
    to find what
    they need

    View Slide

  237. Lives in the
    source, not a
    wiki

    View Slide

  238. Docs are only
    valid for a
    point in time

    View Slide

  239. Helpers love
    contributing
    to docs

    View Slide

  240. so

    View Slide

  241. Make more
    docs

    View Slide

  242. Make better
    docs

    View Slide

  243. Docs are the
    gateway to
    code
    contributions

    View Slide

  244. Sane
    Code

    View Slide

  245. realtalk

    View Slide

  246. Sprockets
    designed to
    solve
    problems

    View Slide

  247. Sometimes it
    feels like

    View Slide

  248. View Slide

  249. They don’t
    know why
    it fails

    View Slide

  250. Sprockets
    isn’t talking
    to devs

    View Slide

  251. How does
    code talk?

    View Slide

  252. Errors

    View Slide

  253. Not

    View Slide

  254. “something
    broke”

    View Slide

  255. No route matches
    {:action=>"show", :controller=>"users"}

    View Slide

  256. “This broke”

    View Slide

  257. No route matches
    {:action=>"show", :controller=>"users"},
    :id key is missing

    View Slide

  258. Look here

    View Slide

  259. No route matches
    {:action=>"show", :controller=>"users"},
    :id key is missing

    View Slide

  260. Good errors
    are
    instructive

    View Slide

  261. Sprockets
    will have
    better errors

    View Slide

  262. I care about
    this

    View Slide

  263. View Slide

  264. Deprecations

    View Slide

  265. Deprecating
    in comments
    is not enough

    View Slide

  266. View Slide

  267. A) No one
    casually
    reads your
    method docs

    View Slide

  268. B) Who has
    the time?

    View Slide

  269. You cannot
    break your
    API without
    warning*

    View Slide

  270. *when you’ve
    got 51 million
    downloads

    View Slide

  271. Your code
    knows

    View Slide

  272. YELL AT
    THEM FOR IT

    View Slide

  273. Sprockets 3.X
    will have
    deprecations
    before 4.x

    View Slide

  274. View Slide

  275. Deprecations
    nudge

    View Slide

  276. Deprecations
    Help people
    upgrade

    View Slide

  277. Deprecations
    help with API
    design

    View Slide

  278. If you can’t
    write a good
    deprecation

    View Slide

  279. The interface
    wasn’t very
    good

    View Slide

  280. What if you
    change a
    hash key?

    View Slide

  281. Sprockets did
    this

    View Slide

  282. filename = input[:source_path] || input[:filename]

    View Slide

  283. (more) Sane
    Code

    View Slide

  284. Sprockets
    suffers from
    the god object
    problem

    View Slide

  285. 1 main class,
    lot’s of
    concerns.

    View Slide

  286. 1 object,
    105 methods

    View Slide

  287. Where did
    that method
    come from?

    View Slide

  288. Sprockets::Base

    View Slide

  289. Sprockets::
    Environment

    View Slide

  290. Sprockets::
    Dependencies

    View Slide

  291. Sprockets::
    DigestUtils

    View Slide

  292. Sprockets::
    HTTPUtils

    View Slide

  293. Sprockets::
    Mime

    View Slide

  294. Sprockets::
    Server

    View Slide

  295. Sprockets::
    Resolve

    View Slide

  296. Sprockets::
    Loader

    View Slide

  297. Sprockets::
    Bower

    View Slide

  298. Sprockets::
    PathUtils

    View Slide

  299. Sprockets::
    PathDependencyUtils

    View Slide

  300. Sprockets::
    PathDigestUtils

    View Slide

  301. Sprockets::
    DigestUtils

    View Slide

  302. Sprockets::
    SourceMapUtils

    View Slide

  303. Sprockets::
    UriUtils

    View Slide

  304. My favorite

    View Slide

  305. Sprockets::
    Utils

    View Slide

  306. mixed into

    View Slide

  307. Sprockets::
    Compressing

    View Slide

  308. mixed into

    View Slide

  309. Sprockets::
    Configuration

    View Slide

  310. Included in

    View Slide

  311. Sprockets::
    Base

    View Slide

  312. Inherited by

    View Slide

  313. Sprockets::
    Environment

    View Slide

  314. Wrapped and
    cached by

    View Slide

  315. Sprockets::
    CachedEnvironment

    View Slide

  316. View Slide

  317. Impossible to
    know at a
    glance how
    they interact

    View Slide

  318. For more info
    go to Rafael
    Franca’s talk

    View Slide

  319. Which was
    yesterday

    View Slide

  320. Solution to
    god objects?

    View Slide

  321. Move logic
    over to helper
    classes

    View Slide

  322. View Slide

  323. Minimize God
    object API

    View Slide

  324. Small easy to
    understand
    files

    View Slide

  325. Readable
    code

    View Slide

  326. Attracts
    helpers who
    read code

    View Slide

  327. Ruby is
    Object
    Oriented

    View Slide

  328. Get
    comfortable
    with objects

    View Slide

  329. Sandi Metz
    POODR

    View Slide

  330. Katrina Owen
    Refactoring
    &
    Exercism.io

    View Slide

  331. Helping
    takes
    commitment

    View Slide

  332. respect that

    View Slide

  333. How?

    View Slide

  334. Be nice

    View Slide

  335. “thanks for
    submitting
    this PR

    View Slide

  336. They cared
    enough to try
    to help

    View Slide

  337. Help them
    help you

    View Slide

  338. What else do
    people want?

    View Slide

  339. Maybe they
    want
    recognition?

    View Slide

  340. View Slide

  341. Maybe
    helpers want
    pizza?

    View Slide

  342. Windows
    Tests

    View Slide

  343. )

    View Slide

  344. Thanks
    @daniel-rikowski

    View Slide

  345. These are our
    ideals

    View Slide

  346. So you inherited
    a project with
    51 million
    downloads

    View Slide

  347. The original
    maintainer
    mic-dropped

    View Slide

  348. What do you
    do?

    View Slide

  349. Find
    something
    that needs
    fixing

    View Slide

  350. Bug driven
    development

    View Slide

  351. Get an
    example app

    View Slide

  352. OMG
    example apps
    are amazing

    View Slide

  353. Reproduce
    the problem

    View Slide

  354. Repeat

    View Slide

  355. Every bug you
    fix, you’ll learn
    more about the
    project

    View Slide

  356. Eventually
    you’ll begin
    to see non-
    bug problems

    View Slide

  357. So you’ve got
    a bug report
    what do you
    do now?

    View Slide

  358. Source Maps
    in Sprockets
    4

    View Slide

  359. Half finished

    View Slide

  360. I had no idea
    what source
    maps were

    View Slide

  361. Fixing bugs
    made tests
    break

    View Slide

  362. Are those test
    reliable?

    View Slide

  363. ¯\_(ツ)_/¯

    View Slide

  364. Where do we
    start?

    View Slide

  365. Become an
    archeologist

    View Slide

  366. Research

    View Slide

  367. Mozilla RFC

    View Slide

  368. Notes

    View Slide

  369. Create guides

    View Slide

  370. What is a
    source map?

    View Slide

  371. Read my
    guide!

    View Slide

  372. Good OSS
    maintainers
    steal
    borrow

    View Slide

  373. Used other
    projects to
    verify
    Sprockets

    View Slide

  374. Encoding
    $ npm install uglify-js

    View Slide

  375. Encoding
    $ uglifyjs foo.js
    --source-map foo.js.map
    var foo="foo";var bar="bar";
    //# sourceMappingURL=foo.js.map

    View Slide

  376. Decoding
    $ npm install source-map

    View Slide

  377. Is it finished?

    View Slide

  378. No, need more
    actionable bug
    reports

    View Slide

  379. Where do we
    go now?

    View Slide

  380. Maintainers
    Won’t be
    around
    forever

    View Slide

  381. I
    Won’t be
    around
    forever

    View Slide

  382. I need help

    View Slide

  383. Help
    maintain the
    history of
    Sprockets

    View Slide

  384. Preserve the
    stories

    View Slide

  385. Get involved

    View Slide

  386. If you won’t,
    who will?

    View Slide

  387. We all need to
    step up

    View Slide

  388. Take 5
    minutes

    View Slide

  389. Read guides

    View Slide

  390. Write docs

    View Slide

  391. Open issues

    View Slide

  392. Create
    example apps

    View Slide

  393. Just

    View Slide

  394. 5

    View Slide

  395. minutes

    View Slide

  396. Join me

    View Slide

  397. Become

    View Slide

  398. A helper

    View Slide

  399. A maintainer

    View Slide

  400. Together

    View Slide

  401. Save
    Sprockets

    View Slide

  402. Questions?

    View Slide