<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arnaud Spanneut</title>
    <description>The latest articles on DEV Community by Arnaud Spanneut (@arnaudspanneut).</description>
    <link>https://dev.to/arnaudspanneut</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F517323%2F554dfa1a-2321-482a-956d-49a780682316.jpg</url>
      <title>DEV Community: Arnaud Spanneut</title>
      <link>https://dev.to/arnaudspanneut</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arnaudspanneut"/>
    <language>en</language>
    <item>
      <title>Document your technical improvements to make them a success 🎯 </title>
      <dc:creator>Arnaud Spanneut</dc:creator>
      <pubDate>Tue, 15 Dec 2020 00:03:00 +0000</pubDate>
      <link>https://dev.to/arnaudspanneut/document-your-technical-improvements-to-make-them-a-success-43gh</link>
      <guid>https://dev.to/arnaudspanneut/document-your-technical-improvements-to-make-them-a-success-43gh</guid>
      <description>&lt;p&gt;Many software companies are facing the same problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to prioritize Non-functional requirements vs Functional requirements?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's explain first which is the difference between these requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Functional requirements&lt;/em&gt;: Come from user expectations. Example: Product feature development.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Non-functional requirements&lt;/em&gt;: Define the system quality attributes. Example: Architecture evolution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the same criticality level, functional projects often looks more urgent than non-functional projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The underlying reason come from the fact that non-functional projects are not as well managed as functional ones.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User needs are clear and documented &lt;em&gt;vs.&lt;/em&gt; Engineers' needs are in the engineers' minds.&lt;/li&gt;
&lt;li&gt;The product roadmap is defined for the next 3 months &lt;em&gt;vs&lt;/em&gt;. Non-functional projects are coming when we will have time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second point is inherent to the first. Lack of visibility does not give the same priority to a project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use the documentation as a tool.
&lt;/h1&gt;

&lt;p&gt;Using documentation to build on have many benefits in large companies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Having one channel to share and align people.
&lt;/h3&gt;

&lt;p&gt;There are plenty of ways to share ideas in a company. It could be on Slack, JIRA, with a Pull Request or even during a coffee discussion.&lt;/p&gt;

&lt;p&gt;Having one channel &lt;strong&gt;regroups knowledge and facilitates building&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Include engineers in decision process.
&lt;/h3&gt;

&lt;p&gt;The code base is the day-to-day engineers' tool. It is crucial to let them participate in the evolution of their platforms. &lt;strong&gt;It creates ownership and better adoption of the evolutions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Communicating earlier also prepares engineers for later. It is much easier to participate in a project that is still under consideration than in an RP that took a month to develop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Educating engineers.
&lt;/h3&gt;

&lt;p&gt;Sharing ideas on a dedicated channel is nice for engineers to learn practices.&lt;/p&gt;

&lt;p&gt;Besides, &lt;strong&gt;writing is a wonderful exercise to reinforce knowledge&lt;/strong&gt;. It helps to pose technical problems and solutions in a structured manner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build your software history.
&lt;/h3&gt;

&lt;p&gt;Understanding the origin and the timeline of past decisions is priceless in a company. There is nothing better than the written word to preserve the traces of the past.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://firstround.com/review/empathy-driven-development-how-engineers-can-tap-into-this-critical-skill/"&gt;It's a perfect way to create empathy&lt;/a&gt; by understanding why old decisions were made.&lt;/p&gt;

&lt;h2&gt;
  
  
  AD(R) as a template.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;An architectural decision record (ADR) is a document that captures an important architectural decision made along with its context and consequences. &lt;a href="https://github.com/joelparkerhenderson/architecture_decision_record"&gt;[source]&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The AD is an excellent model to open a discussion with a structured description that makes it clear to everyone.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is the starting point for expressing intent and allowing people to share their opinions and build on them.&lt;/p&gt;

&lt;p&gt;You can use &lt;a href="https://guides.github.com/features/issues/"&gt;GitHub's issues&lt;/a&gt; or &lt;a href="https://github.blog/2020-05-06-new-from-satellite-2020-github-codespaces-github-discussions-securing-code-in-private-repositories-and-more/#discussions"&gt;discussions&lt;/a&gt; as a tool to run this process. It's nice for writing, organizing, commenting and reacting with emojis. &lt;/p&gt;

&lt;p&gt;Any engineer who wants to propose an idea can create a document.&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Template
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context / Problems:&lt;/strong&gt; What is the actual problem of the system?
Describe what is going wrong. &lt;strong&gt;Why&lt;/strong&gt; is the current implementation problematic?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proposition:&lt;/strong&gt; How do you think it can be improved?
Describe how you would like to improve the architecture. Present a plan, add diagrams. The more you're clear, the more you convince that it is a good proposition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benefits:&lt;/strong&gt; Summary of how it will improve the system.
Bullet point of good impacts that this proposition will address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitation:&lt;/strong&gt; How could the project be risky?
Each solution has some limitations. List the different difficulties we could face on during the implementation (complexity/maintenance/lack of shared knowledge...).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deadlines&lt;/strong&gt;: When do you think it could be done?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;References:&lt;/strong&gt; Add relative links to other ADR, articles, videos, documentation or code.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ⚡️ Process
&lt;/h2&gt;

&lt;p&gt;The proposer has to lead this pretty simple process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open and complete the template.&lt;/li&gt;
&lt;li&gt;Share it and invite commenting and reactions on the proposal.&lt;/li&gt;
&lt;li&gt;When a Go is decided: Organize, animate and communicate about project progression.&lt;/li&gt;
&lt;li&gt;Deliver it.&lt;/li&gt;
&lt;li&gt;Celebrate 🎉.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🦄 Some simple rules
&lt;/h2&gt;

&lt;p&gt;If you want this process to be a success, there is some easy rules to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do not edit original document, build in comments.&lt;/li&gt;
&lt;li&gt;Use voice talking if you're struggling on writing. Then write the note on the document.&lt;/li&gt;
&lt;li&gt;Agree to be able to disagree on a proposition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As any project, be sure that engineers adopt it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is engineers' participation that will make it successful by creating a virtuous synergy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can nominate facilitators for the process to help people work with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each proposition should be small enough&lt;/strong&gt; to be done in a short term.&lt;/p&gt;

&lt;p&gt;For example, a framework migration which implies a full codebase modification cannot be treated by only one document.&lt;/p&gt;

&lt;p&gt;This could be, at least, the beginning of a discussion on how to divide the work and conduct to the opening of other ADRs.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With a better visibility, it is easier to talk about non-functional projects with leads and products.&lt;/p&gt;

&lt;p&gt;You can defend them by collecting and sharing engineering feedback. You can also include these projects in the roadmap.&lt;/p&gt;

&lt;p&gt;And don't forget to communicate on their success 🎉.&lt;/p&gt;

&lt;p&gt;This process can be extended for all decisions that has to be taken in a company. From product features to company organization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A teammate said once: “ADR is like having a technical discussion at the coffee machine.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the exception that is it in a more constructive and inclusive way.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>startup</category>
      <category>architecture</category>
      <category>learning</category>
    </item>
    <item>
      <title>How I saved 4 months of work on a code base migration with Codemod ✨</title>
      <dc:creator>Arnaud Spanneut</dc:creator>
      <pubDate>Fri, 20 Nov 2020 15:29:58 +0000</pubDate>
      <link>https://dev.to/arnaudspanneut/how-i-gained-4-months-of-work-on-the-migration-of-a-code-base-with-codemod-2pbn</link>
      <guid>https://dev.to/arnaudspanneut/how-i-gained-4-months-of-work-on-the-migration-of-a-code-base-with-codemod-2pbn</guid>
      <description>&lt;p&gt;The SimpliField mobile application started in 2014.&lt;/p&gt;

&lt;p&gt;At that time, AngularJS and Ionic were at the top 🕺. I decided to start with this stack but JavaScript &lt;strong&gt;Modules system was not yet the norm.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two years ago (2018), I thought it was time to &lt;strong&gt;migrate the code base to a new bright system of ES modules&lt;/strong&gt;. This migration was a good step forward to prepare the next code migrations (TypeScript, new framework...).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The code contained ~600 files&lt;/strong&gt; with our old friend's &lt;code&gt;IIFE&lt;/code&gt; function, an outdated syntax and without any modularization.&lt;/p&gt;

&lt;p&gt;I knew that a manual modification creates the risk of introducing bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗺 The Plan
&lt;/h2&gt;

&lt;p&gt;My plan to was to &lt;strong&gt;migrate the codebase incrementally&lt;/strong&gt; by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Updating the builder system to run ES module on some folders of the app.&lt;/li&gt;
&lt;li&gt;Rewriting folders with &lt;code&gt;export&lt;/code&gt; syntax.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;import&lt;/code&gt;ing exported files in a root file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I estimated at &lt;strong&gt;4 months the time needed to migrate&lt;/strong&gt; the code base (in parallel with other projects). It seemed like a long and difficult road before being able to start the next improvements.&lt;/p&gt;

&lt;p&gt;After 1 months of tedious work, I realized that the road could be longer than expected 😓.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Codemod
&lt;/h2&gt;

&lt;p&gt;And then, Codemod enter the game 🔥.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Codemod is a tool/library to assist you with large-scale codebase refactors that can be partially automated&lt;/em&gt; &lt;a href="https://github.com/facebook/codemod"&gt;[source]&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Codemod is parsing code source into an Abstract Syntax Tree (AST) which is the graph representation of the structure of source code. It provides a simple and comprehensive data structure to work with.&lt;/p&gt;

&lt;p&gt;To help you understand code AST, there is a set of useful tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://astexplorer.net/"&gt;AST Explorer&lt;/a&gt;: Your best friends for this mission. You can navigate, query and test the code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/estree/estree/blob/master/es5.md"&gt;EStree&lt;/a&gt;: Es tree syntax specification. It provides the documentation of nodes definition.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/facebook/jscodeshift"&gt;jscodeshift&lt;/a&gt;: Run Codemod over multiple JavaScript or TypeScript files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🕹 Let's play
&lt;/h2&gt;

&lt;p&gt;I will present a simple example to help you dive in a use case.&lt;/p&gt;

&lt;p&gt;But first, go on &lt;a href="https://astexplorer.net/"&gt;AST Explorer&lt;/a&gt; to configure the editor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy past the old syntax &lt;em&gt;in the upper left&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;@babel/parser&lt;/code&gt; &lt;em&gt;in the header&lt;/em&gt; (next to JavaScript)&lt;/li&gt;
&lt;li&gt;Activate &lt;code&gt;Transform&lt;/code&gt; option &lt;em&gt;in the header&lt;/em&gt; with jscodeshift&lt;/li&gt;
&lt;li&gt;Run and play with the code in the &lt;code&gt;transformer()&lt;/code&gt;  function &lt;em&gt;in the bottom left&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Enjoy the result &lt;em&gt;in the bottom right&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3SxTDtXk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/64qzaipgcjrxukoeagz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3SxTDtXk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/64qzaipgcjrxukoeagz1.png" alt="astexplorer.net_"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect, &lt;strong&gt;you're now ready!&lt;/strong&gt; 🚀.&lt;/p&gt;

&lt;p&gt;This is what we will expect from this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// old syntax&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;iife&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;say&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// result&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;HelloWorld&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;say&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We have to apply 2 transformations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove IIFE wrapper&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;export&lt;/code&gt; the &lt;code&gt;HelloWorld&lt;/code&gt; class&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  1. Remove IIFE wrapper
&lt;/h3&gt;

&lt;p&gt;Let's remove the IIFE wrapper to keep only the class. This is what our transformer has to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query the wrapper function

&lt;ul&gt;
&lt;li&gt;We will select all the &lt;code&gt;(function iife())&lt;/code&gt; wrapper&lt;/li&gt;
&lt;li&gt;First argument is the tree type we want: &lt;code&gt;j.ExpressionStatement&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Second argument is the node path selector (expression → callee → id → name) with the value &lt;code&gt;iife&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It can be found thanks AST explorer. Just click on iife value &lt;em&gt;in the upper right&lt;/em&gt; and look at the path.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Replace node

&lt;ul&gt;
&lt;li&gt;Call Codeshift API with AST node to use helpers.&lt;/li&gt;
&lt;li&gt;Replace the wrapper with his content (the class).
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jscodeshift&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 1. Query AST&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ExpressionStatement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;callee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iife&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Loop on AST nodes&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 3. Replace element&lt;/span&gt;
        &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Copy past the code above in the &lt;code&gt;transformer()&lt;/code&gt; function &lt;em&gt;in the bottom left&lt;/em&gt; and see the result &lt;em&gt;in the bottom right.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  2. Add export
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Copy past the result of the step 1 in the upper left&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s now export the class.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query the class element

&lt;ul&gt;
&lt;li&gt;First argument is the tree type we want: &lt;code&gt;j.ClassDeclaration&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Second argument: for this case, we don't need to query a specific class definition, so we can avoid it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Loop on AST nodes: &lt;code&gt;.forEach()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Define the new ES tree: &lt;code&gt;j.exportNamedDeclaration(content)&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;💡 Use AST explorer to know the definition of &lt;code&gt;export&lt;/code&gt; AST node&lt;/li&gt;
&lt;li&gt;💡 Use EStree documentation to know the implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Replace with the new export definition

&lt;ul&gt;
&lt;li&gt;Call Codeshift API with AST node to use helpers2.&lt;/li&gt;
&lt;li&gt;Replace the wrapper with his content → Remove &lt;code&gt;iife&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// 1. Query AST&lt;/span&gt;
&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ClassDeclaration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Loop on AST nodes&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 3. Define the new ES tree&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;exportNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exportNamedDeclaration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// 4. Replace with the new export definition&lt;/span&gt;
        &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exportNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Copy past the code above in the &lt;code&gt;transformer()&lt;/code&gt; function after the code of step 1 and see the result*.*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Et Voilà ! 🎉✨&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You now have your exported class without IIFE. And you can run it on all your affected files.&lt;/p&gt;

&lt;p&gt;You can now take the first old code and run both transformation and see your new file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can access to a full implementation here:&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ArnaudSpanneut"&gt;
        ArnaudSpanneut
      &lt;/a&gt; / &lt;a href="https://github.com/ArnaudSpanneut/codemod-example"&gt;
        codemod-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Codemod example for the article
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  👌 Conclusion
&lt;/h2&gt;

&lt;p&gt;With Codemod, you can migrate easily any codebase to new code style with peace of mind.&lt;/p&gt;

&lt;p&gt;You need to invest some time on the implementation, but it's totally worth it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It took me 1 week&lt;/strong&gt; to implement Codemod and migrate the SimpliField codebase&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation ideas
&lt;/h3&gt;

&lt;p&gt;You can do many things with Codemod to transform your code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run your updated code style on all the code base.&lt;/li&gt;
&lt;li&gt;Split methods from a source file to create one file per method.&lt;/li&gt;
&lt;li&gt;Update your code to move to another framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Some feedback regarding my experience playing with it:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It is a bit challenging query AST at the beginning.&lt;/li&gt;
&lt;li&gt;Create helpers function to help you migrate the code. You can compose your helpers to migrate different files depends on the syntax.&lt;/li&gt;
&lt;li&gt;Keeping a style of code in a project helps you migrate files because they respect the same structure.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;ast.forEach()&lt;/code&gt; instead of &lt;code&gt;ast[0]&lt;/code&gt;. It avoids adding a sanity check in case of the element doesn't exist in your tree.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Special thanks to &lt;a href="https://github.com/quentin-tardivon"&gt;Quentin Tardivon&lt;/a&gt; and &lt;a href="https://medium.com/@oleksandr.k"&gt;Oleksandr Korneiko&lt;/a&gt; for their help on this article.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>refactorit</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
