Swizec Teller - a geek with a hatswizec.com

    Fun surprise: UglifyJS can't ES6

    "Yo Swiz, why aren't there any generated assets on preprod?"

    Preprod is production-but-not. As the last step before deploying to production, it acts just like the real deal. Real data, real users, real configuration, real everything except payments. Because that would be rude.

    "Errr ... what do you mean there's no assets?"

    "Well, we ran out of environments, so I'm testing on preprod. It's like Webpack doesn't output anything, but it works on localhost and all our other environments."

    O.o

    ERROR in tutor_onboarding.js from UglifyJs
    SyntaxError: Unexpected token: name (defaultHeaders) [./~/better-fetch/index.js:2,0]

    That's funny ... UglifyJS throws an error on the first line of my better-fetch library. Why would it do that? ?

    "We don't minify our code on localhost, do we? What about on staging?"

    "Yeah, only prod and preprod"

    Great, at least we know how nobody noticed this in over a month. It only happens on servers configured for production.

    Thank the-god-of-grizzled-veterans for preprod! Error happens, deploy goes through, assets are empty, nothing works. Imagine how absolutely fantastic this would be to discover when deploying to real production ?

    Here's the line that broke UglifyJS:

    let defaultHeaders = {};

    I built a fetch() wrapper in ES6. Fuck me, right? Not like it's an ES6+ only API or anything like that…

    Hint: it is. It's ES6 only. You'd think building a wrapper in ES6 without compiling before npm publish would work, right?

    Nope. Not if a project that imports your library minifies their assets.

    How to package your ES6 library so anyone can use it

    3.73 months ago, I thought packaging a library was hard. Turns out it's not so bad at all.

    You have to add Babel, the ES6 -> ES5 compiler1, configure it, update your new main entry, and add a build script to npm scripts. That makes it easier to run.

    These 7 lines are all it takes: diff on Github

    You have to install babel-cli and babel-preset-latest:

    $ npm install --save-dev babel-cli babel-preset-latest

    And configure Babel:

    // package.json
    "babel": {
    "presets": ["latest"]
    }

    Configuring in package.json is easiest. 17 characters is not a good enough reason to add another config file to your project.

    You should update your main entry as well. It tells npm which file to use when somebody uses require('your-library') or import YourThing from 'your-library'.

    // package.json
    "main": "lib/index.js"

    Many projects use lib/ for their compiled files. dist/ is another popular choice.

    To improve your quality of life, you should add a build script. Also in package.json:

    // package.json
    "scripts": {
    "build": "babel src -d lib"
    }

    Now you can use npm run build to run babel, read files from src/, and output the compiled versions in lib/. Library fixed. Crisis solved. \o/

    Further quality of life improvement

    While heroically saving the day with the above 7 lines of configuration, I found another way to improve my quality of life: automatic version bumping and GitHub pushing.

    Add these 3 lines to package.json:

    // package.json
    "scripts": {
    "preversion": "",
    "version": "npm run build && git add -A lib",
    "postversion": "git push && git push --tags && rm -rf build/temp",
    }

    You can use npm version X where X is one of patch, minor, major, etc. to bump your library version number. That always works.

    These three lines make it better. preversion runs a command before updating the version number. If the command fails, the version doesn't change. Usually these are tests. In my case, it's empty because I'm a bad person.

    version runs a command when the version updates. This is a great spot to compile your library and add the compiled files to git.

    postversion runs after the version updates. And this is a great spot to push to GitHub and perform any build cleanup.

    Now you can update your library then run npm version patch to bump the version, build the lib, and push to github. npm publish announces the fix to the world.

    Time to congratulate yourself and grab a beverage. ?

    Lesson Learned

    UglifyJS doesn't support ES6. They've been working on it since at least March of 2014. As of December 6th, 2016, it's still not ready. Turns out this is a hard problem.

    Most real world projects use UglifyJS to minify their JavaScript.

    You have to distribute a compiled version of your JavaScript libraries no matter what they do. Such is life.


    1. Yes, Babel is technically a transpiler ↩

    Did you enjoy this article?

    Published on December 7th, 2016 in Front End, react, Technical,

    Learned something new?
    Read more Software Engineering Lessons from Production

    I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.

    Subscribe below πŸ‘‡

    Software Engineering Lessons from Production

    Join Swizec's Newsletter and get insightful emails πŸ’Œ on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.

    "Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. πŸ‘Œ"

    ~ Ashish Kumar

    Join 15,883+ engineers learning lessons from my "raw and honest from the heart" emails.

    ⭐️⭐️⭐️⭐️✨
    4.5 stars average rating

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help πŸ‘‰ swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers πŸ‘‰ ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Want to brush up on modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❀️

    Created by Swizec with ❀️