Artem Sapegin’s Blog

What to learn in 2017 if you’re a frontend developer

With our fast-paced ecosystem we tend to spend our time trying the latest inventions and arguing about them on the internet. I’m not saying we shouldn’t do that, but probably we should slow down a bit and take a look at things that don’t change much: they could greatly improve quality and value of our work, and understanding of those new tools.

This post is a mix of my experience and my wishes for the New Year. I want to hear your suggestions as much as I want to share mine.

Learn how to write readable code

Most of our work isn’t in writing new code but modifying existing code. That means you read code much more often then write it, so you need to optimize you code for the next programmer, not for the interpreter.

I recommend reading these three amazing books — in this order, from shortest to longest:

Learn JavaScript deeper

When every week we have a new JavaScript framework that’s better than any older framework, it’s easy to spend most of your time learning frameworks rather than the language itself. If you’re using a framework but don’t understand how it works, stop and start learning the language until you understand how tools you use work.

Learn functional programming

For years we wanted classes in JavaScript. Now we finally have them but don’t want to use them anymore: functions are all we want! We even write HTML using functions (JSX).

Learn design basics

As frontend developers we’re closer to users than anybody else in the team, maybe even closer than designers. And if designers have to verify every pixel you put on screen, you’re doing something wrong.

Learn how to work with humans

Some of us come to programming because we prefer to interact with computers more than with humans — unfortunately that’s not how it works.

We rarely work in isolation: we have to talk to other developers, designers, managers and sometimes even users. That’s hard but it’s very important if you want to really understand what you’re doing and why, because that's where the value in what we do lies.

Learn how to write for humans

A big portion of communication with our colleagues and other people are textual: task descriptions and comments, code comments, Git commits, chat messages, emails, tweets, blog posts, etc.

Imagine how much time people spend reading and understanding all that. If you can reduce this time by writing more clearly and concisely, the world will be a better place to work.

Learn the old computer science wisdom

Frontend development isn’t animated dropdown menus any more. It’s more complicated than ever before, and part of that notorious “JavaScript fatigue” stems from the increased complexity of the tasks we have to solve.

This, however, means that it’s time to learn from all wisdom that non-frontend developers built up over many decades. And here I want your recommendations the most.


What would you recommend? What are you going to learn in 2017?


Thanks to Henrique Alves, Nicolás Bevacqua, Alexander Burtsev, Nataliya Karatkova, Oliver Turner, Juho Vepsäläinen and Anton Zhiyanov for feedback and suggestions.

Testing React components with Jest and Enzyme

Some people say that testing React components is useless and in many cases it is, but there are a few cases when I think it’s useful:

  • component libraries,
  • open source projects,
  • integration with third-party components,
  • bugs, to prevent regressions.

I’ve tried many tools and finally have found a combination that I like enough to suggest to other developers:

  • Jest, a test runner;
  • Enzyme, a testing utility for React;
  • enzyme-to-json to convert Enzyme wrappers for Jest snapshot matcher.

For the most of my tests I use shallow rendering with Jest snapshots.

Shallow rendering

Shallow rendering renders only component itself without its children. So if you change something in a child component it won’t change shallow output of your component. Or a bug, introduced to a child component, won’t break your component’s test. It also doesn’t require DOM.

For example this component:

const ButtonWithIcon = ({icon, children}) => (
  <button><Icon icon={icon} />{children}</button>
);

Will be rendered by React like this:

<button>
  <i class="icon icon_coffee"></i>
  Hello Jest!
</button>

But like this with shallow rendering:

<button>
  <Icon icon="coffee" />
  Hello Jest!
</button>

Note that the Icon component was not rendered.

Snapshot testing

Jest snapshots are like those old text UIs with windows and buttons made of text characters: it’s a rendered output of your component stored in a text file.

You tell Jest that you want to be sure that output of this component should never change accidentally and Jest saves it to a file that looks like this:

exports[`test should render a label 1`] = `
<label
  className="isBlock">
  Hello Jest!
</label>
`;

exports[`test should render a small label 1`] = `
<label
  className="isBlock isSmall">
  Hello Jest!
</label>
`;

Every time you change your markup Jest will show you a diff and ask you to update a snapshot if the change was intended.

Jest stores snapshots besides your tests in files like __snapshots__/Label.spec.js.snap and you need to commit them with your code.

Why Jest

  • Very fast.
  • Snapshot testing.
  • Awesome interactive watch mode that reruns only tests that are relevant to your changes.
  • Helpful fail messages.
  • Simple configuration.
  • Mocks and spies.
  • Coverage report with a single command line switch.
  • Active development.
  • Impossible to write silently wrong asserts like expect(foo).to.be.a.function instead of expect(foo).to.be.a('function') in Chai because it’s the only natural thing to write after (correct) expect(foo).to.be.true.

Why Enzyme

  • Convenient utilities to work with shallow rendering, static rendered markup or DOM rendering.
  • jQuery-like API to find elements, read props, etc.

Setting up

I use Babel and CSS Modules so you’ll see them in the examples below but both are optional.

First install all the dependencies including peer dependencies:

npm install --save-dev jest babel-jest react-addons-test-utils enzyme enzyme-to-json

Update your package.json:

"scripts": {
  "test": "jest",
  "test:watch": "jest --watch",
  "test:coverage": "jest --coverage"
},
"jest": {
  "setupFiles": ["./test/jestsetup.js"],
  "snapshotSerializers": [
    "<rootDir>/node_modules/enzyme-to-json/serializer"
  ]
}

snapshotSerializers allows you to pass Enzyme wrappers directly to Jest’s snapshot matcher, without converting them manually by calling enzyme-to-json’s toJson function.

Create a jestsetup.js file to customize Jest environment (see setupFiles above):

// Make Enzyme functions available in all test files without importing
import { shallow, render, mount } from 'enzyme';
global.shallow = shallow;
global.render = render;
global.mount = mount;

// Skip createElement warnings but fail tests on any other warning
console.error = message => {
  if (!/(React.createElement: type should not be null)/.test(message)) {
    throw new Error(message);
  }
};

For CSS Modules also add to jest section in your package.json:

"jest": {
  "moduleNameMapper": {
    "^.+\\.(css|scss)$": "identity-obj-proxy"
  }
}

And run npm istall --save-dev identity-obj-proxy.

Note that identity-obj-proxy requires node --harmony-proxies flag for Node 4 and 5.

Writing tests

Testing basic component rendering

That’s enough for most non-interactive components:

it('should render a label', () => {
  const wrapper = shallow(
    <Label>Hello Jest!</Label>
  );
  expect(wrapper).toMatchSnapshot();
});

it('should render a small label', () => {
  const wrapper = shallow(
    <Label small>Hello Jest!</Label>
  );
  expect(wrapper).toMatchSnapshot();
});

it('should render a grayish label', () => {
  const wrapper = shallow(
    <Label light>Hello Jest!</Label>
  );
  expect(wrapper).toMatchSnapshot();
});

Testing props

Sometimes you want to be more explicit and see real values in tests. In that case use Enzyme API with regular Jest assertions:

it('should render a document title', () => {
  const wrapper = shallow(
    <DocumentTitle title="Events" />
  );
  expect(wrapper.prop('title')).toEqual('Events');
});

it('should render a document title and a parent title', () => {
  const wrapper = shallow(
    <DocumentTitle title="Events" parent="Event Radar" />
  );
  expect(wrapper.prop('title')).toEqual('Events — Event Radar');
});

In some cases you just can’t use snapshots. For example if you have random IDs or something like that:

it('should render a popover with a random ID', () => {
  const wrapper = shallow(
    <Popover>Hello Jest!</Popover>
  );
  expect(wrapper.prop('id')).toMatch(/Popover\d+/);
});

Testing events

You can simulate an event like click or change and then compare component to a snapshot:

it('should render Markdown in preview mode', () => {
  const wrapper = shallow(
    <MarkdownEditor value="*Hello* Jest!" />
  );

  expect(wrapper).toMatchSnapshot();

  wrapper.find('[name="toggle-preview"]').simulate('click');

  expect(wrapper).toMatchSnapshot();
});

Sometimes you want to interact with an element in a child component to test effect in your component. For that you need a proper DOM rendering with Enzyme’s mount method:

it('should open a code editor', () => {
  const wrapper = mount(
    <Playground code={code} />
  );

  expect(wrapper.find('.ReactCodeMirror')).toHaveLength(0);

  wrapper.find('button').simulate('click');

  expect(wrapper.find('.ReactCodeMirror')).toHaveLength(1);
});

Testing event handlers

Similar to events testing but instead of testing component’s rendered output with a snapshot use Jest’s mock function to test an event handler itself:

it('should pass a selected value to the onChange handler', () => {
  const value = '2';
  const onChange = jest.fn();
  const wrapper = shallow(
    <Select items={ITEMS} onChange={onChange} />
  );

  expect(wrapper).toMatchSnapshot();

  wrapper.find('select').simulate('change', {
    target: { value },
  });

  expect(onChange).toBeCalledWith(value);
});

Not only JSX

Jest snapshots work with JSON so you can test any function that returns JSON the same way you test your components:

it('should accept custom properties', () => {
  const wrapper = shallow(
    <Layout
      flexBasis={0}
      flexGrow={1}
      flexShrink={1}
      flexWrap="wrap"
      justifyContent="flex-end"
      alignContent="center"
      alignItems="center"
    />
  );
  expect(wrapper.prop('style')).toMatchSnapshot();
});

Debugging and troubleshooting

Use Enzyme’s debug method to print shallow renderer’s output:

const wrapper = shallow(/*~*/);
console.log(wrapper.debug());

When your tests fail with --coverage flag with diff like this:

-<Button
+<Component

Try to replace arrow function component with regular function:

- export default const Button = ({ children }) => {
+ export default function Button({ children }) {

Resources


Thanks to Chris Pojer, Max Stoiber and Anna Gerus for proofreading and comments.

Ask Me Anything is the new way of blogging

AMA is a GitHub repository where anyone can file an issue with any question and author will reply in a comment. It was started by Sindre Sorhus in July 2015 and now there are more than 100 AMAs.

Some of the questions are really interesting. Basically to answer a question one has to write a tiny (and sometimes not so tiny) blog post. For me it’s something between Twitter and a blog but directed by the readers.

“Watch” someone’s AMA repository and you’ll see all new questions and answers in GitHub feed.

My favorite AMAs:

Read answers, ask questions. You can ask me anything too.

Why I open source my personal code

I store most of my personal code on GitHub, accessible to anyone. I have a lot of reasons to do it and couldn’t find any reason not to do it.

My GitHub profile

I have nothing to hide

Most of my personal code is my sites’ code or tools that I use to develop my sites. Anyone can unminify this code and read if they really want.

I can use GitHub and Travis CI and any other open source tool for free

I like GitHub and I don’t like Bitbucket (they have free private repositories). I like to store all my code in the same place — it’s convenient. I also like Travis CI and use it for all my projects, even for my blog.

I can publish to npm for free

Sharing code with npm is much more convenient than copypasting. And you don’t have to pay for private npm.

It forces me to write better code

My future coworker may find it and may judge my coding skills by this code. I don’t want him to look into a wrong project so I try to make all my public code good. Later me will thank current me for that.

It forces me to write documentation

Nobody likes to find a project that seems useful but has no documentation or even comments in the code. Me too, even if it’s my own code.

I can send a link to show my code

Often someone asks how I do this or that. If this or that is open sourced I could just send a link to a file on GitHub. I can even select particular lines in that file.

I receive pull requests with grammar fixes

It’s rare but it’s real. Some people love to fix bugs or typos if they can. I’m one of them.

Someone else may find it useful

That’s very cool though very rare for me. Maybe one day.

Automate npm releases with semantic-release and human-written change logs

Making new releases is one of the most boring and tedious tasks in open source.

There are many tools that try to automate publishing and one of the most interesting is semantic-release. I was avoiding it for a long time because it makes publishing fully automated with changelogs generated from commit messages, and I believe that changelogs must be written by humans.

But actually it’s very flexible and I was able to customize it to do exactly what I want:

  • Publish a new PATCH version to npm as soon as a fix commit merged to the master branch, generate changelog from commit messages.
  • Postpone MINOR and MAJOR release until a proper changelog is written by a project maintainer.
  • Generate changelog draft: Markdown file with all important commits since the latest release grouped into three sections: breaking changes, new features and bugfixes.

Below I’ll describe my own set of scripts that implements this workflow.

How it works

  1. Semantic-release runs on a CI server.

  2. After each successful build it analyzes new commits and see if there’s something to publish.

  3. It determines a release type (PATCH, MINOR or MAJOR) by analyzing commit messages (more on that later).

  4. It generates a changelog:

    a. If the release type is PATCH: from commit messages.

    b. If the release type is MINOR or MAJOR and the latest commit is a changelog: uses body of that commit as a changelog.

  5. Publishes a new version to npm.

  6. Publishes changelog to GitHub Releases page.

Install semantic-release

First install semantic-release command line tool:

npm install -g semantic-release-cli

Then run it in your project folder:

semantic-release-cli setup

Enter your npm and GitHub credentials. Choose “Create no .travis.yml” if you already have one, otherwise it will be overwritten.

Semantic-release setup

Add these lines to your travis.yml:

after_success:
  - npm run semantic-release
branches:
  except:
    - /^v\d+\.\d+\.\d+$/

Customize semantic-release

You can change semantic-release behavior with plugins: detect release type, check release requirements (like a changelog), generate changelog, etc. I made a package with all plugins I need to support my workflow.

First install the plugins:

npm install --save-dev semantic-release-tamia

Then add to your package.json:

"release": {
  "analyzeCommits": "semantic-release-tamia/analyzeCommits",
  "generateNotes": "semantic-release-tamia/generateNotes",
  "verifyRelease": "semantic-release-tamia/verifyRelease"
}

Run npm install and npm run semantic-release to test if everything works. You’ll see something like that:

semantic-release WARN pre semantic-release didn’t run on Travis CI and therefore a new version won’t be published.
semantic-release WARN pre You can customize this behavior using "verifyConditions" plugins: git.io/sr-plugins
semantic-release ERR! pre Failed to determine new version.
semantic-release ERR! pre ENOCHANGE There are no relevant changes, so no new version is released.

Which is fine and means two things: semantic-release will not make a release until it runs in a CI environment and you have no changes that could be published.

Use Git commit message convention

By default semantic-release uses AngularJS conventions which I don’t like aesthetically. So I use a slightly modified convention:

Git commits following a convention

Each commit message consists of:

  1. Type: Feat for new feature, Fix for bug fix, etc.
  2. Subject: short change description.
  3. Body (optional): long change description.
  4. Footer (optional): breaking changes, GitHub issues references, etc.

Semantic-release uses this tags to find all important commits for the release (Fix is important, Docs is not) and determine which version (MAJOR, MINOR or PATCH) should be released.

Write changelog for MINOR or MAJOR release

I wrote a script to help me with changelogs.

First run sr-changelog. It will create a file with all important commits for the release grouped by type (breaking changes, new features and bugfixes) and open it in your default editor.

Now you can rewrite your changelog to make it useful and easy to read for your users.

Then run sr-changelog commit. It will make a commit without changes (git commit --allow-empty) of type Changelog and changelog in the commit message body.

Publish new release

Now you need to git push your changes and make some coffee.

GitHub release notes

Caveats

  • Do not merge pull requests, squash them into a single commit with a proper message.

  • If you forget to do that and want to make a PATCH release:

    git commit -m "Fix: Proper commit message" --allow-empty

Links

Add the Fucking Change Log

Every time I upgrade my project’s dependencies using npm-upgrade and it cannot find a change log I create an issue titled “Add changelog”. Most of them were ignored, sometimes maintainers answer something that means “fuck off”, very rarely they listen.

npm-upgrade

A good change log answers these questions for the project’s user:

  • What’s the new value for my project in the new version?
  • What are the breaking changes?
  • How can I migrate my codebase to the new version?
  • Were my issues fixed?

A change log is a tool that helps you decide to upgrade or not and to evaluate the benefits and the cost of the upgrade.

A good change log is:

  • Written for humans, not computers.
  • Understandable by users, not just contributors.
  • Not a Git commit log.
  • Written by a project maintainer — don’t ask for a pull request.

You should read this awesome guide and add a change log to your open source project today.

View Source 2016

View Source is a conference organised by Mozilla, was held on September 12–14 in Berlin, Germany, for the first time in Europe.

Chris Wilson at View Source 2016

First day talks

Opening keynote: State of the web by Hadley Beeman. Slides. Video.

  • The future isn’t built yet.
  • We don’t all agree what the future should be.
  • We need you to help create the future.
  • The rules are fluid, because we make them. We have the ability to shape the web. What should it be?

Design for non-designers by Tracy Osborn. Slides. Video.

  • Developers can’t escape at least some designing: site for open source project or just a home page.
  • Fastest way for better looking designs: cut down on clutter.
  • Reduce number of fonts and colors, line things up.
  • Whitespace is the ultimate clutter reducer.
  • Make it easy to find and use the most important action.
  • Content principles: less is more, big paragraphs are a sign of clutter, break into bullets.
  • Headlines: talk benefits, not details, keep it short, use natural and friendly language.
  • Good artists copy, great artists steal: use work of others as inspiration. Designing without inspiration is like programming without Stack Overflow.
  • Colourlovers, Beautiful Web Type, Typewolf.
  • A Simple Web Developer’s Guide To Color.
  • Upcoming book about web design.

Inclusive markup: you don’t need a framework for that by Estelle Weyl. Slides. Video.

  • Original purpose of frameworks is normalization of browser features like addEventListener: not relevant anymore.
  • Frameworks are good: faster, optimized and readable code.
  • But you don’t need jQuery to add a class.
  • Using frameworks developers are not learning basics of web development.
  • Frameworks don’t guarantee accessibility: you need to understand the output you’re generating.
  • Semantic markup is one of the core principles of an accessible web. For example, different input types.
  • Average web page size has grown by 351% since 2010.
  • Front end requirements: progressive enhancement, accessibility, performance, security, user experience and design, good taste, social skills, communication and writing, teaching, debate, documentation…
  • Resume Driven Development (RDD).

You might not need a CSS framework by Belen Albeza from Mozilla. Slides. Video.

  • Why people use frameworks: they believe it’s quicker and best practice, already implemented design.
  • Quicker? Not true for most projects with custom design.
  • Good for back office, prototypes and projects without a designer.
  • Problems: unsemantic, bloated HTML, unused rules, hard to override styles (too specific), opinionated.
  • Why use class to disable a button instead of disabled attribute? Why use two classes for a colored label?
  • Use Flexbox for layouts today. Use CSS Grid for layouts tomorrow.
  • Don’t include a whole framework if you just need a grid or a few UI components.

Node.js versions: how do they work? by Myles Borins from IBM. Slides. Video.

  • Versions are confusing but you don’t have to understand everything to contribute in a meaningful way.
  • Stop using Node 0.10 and 0.12 because OpenSSL used in these versions will stop updating in December.
  • Do not use odd versions in production. Use 4.x now. Maybe.
  • Next month 6.x will become LTS with 30 month support cycle and lots of ES6 goodies.
  • Smoke testing: run tests for the most popular npm modules to ensure no breaking changes.
  • Tools: branch-diff, changelog-maker.

Type is your right! Performance and web typography by Helen Holmes from Mozilla. Slides. Video.

You can read about most of these things in Helen’s article What is Beautiful Web Typography.

  • Use OpenType features in CSS: kerning, ligatures, etc.
  • Use OpenType Sandbox to check what features are available in a font.
  • Custom fonts have performance issues that could be fixed.
  • Prevent the FOIT (flash of invisible text).
  • Minimize the FOUT (flash of unstyled text).
  • Minimize FOFT (flash of faux text): choose closest safe font, tweak size to match custom font.
  • Load regular, italic and bold separately.
  • Tools: fontfaceonload, utility-opentype, Normalize-OpenType.css.

Things you can do in ES6 that can’t be done in ES5 by Dan Shappir from Wix.com. Slides. Video.

  • ES6 is mostly syntactic sugar: arrow functions, destructuring, default function parameters, template strings, classes, etc.
  • It’s good: you want the syntax to be friendly.
  • What ES6 can do is what Babel can do.
  • Map can be emulated in ES5 but much slower.
  • WeakMap and Proxy can’t be emulated in ES5.

Closing keynote: Resilience by Jeremy Keith. Slides. Video.

  • First version of HTML had 21 tag, HTML 5 has 121.
  • HTML and CSS have loose error handling. Show content, skip tags and properties they don’t understand. Browser doesn’t stop parsing when it finds an error.
  • The first website still works in modern browsers.
  • HTML and CSS are declarative and resilient, JavaScript is imperative and fragile.
  • Make core functionality available using the simplest technology, then enhance.
  • Developer convenience shouldn’t be more important than user needs.

Second day talks

Opening keynote: existing in tech by Lena Reinhard from Travis CI. Slides. Video.

  • The tech industry is not hospitable to humans.
  • How to survive in tech:

    • remember that you matter;
    • use the power of language;
    • practice self care;
    • do only one thing, but do the one thing;
    • get professional help;
    • set and enforce boundaries;
    • learn to recognize warning signs;
    • be open about your experiences;
    • remember that you’re not alone;
    • know there’s a spaceship, you can leave;
    • support others.

Laying out the future with Grid and Flexbox by Rachel Andrew. Slides. Video.

  • CSS wasn’t designed for layouts: floats, inline-block, display: table, absolute and relative positioning, lots of frameworks.
  • Hopes for the future: Flexbox, CSS Grid Layout, Box Alignment.
  • Grid by Example.
  • Separation of source order and display order.
  • CSS Grid automatic placement: fantastic for a photo gallery, not so good for a form.
  • On CSS accessibility and drinking tea — Léonie Watson at CSS Day 2016.
  • It’s 2016. We can finally centre things.
  • Responsive by default.
  • Flexbox Tester.
  • Flexbox is for one-dimensional layout, CSS Grid is for two-dimensional layout.
  • Vendor prefixes didn’t work because developers used unfinished features in production and got upset when that features changed.
  • Try unfinished features and give feedback: it can be included in the spec.

Progressive Web Apps is the new Ajax by Chris Wilson from Google. Slides. Video.

  • The most exciting time in web development.
  • Average user installs zero app per month.
  • Like Ajax it’s about users, not technology.
  • User experience needs to be reliable, fast and engaging.
  • Reliable: never show a Downasaur.
  • Fast: 40% of users abandon sites that take longer than 3 seconds to load.
  • Engaging: full screen theming, orientation, auto-adding to home screen, push notifications.
  • The offline cookbook.
  • A promise to the user: works offline, consistent experience, the users is engaged.

Revolutionize your page: real art direction on the web by Jen Simmons from Mozilla. Slides. Video.

  • Paper magazines use layout to communicate an idea of a story, web articles all look the same.
  • Many modern sites use same layouts dictated by our tools.
  • The Experimental Layout Lab of Jen Simmons.
  • Little pieces: initial letter, viewport units, object fit, clip path, CSS shapes.
  • Use CSS Feature Queries to check browser support.
  • Big pieces: Flexbox, CSS Grid Layout, Alignment.
  • CSS Grid is a framework built in a browser.
  • Learn Flexbox by playing a game: Flexbox Defense, Flexbox Froggy.
  • Tools: Firefox Nightly, where Grid just works, CSS Grid Inspector for Firefox, CSS Shapes Editor for Chrome.
  • Don’t work — don’t use is a bad approach.
  • You can use and don’t use enhancements at the same time with CSS.
  • In one year we will have 60–80% support of CSS Grid.
  • Start learning Grid now and you’ll understand it when it starts shipping in browsers.

Doing the unstuck: how to make browsers compatible with the web by Mike Taylor from Mozilla. Slides. Video.

  • New browser features can break existing sites.
  • Specs are changing to match reality: existing implementations in browsers.
  • Once we add this garbage pile of hacks, the web is actually usable.
  • Read standards.
  • Test in pre-release versions of browsers: Firefox, Edge, Safari, Chrome, Opera.
  • Report bugs to browsers: Firefox, Edge, Safari, Chrome, Opera or webcompat.com.

I’m offline, cool! What now? by Ola Gasidlo from Styla. Slides. Video.

  • Network is progressive enhancement.
  • SVG over IMG, base64 over IMG (but base64 is expensive and heavy).
  • Save data locally and frequently, use partial updates.
  • Define flexible data schema: prevent merge conflicts.
  • Security: use CORS, encrypt local data, use JSON Web Tokens.
  • Rethink how to use technology, by thinking about the issue. Not about the tools.
  • Tools: jakecache, CouchDB, PouchDB.

Web, meet virtual reality by Dominique Hazael-Massieux from W3C. Slides. Video.

  • VR is not just visual: WebGL, WebVR, Gamepad API, Web Audio, 3D camera and computer vision.
  • A-Frame: create virtual reality using markup.

Closing keynote: the future of the web — progressive web apps and beyond by Robert Nyman from Google. Slides. Video.

  • Web declared dead in 2010. Web very much alive in 2016!
  • 800 Million users of mobile Chrome in November 2015 → 1 Billion in May 2016.
  • Progressive web apps: instant loading, add to home screen, push notifications, fast, secure, responsive.
  • What about the future?
  • Automatic sign-in.
  • Paying for things on the web.
  • 66% of purchases on mobile are on web, 66% fewer conversions on mobile websites vs. desktop.
  • Checkout forms today: manual, tedious, slow, many taps.
  • Autofill fills web forms with a single click: 25% increase in conversion rate.
  • Checkout with Autofill: automatic, simple, still slow, still many taps.
  • PaymentRequest: a W3C API to eliminate checkout forms for users and standardize payment collection for sites.
  • Checkout with PaymentRequest: automatic, simple, fast, single tap.
  • Connecting with hardware: Bluetooth Low Energy (BLE), WebNFC, generic sensors.
  • Our job isn’t about frameworks or discussions about semicolons, it’s about people.

Discussion corners

Sustainable Open-Source Projects with Jan Lehnardt.

Based on Jan’s article.

  • Treat contributors as people.
  • Have a Code of Conduct.
  • Always recruit contributors.
  • Document everything, document decision making process.
  • Make detailed issues instead of fixing bugs yourself.

New and upcoming Web APIs with Florian Scholz and Jean-Yves Perrier.

  • APIs: easy to use but limited or harder to use but allow anything?
  • Any standard is a very long process: making things possible is more important then a nice API.
  • Browsers have to support all past technologies.
  • People maintaining documentation (like MDN) have to constantly update documentation to reflect changing specs, but they also have to maintain documentation to all past technologies.

Why developers need to learn Design with Emanuele Libralato.

Some takeaways

  • Mobile apps are finally dying: learn how to build progressive web apps.
  • Learn CSS Grid today: you’ll need it tomorrow.
  • Learn how your framework works: you might not need it.
  • Vendor prefixes → pre-release browser channels to test new features.
  • People finally understood that we’re here not to write code but to help our users.
  • New words: Downasaur (dinosaur in Chrome when you’re offline), Lie-Fi.

Some closing notes

I’ve enjoyed the conference very much. I like that it wasn’t about just technology but about how to apply technology and that’s inspiring. Topics were very diverse but not too hardcore.

Links

Structuring React and Redux Applications

There’s no idiomatic way to structure Redux applications yet. And I believe there’s no The Only True Project Structure but I’ll describe what works for me.

General structure

There are two approaches for grouping files:

  • By type: one folder for components, one for reducers, one for actions, etc.
  • By feature: all files related to one feature are inside the same folder.

I started from grouping by type. It works for a small application but to add a new feature you have to create: reducers/myfeature.js, selectors/myfeature.js, components/MyFeature.js and a few more. It’s annoying and difficult to explain to new team members.

Now I group files by view or page: dashboard, users, etc.

Here are main folders I have in my application:

  • app: Redux store configuration and root reducer, React Router routes, application root components with connections to Redux, Redux DevTools, React Router and React Intl.
  • components: shared components.
  • models: Immutable.js records.
  • util: any shared non-React JavaScript code.
  • features.

Read more…

Egghead Courses Review: React, Reactive Programming & Open Source

Most courses are good but very basic. They are very good to get to know a new technology. Only the Redux course I can recommend to any developer: no matter if you just starting with Redux, already fluent or not going to use it at all.

Some courses are free but most of them are available only by subscription. With a subscription you have access to all Egghead’s courses and a few useful features: adjusting playback speed, skip 25 seconds button, downloading HD videos. In the past they had a $20 monthly subscription but now they have only $200 yearly. And I can’t recommend it anymore: one month is enough to watch most of the good courses.

Getting Started with Redux by Dan Abramov (free)

Really great course. Teaches you many other things besides Redux: like ES6 and just how to write good code. Watch in any case.

Building React Applications with Idiomatic Redux by Dan Abramov (free)

Not as universal as the first one but also very good. Watch if you’re already using Redux.

How to Contribute to an Open Source Project on GitHub by Kent C. Dodds (free)

Very short and good course. Watch before you send your first 20 pull requests.

If you want more pull request to your open source projects, you can try to add a badge with the link to this course.

How to Write an Open Source JavaScript Library by Kent C. Dodds (free)

Great course for beginners but I’ve learned something from it myself. Watch before you make your first 10 open source projects.

One thing I don’t like about this course: Kent suggests semantic-release to automate releases. I wouldn’t recommend it because it makes project maintainer life harder: it doesn’t allow you to group breaking changes and write human readable change logs. And I think it’s too opinionated for such course.

Learn how to use Immutable.js by J.S. Leonard

Mostly just retelling of the docs (which are hard to read). Watch if you don’t know much about Immutable.js.

React Testing Cookbook by Trevor Miller

Short and very basic. Covers shallow rendering, expect-jsx and Redux.

React: Flux Architecture (ES6) by Joe Maddalone

Watch the first Redux course instead. Watch this course only if you really have to use the vanilla Flux.

Reduce Data with Javascript Array#reduce by Joe Maddalone

I enjoyed watching this short course. Watch if you can’t use the reduce function with your eyes closed.

Getting Started with React Router by Joe Maddalone

Very basic and very short course. If you’re already using React Router in a project you most probably won’t learn anything new.

React Fundamentals by Joe Maddalone

Watch the free React.js Fundamentals course by Tyler McGinnis instead (yeah, the name is the same but it’s a different course by a different author).

Introduction to Reactive Programming by André Staltz

Looks like the example project is not very good to learn reactive programming. The resulting code looks for me like a typical jQuery soup. Watch the next course instead.

Step-by-Step Async JavaScript with RxJS by John Lindquist

This course is much better than the previous one. But it’s still not very useful if you want to understand when to use reactive programming in real projects. Watch if you want to see how reactive programming with RxJS looks like.

React Native Fundamentals by Tyler McGinnis

I didn’t know much about React Native and wanted to know how it looks. This course was good for that. Through the course the author develops an app for displaying GitHub profiles so in the end you have an idea of how to make an app with React Native.

Why I Wrote Another Static Site Generator

For many years I was struggling every time I was using a someone else’s engine to build one of my sites. I’ve tried WordPress, Koken, Aegea, Django, DocPad and Hexo. Now all my personal sites (this blog, homepage and photo portfolio) work on my own static site generator —Fledermaus — and I’ve never been more happy.

It’s not my first engine:

  • fjSiter, 2002: PHP, MySQL, XSLT based content management system.
  • Custom PHP based generator for my photo gallery, 2008.
  • Sweet, 2011: Node.js based static site generator.
  • Springhare: Python based gallery engine, unfinished (the project was too big for one developer with limited time).
  • Others that I don’t remember.

Experience with other engines has taught me how an engine shouldn’t be implemented.

Usual site engine is a massive piece of code that’s optimized for a few the most popular use cases. But if you want something else you have to suffer: it’s either too hard or not possible at all. Often you end up with an ugly unstable code that breaks after every engine update.

It’s like in Joe Armstrong’s famous saying about object-oriented programming:

You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

But in that case the banana is half-eaten.

With the Fledermaus I took a different approach. Actually it’s just a collection of useful functions that you can use to write your own static site generator: loading Markdown source files, documents filtering, grouping and sorting, pagination, internationalization, generating HTML pages and RSS, etc.

You can combine them any way you want, add custom processing at any step, generate pages yourself. For example, in my photo gallery I read EXIF meta data from JPEG files and generate pages and albums based on this data.

It’s based on fancy modern things like ES2015, JSX, Markdown and Intl.

And it’s very small and fast:

Engine code
Docpad: 10300 lines (without 6 required plugins)
Hexo: 7800 lines (without 2 required plugins)
Fledermaus: 1300 lines

Blog code
Docpad: 211 lines
Hexo: 361 lines
Fledermaus: 159 lines

Build time
Docpad: 77,49s (version 6.78.4)
Hexo: 4,60s (version 3.1.1)
Fledermaus: 3,80s (version 5.0.1, including Babel transpilation)

It builds my whole photo gallery (2000 HTML pages) in 35 seconds on my 2011 MacBook Pro.

Now I finally can build stuff instead of crutches.