<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Kenneth Skovhus on Medium]]></title>
        <description><![CDATA[Stories by Kenneth Skovhus on Medium]]></description>
        <link>https://medium.com/@skovhus?source=rss-d6d792aa496a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Z04IajdYwRcbrvNKUv4LLA.jpeg</url>
            <title>Stories by Kenneth Skovhus on Medium</title>
            <link>https://medium.com/@skovhus?source=rss-d6d792aa496a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 04 Apr 2026 16:43:24 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@skovhus/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Converting an app to React Native — How to get started]]></title>
            <link>https://medium.com/leoilab/converting-an-app-to-react-native-how-to-get-started-924548ff6c62?source=rss-d6d792aa496a------2</link>
            <guid isPermaLink="false">https://medium.com/p/924548ff6c62</guid>
            <category><![CDATA[prettier]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[eslint]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Kenneth Skovhus]]></dc:creator>
            <pubDate>Fri, 13 Apr 2018 11:47:45 GMT</pubDate>
            <atom:updated>2019-03-07T10:20:38.955Z</atom:updated>
            <content:encoded><![CDATA[<h3>Converting an app to React Native — How to get started</h3><p>This is part 2 of a series. Check out <a href="https://medium.com/leoilab/converting-an-app-to-react-native-why-and-how-b56c02c07b96">part 1</a> if you want to know why we went for React Native and how we approached it.</p><p><em>Written by </em><a href="https://medium.com/u/d6d792aa496a"><em>Kenneth Skovhus</em></a><em> and </em><a href="https://medium.com/u/f5f04c5abc51"><em>Kevin Pelgrims</em></a><em>.</em></p><h3>React Native under the hood, a crash course</h3><p>To understand how React Native works on mobile, you first need to look at the virtual DOM (Document Object Model) that is used in both React and React Native. If you’ve ever done web development, you know how the DOM works in the browser. If not, you might be interested in <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction">reading up on it</a>. In short: The DOM represents a page as nodes and objects. In plain React, <a href="https://reactjs.org/docs/faq-internals.html">the virtual DOM</a> is an in-memory representation of the UI on top of the actual DOM. When a node or object changes, React will diff the virtual DOM and the actual DOM, and only update those nodes or objects that have changed. In React Native, there is no browser DOM. Instead, the virtual DOM is rendered into native iOS or Android views.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y2a-TrDHBq-DhT6qNHfzrw.png" /><figcaption>Virtual DOM in React and React Native</figcaption></figure><p>While you write plain JavaScript and JSX (tag syntax that is an extension to JavaScript) to define how your React Native app should look and behave, the UI is still rendered natively. Whenever there is a change in one of the nodes or objects, React Native will update the relevant parts of the UI automatically.</p><p>This is what sets React Native apart from other cross-platform solutions. Rendering native components significantly speeds up interaction with the app, and while this also introduces some complexities (sometimes you will need to create a custom UI component), for us, it was definitely a good trade-off.</p><h3>Navigation is hard</h3><p>Navigation has always been a bit of a problem on React Native, but the vast amount of packages that are available show that this area is under development. Ideally, Facebook would create or, at least, recommend one solution. But for now, that’s not the case, and we all have to choose a third party library and stick with it. For us, the main contenders were <a href="https://github.com/react-navigation/react-navigation">react-navigation</a> and <a href="https://github.com/wix/react-native-navigation">wix/react-native-navigation</a>. The first is very flexible and runs everything purely in JavaScript, while the second one is based on native navigation on both platforms. We decided to go with react-native-navigation because we felt like native components would make the app feel more familiar to our users.</p><h3>Getting used to JavaScript</h3><h4>JavaScript? No, thanks</h4><p>In mobile development circles, most people cringe at the thought of writing an entire app in JavaScript. Why would you even do such a thing? JavaScript has a lousy reputation, and rightfully so. If you worked with JavaScript a decade ago, you likely had a horrible experience. Suitable for small scripts on websites, but not ideal for developing an application of any significant size.</p><p>However, things have changed, and over the last ten years there have been significant development efforts in tooling, frameworks, and engines. We saw the creation of <a href="https://jquery.com/">jQuery</a>, <a href="https://developers.google.com/v8/">V8</a>, <a href="https://nodejs.org">Node</a>, <a href="http://backbonejs.org/">Backbone</a>, … All of these efforts propelled JavaScript into one of the most used languages in the world. Today, Google’s <a href="https://angularjs.org/">Angular</a> and Facebook’s <a href="https://reactjs.org/">React</a> are the two most popular JavaScript frameworks. They are used by Google and Facebook themselves and provide a solid foundation for app development.</p><h4>Modern JavaScript</h4><p>JavaScript itself also saw significant advances in the last few years. When <a href="http://www.ecma-international.org/ecma-262/6.0/">EcmaScript 6</a> came out, developers finally had access to features that were already common in most modern programming languages, such as classes, arrow functions (aka lambdas), string interpolation, let and const, and <a href="https://github.com/lukehoban/es6features">many more</a>. Meanwhile, <a href="http://coffeescript.org/">CoffeeScript</a> and <a href="https://babeljs.io/">Babel</a> pioneered <a href="https://scotch.io/tutorials/javascript-transpilers-what-they-are-why-we-need-them">transpilation</a> so everyone could start using new language features that were not yet implemented by all browsers or engines. ES 7 and 8 kept on advancing the language significantly, and by now we can say that JavaScript can be a very nice language to work with.</p><p>Of course, it’s not all sunshine and rainbows. While the language itself is getting better, it is still difficult to set up a good development environment. Because of the dynamic nature of the language, doing something as simple as renaming a variable can still be a challenge. Coming from Android, you might find JetBrains’ <a href="https://www.jetbrains.com/idea/">IntelliJ</a> useful, because of its familiarity. Web developers tend to stick with editors like <a href="https://code.visualstudio.com/">VSCode</a> or <a href="https://atom.io/">Atom</a> when they go to React Native. As long as the plugins are there to support what you need, you can use any editor you want.</p><p>We found that a lot of JavaScript’s shortcomings can be countered with internal coding conventions and a good tooling setup to enforce them. Once you get into the habit of writing good, idiomatic JavaScript in a proper architecture, it becomes quite nice, even when you come from Swift or Kotlin in native land.</p><h3>Tooling</h3><p>After we understood how React Native works and decided to make peace with JavaScript, we wanted to make sure we had the right tooling set up to enforce best practices, and that the native developers on our team are made aware when they write non-idiomatic JavaScript. The setup, with a variety of tools from the JavaScript and React ecosystem, also helps us write more maintainable code that is easier to read.</p><h4>Static analysis and code consistency</h4><p>The dynamic and loosely-typed nature of JavaScript makes it especially prone to runtime errors. To help us find these errors before running the app, we use <a href="https://eslint.org/">ESlint</a>. ESlint also helps us see dead code and detect problematic patterns that sneak into the codebase. Our configuration is based on the widely used <a href="https://www.npmjs.com/package/eslint-config-airbnb">eslint-config-airbnb</a>.</p><p>Although ESlint can also check that a codebase adheres to a specific style guideline, we strongly believe that a code style should be enforced by a tool. Instead of debating over coding style, we use <a href="https://prettier.io/docs/en/why-prettier.html">Prettier</a> to format our code. It <a href="https://github.com/prettier/eslint-plugin-prettier">integrates</a> with ESlint, so when hitting save in our editor the code is formatted and statically analyzed.</p><h4>State management</h4><p>For state management, we enjoy the simplicity and testability of <a href="https://redux.js.org/">Redux</a>. We use the <a href="https://github.com/rt2zz/redux-persist">redux-persist</a> middleware to read and write parts of our Redux store to disk.</p><h4>Static type checking</h4><p>We started rebuilding the application in React Native without types. But as the application grew, it became clear that a static type checking tool like Flow or TypeScript would help us refactor and discover bugs. The more of the codebase we covered with types, the more bugs we uncovered.</p><p>TypeScript by Microsoft and Flow by Facebook are similar tools, providing gradual static typing capabilities, a similar syntax, and widespread usage.</p><p>For React Native, Flow was a natural choice. It integrates nicely with the build tool, and most third-party libraries already provide Flow types.</p><p>A type checker is not a silver bullet, though. The learning curve is steep, and you find yourself fighting the type system. But we are happy that a lot of development is happening in this area. One of the most promising options for the future is <a href="https://reasonml.github.io/">Reason</a> (also by Facebook), a type-safe language build on top of OCaml which compiles to very readable JavaScript.</p><h4>Storybook as a productivity booster</h4><p>Storybook is a UI development environment for your UI components. With it, you can visualize different states of your UI components and develop them interactively.</p><p>If we were to dream up a productive setup for developing UI components and screens, it would:</p><ul><li>Work on components and screens in isolation without starting the entire application</li><li>Be able to describe and quickly switch between components and screens in different states</li><li>Support hot reloading when styles and markup changes</li><li>Have multiple simulators and cross-platform devices connected and see them all update when updating the code</li></ul><p>We are happy to see that <a href="https://storybook.js.org">Storybook</a> delivers all of these. It is a major productivity booster when developing UIs.</p><h4>Automated testing</h4><p>For unit and integration testing, we are using <a href="https://facebook.github.io/jest/">Jest</a> — another great open source tool by Facebook. It provides a testing framework with excellent watch mode, coverage support, fairly simple mocking and swift feedback when writing tests. As it runs in Node, you mock out all native components (though it requires some <a href="https://github.com/facebook/react-native/blob/1490ab12ef156bf3201882eeabfcac18a1210352/jest/setup.js">setup</a>).</p><p>We have experimented with Appium and Amazon Device Farm for cross-platform UI automation tests. But currently, we’re focusing on a solid and fast unit testing setup that helps us catch bugs and documents the expected behavior of our code.</p><h4>Editor support</h4><p>Everyone on the team uses their preferred editor, whether it be Visual Studio Code, Atom, or IntelliJ IDEA. To have a good and consistent development experience we ensure that all of our editors:</p><ul><li>Show ESlint errors</li><li>Call eslint — fix on file save (we never do manual formatting, we have Prettier for that)</li><li>Understand Flow declarations, so we get autocompletion and type errors in the editor</li></ul><h3>What’s next?</h3><p>While we are quite happy with the current setup, there is room still for improvement. One thing we want to do is to have a big set of UI tests. We’re not entirely sure yet what the best option for that would be. But in general, we now have a solid foundation on which we can build more features, and we have great checks in place that make sure our code adheres to best practices and our internal style. The development cycle is also a lot faster because of the unit tests and Storybook.</p><p>There is one more thing we feel is important when converting to React Native, and that is native modules and UI components. We will cover that in our next blog post.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=924548ff6c62" width="1" height="1" alt=""><hr><p><a href="https://medium.com/leoilab/converting-an-app-to-react-native-how-to-get-started-924548ff6c62">Converting an app to React Native — How to get started</a> was originally published in <a href="https://medium.com/leoilab">LEO Innovation Lab</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Type safe CSS Modules with Flow]]></title>
            <link>https://medium.com/hackernoon/type-safe-css-modules-with-flow-dd95e761bbe5?source=rss-d6d792aa496a------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd95e761bbe5</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[flowtype]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[css-modules]]></category>
            <dc:creator><![CDATA[Kenneth Skovhus]]></dc:creator>
            <pubDate>Tue, 20 Jun 2017 22:14:36 GMT</pubDate>
            <atom:updated>2017-07-20T19:04:25.915Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k1Qza6ToJzWKp45oIBjaKw.png" /><figcaption>CSS Modules + Flow = type safety and editor autocompletion</figcaption></figure><p>I’ve been dreaming about type safety and editor autocompletion when using <a href="https://github.com/css-modules/css-modules">CSS Modules</a>. There are a few TypeScript tools for this (see <a href="https://medium.com/@sapegin/css-modules-with-typescript-and-webpack-6b221ebe5f10">this</a> and <a href="https://github.com/Quramy/typed-css-modules">this</a>), but I didn’t find any solid tools for <a href="https://flow.org/">Flow</a>.</p><p><em>TL;DR I’ve made some </em><a href="https://github.com/skovhus/css-modules-flow-types"><em>new tools</em></a><em>, and when trying them on a codebase I’m working on, Flow found </em><strong><em>a lot of dead code (and potential bugs)</em></strong><em>… </em>😬</p><h3>The problems</h3><p>It is quite easy to misspell a class name or forget to update .js consumers after removing a class in a .css file. As an example, the class foo might not be defined in Button.css:</p><pre>/* @flow */<br>import styles from &#39;./Button.css&#39;;</pre><pre>const Button = () =&gt; &lt;button className={styles.foo} /&gt;;</pre><h3>Solutions</h3><p>To teach Flow about CSS Modules file, we can create a definition file Button.css.flow containing the class names exposed by Button.css. By doing so we can get:</p><ul><li>static type checks showing usage of non existing classes</li><li>editor autocompletion of CSS classes (for editors supporting Flow)</li></ul><p>To generate these .flow files I was thinking of two use cases. One using a simple CLI and another using webpack.</p><h3>Solution: CLI</h3><p><a href="https://www.npmjs.com/package/css-modules-flow-types-cli">css-modules-flow-types-cli</a> is a CLI that quickly generates .flow files.</p><p>Let us install it:</p><pre>npm install --save-dev css-modules-flow-types-cli</pre><pre># Or<br>yarn install -D css-modules-flow-types-cli</pre><p>And then just run the CLI on your source directory:</p><pre>css-modules-flow-types src</pre><p>I recommend using the CLI on your CI system (like Travis or Circle) to ensure that all .flow files are up-to-date before running Flow. This will catch potential styling errors before deploying.</p><p>Another use case is quick feedback loop when developing and changing CSS Modules files. The CLI includes a watch mode for this, but I myself would like to avoid having yet another tool that needs to be running while developing. As a lot of people already have webpack running, I did a small loader consuming the tokens from style-loader.</p><h3>Solution: webpack loader</h3><p><a href="https://www.npmjs.com/package/css-modules-flow-types-loader">css-modules-flow-types-loader</a> is a webpack loader keeping .flow files updated by consuming the tokens from style-loader. I recommend using this when developing as part of a webpack-dev-server setup. It will give a small slowdown, as the loader potentially needs write a lot of files.</p><p>To get started:</p><pre>npm install --save-dev css-modules-flow-types-loader</pre><p>Then update your webpack config:</p><pre>{<br>  test: /<strong>\.</strong>css$/,  // or the file format you are using<br>  use: [<br>    &#39;style-loader&#39;,<br>    &#39;css-modules-flow-types-loader&#39;,  // right after style-loader<br>    // Other loaders like css-loader after this:<br>    ...<br>  ]<br>}</pre><p>And then sit back and enjoy CSS Modules being type checked by Flow. 🍺</p><p>Please let me know what you think… And give a little ⭐️ over at github.</p><p><a href="https://github.com/skovhus/css-modules-flow-types">skovhus/css-modules-flow-types</a></p><figure><a href="http://bit.ly/HackernoonFB"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0hqOaABQ7XGPT-OYNgiUBg.png" /></a></figure><figure><a href="https://goo.gl/k7XYbx"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vgw1jkA6hgnvwzTsfMlnpg.png" /></a></figure><figure><a href="https://goo.gl/4ofytp"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gKBpq1ruUi0FVK2UM_I4tQ.png" /></a></figure><blockquote><a href="http://bit.ly/Hackernoon">Hacker Noon</a> is how hackers start their afternoons. We’re a part of the <a href="http://bit.ly/atAMIatAMI">@AMI</a> family. We are now <a href="http://bit.ly/hackernoonsubmission">accepting submissions</a> and happy to <a href="mailto:partners@amipublications.com">discuss advertising &amp; sponsorship</a> opportunities.</blockquote><blockquote>If you enjoyed this story, we recommend reading our <a href="http://bit.ly/hackernoonlatestt">latest tech stories</a> and <a href="https://hackernoon.com/trending">trending tech stories</a>. Until next time, don’t take the realities of the world for granted!</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*35tCjoPcvq6LbB3I6Wegqw.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dd95e761bbe5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hackernoon/type-safe-css-modules-with-flow-dd95e761bbe5">Type safe CSS Modules with Flow</a> was originally published in <a href="https://medium.com/hackernoon">HackerNoon.com</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React PropTypes to Flow codemod]]></title>
            <link>https://medium.com/netscape/react-proptypes-to-flow-codemod-9757f5ec5381?source=rss-d6d792aa496a------2</link>
            <guid isPermaLink="false">https://medium.com/p/9757f5ec5381</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[codemod]]></category>
            <category><![CDATA[flowtype]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Kenneth Skovhus]]></dc:creator>
            <pubDate>Mon, 10 Apr 2017 22:07:31 GMT</pubDate>
            <atom:updated>2017-04-11T09:58:28.831Z</atom:updated>
            <content:encoded><![CDATA[<p><em>I’m presenting how to automatically convert your existing codebase using React PropTypes to use more powerful Flow annotations. If you already seen why this is valuable, you can skip down to the next section.👇🏻</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IRx7U41KnABubMY9pY3TLw.jpeg" /><figcaption>Eye candy, because you deserve it (<a href="https://unsplash.com/@thekorus">unsplash.com/@thekorus</a>)</figcaption></figure><p>If React were Facebook’s gateway drug to declarative and composable UI, React PropTypes introduced a lot of people to type checking.</p><p>PropTypes documents a given<strong> </strong>component’s props and gives runtime validation of props during development. I find them really helpful, but they also have <a href="http://technologyadvice.github.io/eradicate-runtime-errors-in-react-with-flow/">several shortcomings</a>. Most notably we should aim to catch errors before opening our browser. Say hello to static type checking.</p><p>To statically type-check an application, you can use JavaScript extensions like <a href="https://flow.org/">Flow</a> or <a href="https://www.typescriptlang.org/">TypeScript</a>. In this blog post I’m focusing on Flow, but the same approach can be applied to TypeScript.</p><blockquote>No doubt: Static type checking (using Flow or TypeScript) at build time is vastly superior runtime validation.</blockquote><p>If you are new to Flow, the <a href="https://flow.org/">new documentation is really good</a>. After setting up Flow you can now start type annotating your components state and props. For a simple component it might look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ecbcc85cd121dbed1857ff72d57602b4/href">https://medium.com/media/ecbcc85cd121dbed1857ff72d57602b4/href</a></iframe><p>So far so good. But transitioning an existing codebase to use Flow annotations instead of PropTypes can be tedious... However this is a perfect task for a codemod!</p><h3>Time to mod the code</h3><p>To automate the conversion of React PropTypes to Flow annotations, we are using another tool popularized by Facebook: <a href="https://github.com/facebook/jscodeshift">jscodeshift</a> (JavaScript codemod toolkit).</p><p>If the concept of automated refactoring with codemods is new to you, I’ll shamelessly self promote a meetup talk I recently did:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Ffast.wistia.net%2Fembed%2Fiframe%2Fzjjqx99d0d%3Ftwitter%3Dtrue&amp;src_secure=1&amp;url=https%3A%2F%2Ffast.wistia.com%2Fembed%2Fiframe%2Fzjjqx99d0d&amp;image=https%3A%2F%2Fembed-ssl.wistia.com%2Fdeliveries%2F866fe7098c25360bf506c31a819d00e8ebe45b47.jpg%3Fimage_crop_resized%3D640x360&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=wistia" width="640" height="360" frameborder="0" scrolling="no"><a href="https://medium.com/media/34c0d11c73e348f1b9ff7d32f512bd88/href">https://medium.com/media/34c0d11c73e348f1b9ff7d32f512bd88/href</a></iframe><p>Enough talk. Time to get rid of the PropTypes! Turns out <a href="https://github.com/billyvg">Billy Vong</a> already did a lot of the hard work for us with <a href="https://github.com/billyvg/codemod-proptypes-to-flow">codemod-proptypes-to-flow</a>.</p><p><a href="https://github.com/billyvg/codemod-proptypes-to-flow">billyvg/codemod-proptypes-to-flow</a></p><p>So to automatically convert all components in a folder my-components:</p><ul><li>git clone <a href="https://github.com/billyvg/codemod-proptypes-to-flow">https://github.com/billyvg/codemod-proptypes-to-flow</a></li><li>jscodeshift -t codemod-proptypes-to-flow/src/index.js my-components</li><li>Look no PropTypes! (Although <em>createClass</em>, imported and custom PropTypes validators are not supported — yet!)</li></ul><p>I’ve successfully used this codemod for multiple projects, and it eased the transition remarkably. Now Flow starts finding errors while you write the code instead of when the code is executed! 🍷 🙌🏻</p><p>Notice that there are cases where you want to keep your PropTypes (possible alongside Flow annotations):</p><ul><li>PropTypes in library code can help consumers and document an interface</li><li>If you have no automated tests validating your flow definitions of any external resources (like an API), PropTypes can be really helpful. For this I would recommend using <a href="https://github.com/brigand/babel-plugin-flow-react-proptypes">babel-plugin-flow-react-proptypes</a> to add PropTypes at build time</li><li>PropTypes are still great for learning material on React (no need to burden new people with Flow/TypeScript)</li><li>PropTypes can be more flexible than what the Flow type-checker currently supports (e.g. <a href="https://twitter.com/Daniel15/status/851232924225556480">validating a number is in a particular range</a>)</li></ul><p><em>(Thanks to </em><a href="https://twitter.com/penzington"><em>Maciek Pekala</em></a><em> and </em><a href="https://twitter.com/Mads_Hartmann"><em>Mads Hartmann</em></a><em> for reviewing this post)</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9757f5ec5381" width="1" height="1" alt=""><hr><p><a href="https://medium.com/netscape/react-proptypes-to-flow-codemod-9757f5ec5381">React PropTypes to Flow codemod</a> was originally published in <a href="https://medium.com/netscape">Netscape</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Abandoning the mothership]]></title>
            <link>https://medium.com/@skovhus/abandoning-the-mothership-2d15b7e9313e?source=rss-d6d792aa496a------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d15b7e9313e</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[front-end-development]]></category>
            <dc:creator><![CDATA[Kenneth Skovhus]]></dc:creator>
            <pubDate>Tue, 27 Sep 2016 15:05:00 GMT</pubDate>
            <atom:updated>2016-09-27T15:08:09.172Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<p>The time had come to pour into our front-end code the same poison we had given our back-end systems.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hwjLPHCW1xVywdYwW766qQ.jpeg" /></figure><p><em>Part 2 of “Toward a maintainable front-end” series. Part 1 is </em><a href="http://engineering.issuu.com/2015/09/15/mess-management.html"><em>here</em></a><em>.</em></p><p>For many years, issuu’s engineering group was organized around component teams. Our late great Team Monster handled the front-end code and the rest of the teams provided APIs and back-end infrastructure.</p><p>As we scaled the engineering organization, this classical split became counterproductive. A lot of cross team coordination was required for releases. Business logic and remappings were spread across multiple layers of the application. Dependencies and ownership of features were unclear. Finally, the Monsters had way too much on their plate!</p><p>So in 2013, several of our teams transitioned from component teams to customer-centric, cross-component feature teams. One focused on the end-to-end reading experience, another team handled all publisher-related features and so on. Next was taking ownership of the entire code stack, from database to front end. Our back-end system quickly transitioned into smaller microservices written in technologies the team deemed best (OCaml, Erlang, Python, node.js, MySQL, Postgres, Redis, AMQP).</p><p>Until recently, though, the front-end code running issuu.com was still one big, monolithic codebase. It had turned into such an unmanageable beast that we were all fighting with each other to get features out to users. We identified several blockers:</p><ul><li>With one big pile of code, team ownership and dependencies were unclear;</li><li>we stepped on other people’s toes all the time;</li><li>and as a result the rate of feature deployment decreased. (Oh yes, big-bang releases!)</li></ul><p>Besides, we had a major technology lockdown due to a very customized build system. This alone was around 3.000 lines of code, including a home-built Browserify and a lot of magical grunt tasks. As nobody dared to touch that part of the system, we were locked to our own require system, ES5 and Ruby SASS. Also the size of the codebase made builds painfully slow.</p><p>It was time to pour into our front-end code the same poison we gave our back-end systems, splitting it all apart into maintainable chunks. Our vision was to make each feature team own, build and deploy its front-end code autonomously – and to make things that ought to be trivial actually trivial!</p><h3>To the lifeboats!</h3><p>We started by dividing the front-end codebase into four chunks:</p><ul><li>shared serving infrastructure;</li><li>pages;</li><li>widgets;</li><li>and UI components.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zWvk6hxjMaR7JhdjYj_d4g.png" /><figcaption>Partitioning our frontend-end code base</figcaption></figure><p>The <strong>shared serving infrastructure</strong> is a thin horizontal node.js application responsible for routing and serving <strong>pages</strong>. It holds the configuration for which version of a page to be served.</p><p>A feature team delivers products consisting of the following:</p><ul><li><strong>pages</strong> (node.js handlers, templates and assets like compiled JavaScript/CSS);</li><li>and some <strong>widgets</strong> (shared functionality used on multiple pages, like a message hub, streams or drag-and-drop functionality to initiate a publication upload).</li></ul><p>Our <strong>UI component</strong> package provides high-level building blocks and styling for the site. It is our shared horizontal toolkit for keeping a consistent look and not reinventing buttons, form elements, modals and colors for each page and widget.</p><p>To handle internal code dependencies, we decided to use the same tool we use for all other dependencies in JavaScript: <a href="https://www.npmjs.com/">npm</a>. So we set up a <strong>private npm repository</strong> using the open-source <a href="https://github.com/rlidwka/sinopia">Sinopia tool</a>. When pushing code on master for one of our front-end repositories, our CI server will test and publish a new version of the package to Sinopia.</p><p>To release a change to a page, you simply bump the product version in the shared webserver package. The package.json for our webserver looks like this:</p><pre>{<br>  &quot;dependencies&quot;: {<br>    &quot;issuu-productA&quot;: “1.0.2”,<br>    &quot;issuu-productB&quot;: “2.0.292”,<br>    &quot;issuu-productC&quot;: “1.0.x”<br>    …<br>  }<br>}</pre><p>To follow the principle of least astonishment, most of our top-level packages are locked to a specific version of a page, but some packages like Marketing pages will always take the newest version.</p><p>How did we migrate to this? After the initial serving infrastructure was ready, we made it up to the feature teams to take ownership of the old mothership codebase and turn it into a product/widget in the new world. Of course, the mothership still holds tight to some old products we never touch and that no team really owns. <strong>In the end, it is all about ownership.</strong></p><p>After a few months, the old monolithic codebase is split into 45 packages. Oh, 46 now!</p><h3>A new hope</h3><p>Instead of the old, frustrating technology lockdown, over the last six months a lot our feature teams have been innovating on the tools they have for building products. Most of the teams use the following:</p><ul><li>Makefiles for orchestrating everything why <a href="https://algorithms.rdio.com/post/make/">reinvent the wheel</a>?;</li><li><a href="https://webpack.github.io/">Webpack</a> for building assets;</li><li><a href="https://babeljs.io">Babel</a> for allowing us to write slick ES6 code that transpiles to ES5;</li><li>a move to React and Redux;</li><li>strict linting using <a href="http://eslint.org/">ESLint</a>;</li><li>and more as we go. Nothing stops a team from trying out TypeScript, CSS Modules, Elm, etc.</li></ul><p>We are now able to work on isolated, vertical features without worrying about stepping on toes. Deployment time went from 30 minutes to just a few minutes, as we are rebuilding only what have changed and not the entire codebase. We went from a few weekly deploys to multiple times daily &amp;mdash; continuous delivery for the win!</p><p>The one constraint for a product is that it can be served by node. Heck, we are already talking about breaking the horizontal node server into smaller servers and letting the top-level routing logic reside in a proxy configuration. Ultimate autonomy to the team.</p><h3>A note on sharing code, and lessons learned</h3><p>We want to make fast iterations on products and sustain team autonomy. Our new system is optimized for changes in issuu’s vertical products, not for making horizontal changes easier. It highlights clearly that we still have a lot of horizontal dependencies.</p><p>In our old mothership repository, it is very easy to make a horizontal change and share a lot of code between products. One thing the code split has highlighted is that developers intuitively love to share code. Instead of copying and pasting small pieces, we would rather generalize it into shared components. This comes at a high cost: You now have yet another dependency, and *dependencies slow you down.* You lose autonomy and make simple things complex.</p><p>On the scale of a single product or feature, team code reuse and the <a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">principle of DRY</a> still make sense. But one should be careful about sharing code between products as shared dependencies are cumbersome. Of course, you never want to duplicate business logic, but I would much rather duplicate simple components than share them between verticals.</p><p>Still, redundancy sucks, right? I’m going to end with a quote from the excellent post by <a href="http://yosefk.com/blog/redundancy-vs-dependencies-which-is-worse.html">Yossi Kreinin</a>:</p><blockquote>Redundancy always means duplicated efforts, and sometimes interoperability problems. But dependencies are worse. The only reasonable thing to depend on is a full-fledged, real module, not an amorphous bunch of code. You can usually look at a problem and guess quite well if its solution has good chances to become a real module, with a real owner, with a stable interface making all its users happy enough. If these chances are low, pick redundancy. And estimate those chances conservatively, too. Redundancy is bad, but dependencies can actually paralyze you. I say kill dependencies first.</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d15b7e9313e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>