<?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: Mark Lennox</title>
    <description>The latest articles on DEV Community by Mark Lennox (@mlennox).</description>
    <link>https://dev.to/mlennox</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%2F138418%2Fd15a8164-72e7-4130-ac13-7fe71b55bc67.png</url>
      <title>DEV Community: Mark Lennox</title>
      <link>https://dev.to/mlennox</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mlennox"/>
    <language>en</language>
    <item>
      <title>Differential Privacy - Sharing Insights Privately, In Public</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Mon, 28 Oct 2019 17:57:58 +0000</pubDate>
      <link>https://dev.to/mlennox/differential-privacy-sharing-insights-privately-in-public-15ic</link>
      <guid>https://dev.to/mlennox/differential-privacy-sharing-insights-privately-in-public-15ic</guid>
      <description>&lt;p&gt;&lt;a href="https://www.webpusher.ie/differential/privacy/"&gt;This is a cross-post from my personal blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a previous article I explained &lt;a href="https://webpusher.ie/anonymous/data/not/"&gt;there is no such thing as anonymised data&lt;/a&gt;. If you don't want a privacy breach, don't release your dataset - in any form. As I explained, even statistical and demographic summaries of the data can be used in so-called reconstruction attacks to reveal information about individuals in the dataset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eCeJ5ssQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/a2lqw7ftv4ak8ugbegk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eCeJ5ssQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/a2lqw7ftv4ak8ugbegk5.png" alt="city skyline at dawn, with rays of light cutting through the morning mist by Josh Rose from unsplash.com"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/@joshsrose?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by Josh Rose on Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But for some datasets - such as census data - it is a &lt;em&gt;legal obligation&lt;/em&gt; to release statistical analysis. It is also a legal obligation to preserve the privacy of citizens who participated in the census, but releasing the required statistical analysis will breach privacy...&lt;/p&gt;

&lt;p&gt;You're damned if you do, and damned if you don't!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;computer science got us into this mess, can it get us out of it? - &lt;a href="https://dataprivacylab.org/people/sweeney/"&gt;Latanya Sweeney&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Privacy in the context of statistical analysis
&lt;/h2&gt;

&lt;p&gt;Before we dive into what differential privacy is, we should look at what we - as potential dataset creators - should consider if we care about privacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep it private
&lt;/h3&gt;

&lt;p&gt;It bears repeating - there is no such thing as anonymised data, so we know &lt;em&gt;we must never release the raw data&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Differential privacy is not concerned with data warehousing nor security, we'll just wave our hands here and say "the data is never public".&lt;/p&gt;

&lt;h3&gt;
  
  
  Protect the individuals
&lt;/h3&gt;

&lt;p&gt;We want to ensure that the presence, or lack, of an individual in a dataset will not expose any details of that individual - usually easier with a large dataset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limit the number of queries
&lt;/h3&gt;

&lt;p&gt;While so-called reconstruction attacks cannot be used against differentially private functions, allowing unlimited queries is a de-facto privacy breach. The number of queries should be limited because we know each query results in a loss of privacy.&lt;/p&gt;

&lt;p&gt;If we set an upper limit to how much privacy loss is &lt;em&gt;acceptable&lt;/em&gt;, and we quantify the privacy loss of each query, then we have the basis of a &lt;em&gt;privacy budget&lt;/em&gt; to limit queries from individual researchers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differential privacy
&lt;/h2&gt;

&lt;p&gt;Differential privacy &lt;strong&gt;mathematically&lt;/strong&gt; guarantees that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;anyone seeing the result of a differentially private analysis will essentially make the same inference about any individual's private information, whether or not that individual's private information is included in the input to the analysis&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not only that, but the results of differentially private statistical analysis are immune to reconstruction attacks, linkage attacks, re-identification, and can be combined with other datasets - present and future - without exposing privacy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That is amazing.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How do we do this?
&lt;/h3&gt;

&lt;p&gt;We add noise.&lt;/p&gt;

&lt;p&gt;But how much noise should be added? We want our dataset to be useful, but also preserve privacy. If we add a small amount of noise the statistical results will be very accurate, but the privacy of individuals will be threatened. If we add a lot of noise then the privacy of individuals is guaranteed, but the statistical accuracy will suffer and the data will be useless.&lt;/p&gt;

&lt;p&gt;In order to achieve the most accurate statistical results while preserving privacy, it is vitally important to accurately calculate the minimum amount of noise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy loss parameter
&lt;/h3&gt;

&lt;p&gt;Each query made against a differentially private system will result in a loss of privacy, but as curators of the dataset we choose to set a maximum acceptable level of privacy loss using whatever criteria are relevant to the application. ε-differential privacy quantifies this maximum acceptable loss of privacy using the privacy loss parameter ε (epsilon).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ε - privacy loss parameter&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The larger the value of ε the more privacy is lost. The variable ε quantifies the privacy loss for &lt;em&gt;any&lt;/em&gt; query against an ε-differentially private system. A suitable value for ε could be between 0.1 and 1, although in practice much higher values are in use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7_2aApc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/klfjbt1gs4tzc0hk6bs0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y7_2aApc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/klfjbt1gs4tzc0hk6bs0.png" alt="the output of two databases - one without a person's details, and one with the person's details - should have output that is within epsilon of being identical"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sensitivity determines noise level
&lt;/h3&gt;

&lt;p&gt;To determine how much noise should be added to the results of a particular query we need to figure out the &lt;em&gt;sensitivity&lt;/em&gt; of that query. Sensitivity is a measure of the influence an individual's data can have on the output of a query. The higher the sensitivity, the higher the level of noise required to preserve privacy.&lt;/p&gt;

&lt;p&gt;Imagine a small dataset containing the data of only 100 people. This means each person contributes roughly 1% of the total information. Clearly &lt;em&gt;any&lt;/em&gt; query will have high sensitivity as the dataset is so small. We would need to add a lot of noise to preserve privacy.&lt;/p&gt;

&lt;p&gt;Even in larger datasets queries can have high sensitivity. A query such as "billionaires with blue eyes, living in Florida, and taller than 1.8 metres" will have high sensitivity no matter how large the dataset.&lt;/p&gt;

&lt;p&gt;It's straightforward to calculate the worst-case sensitivity of &lt;em&gt;any&lt;/em&gt; query but more difficult to calculate the &lt;em&gt;exact&lt;/em&gt; sensitivity of a particular query. This results in a higher level of noise than required to preserve privacy, and reduces accuracy of statistical analysis.&lt;/p&gt;

&lt;p&gt;The accurate calculation of the sensitivity of queries is an important area of research as it aims to squeeze more accuracy from statistical queries against datasets while preserving privacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy Budget And Composability
&lt;/h3&gt;

&lt;p&gt;Each query made against an ε-differentially private function results in a loss of privacy, and as we said the dataset creator chooses the maximum acceptable privacy loss. It is possible for users querying the dataset to choose a privacy loss for each query that suits their needs as long as that privacy loss is less than the acceptable maximum privacy loss set by the dataset curator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--miqPm8UV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lemth5gj61av6dasmt76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--miqPm8UV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/lemth5gj61av6dasmt76.png" alt="a dial labelled epsilon represents the choice between high and low privacy, shown by two images of Eric Blair where the one representing high privacy is blurred and labelled with his pen name George Orwell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Researchers can choose to make many queries with low privacy loss, say 1 / 10 of ε, resulting in lower accuracy but higher privacy (ie. lower privacy &lt;em&gt;loss&lt;/em&gt; for the individual) for each query, or choose a higher privacy loss and make fewer queries but with higher accuracy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy budget
&lt;/h3&gt;

&lt;p&gt;Broadly speaking, you can track your privacy budget by adding together the fraction of ε used in each query. If you have made 10 queries each with a privacy loss which is 1/10 ε, then you can make no more queries as you have used your privacy budget.&lt;/p&gt;

&lt;p&gt;A useful visualisation of this process is a hidden image revealed by uncovering random squares where the size of the square is determined by ε. You can see that smaller fraction of ε allows for more queries while still preserving the mystery of the hidden image. Queries using a larger fraction of ε would very quickly reveal the image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--80nrBQjU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zxa83wj19tn6ufiozhqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--80nrBQjU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zxa83wj19tn6ufiozhqi.png" alt="comparison of images revealed by cutting different sized squares through a black layer - cutting many smaller squares reveals less information about the image than cutting much fewer but larger squares"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/@arifriyanto?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo from Arif Riyanto on Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most queries, as described above, are known as sequential queries and simply add their privacy loss to the total used so far. There are also &lt;em&gt;parallel&lt;/em&gt; queries that only add a single unit of privacy loss no matter how many queries are made in parallel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composability
&lt;/h3&gt;

&lt;p&gt;The result of each query is differentially private, and the combination of query results is also differentially private - a valuable feature of differential privacy called &lt;em&gt;composability&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Composability means that while each subsequent query does increase privacy loss, the queries cannot be combined in a way that will lead to privacy loss greater than the sum of all the privacy loss from queries up to that point. As mentioned before, ε-differentially private statistical analysis is immune to reconstruction attacks. If you make 10 queries with privacy loss ε you will only ever have 10ε privacy loss - &lt;em&gt;incredible!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Group privacy
&lt;/h3&gt;

&lt;p&gt;What we have been talking about up to this point has applied to the details of a single person. What if we are concerned with a group of people, such as a family? The same principle of composability applies to groups of people. The privacy loss of an individual is ε and the privacy loss of a group of people is kε where &lt;em&gt;k&lt;/em&gt; is the number of people in the group.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accuracy
&lt;/h2&gt;

&lt;p&gt;We're adding noise, so how useful can any statistical analysis be?&lt;/p&gt;

&lt;p&gt;The outputs from ε-differentially private functions are noisy. If you make the same query twice you'll get two different answers. Remember that smaller ε means larger privacy, and thus less accuracy, which in practical terms means more variation between results from the same query.&lt;/p&gt;

&lt;p&gt;The query sensitivity has a large part to play in the accuracy of any analysis. We know queries against small datasets have high sensitivity, and thus require relatively more noise to preserve privacy. Similar queries against large datasets have relatively lower sensitivity and need less noise to preserve privacy.&lt;/p&gt;

&lt;p&gt;Querying larger datasets result in more accurate results while preserving the same level of privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy washing
&lt;/h2&gt;

&lt;p&gt;Just because a company is open about its approach to privacy does not mean it has your best interests at heart. I can forsee a lot of companies convincing people that their data is private and "safe", encouraging them to share more - this is just &lt;em&gt;privacy-washing&lt;/em&gt; the fact that they are data mining their customers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eV6MMPf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oglk7dldo765lklnpofq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eV6MMPf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/oglk7dldo765lklnpofq.jpg" alt="Three card monte - the original public con trick"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apple, Google, and the U.S. Census are high-profile examples of ε-differential privacy in the real-world. The U.S. Census has been &lt;a href="https://www.census.gov/content/dam/Census/newsroom/press-kits/2019/jsm/presentation-deploying-differential-privacy-for-the-2020-census-of-pop-and-housing.pdf"&gt;very open and clear about how they implement differential privacy&lt;/a&gt;, as has &lt;a href="https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42852.pdf"&gt;Google with regard to its RAPPOR technology&lt;/a&gt;. Apple, however, have been less forthcoming.&lt;/p&gt;

&lt;p&gt;Despite data-mining issues, companies can badly implement differential privacy. This can either be from simple incompetence or by choice. It takes time and money to properly implement differential privacy - as mentioned before data security is essential. A company might choose to cut costs and knowingly use a poor implementation that leaks their customer's privacy.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>privacy</category>
      <category>differentialprivacy</category>
    </item>
    <item>
      <title>No such thing as anonymous data</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Wed, 02 Oct 2019 07:35:03 +0000</pubDate>
      <link>https://dev.to/mlennox/no-such-thing-as-anonymous-data-13kk</link>
      <guid>https://dev.to/mlennox/no-such-thing-as-anonymous-data-13kk</guid>
      <description>&lt;p&gt;New York City publicly released anonymised data of almost two million taxi rides - including fares and tips - in order to facilitate research into transport, traffic, and civic planning by independent researchers. However, they made a mistake - they only replaced the tax medallion number with the MD5 hash of the number. MD5 hashes are computationally weak which allowed a privacy researcher &lt;a href="https://en.wikipedia.org/wiki/Vijay_Pandurangan"&gt;Vijay Pandurangan&lt;/a&gt; to re-identify every taxi driver in the dataset exposing their home address, and income.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1wrp1Rut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xvu58j1ub508105ob1ll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1wrp1Rut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/xvu58j1ub508105ob1ll.png" alt="New York Taxi driving down 7th Avenue through a cloud of steam"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image provided by &lt;a href="https://unsplash.com/@withluke"&gt;Luke Stackpoole&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not only that, other researchers showed that the addresses of celebrities could be exposed by cross-referencing images of them entering or leaving taxis in paparazzi pictures.&lt;/p&gt;

&lt;p&gt;Despite the fact that the cause of this disastrous privacy breach was actually due to using a weak hashing algorithm to mask the highly sensitive taxi medallion number, as &lt;a href="https://en.wikipedia.org/wiki/Cynthia_Dwork"&gt;Cynthia Dwork&lt;/a&gt; says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;de-identified data isn't&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By this she means that either the data is not de-identified (anonymous), or is not data!&lt;/p&gt;

&lt;h2&gt;
  
  
  De-identified? Anonymous?
&lt;/h2&gt;

&lt;p&gt;Even if efforts are made to achieve anonymised datasets - masking information, generalising, or even deleting directly and indirectly identifying information, privacy can still be jeopardised. Even if everything is done perfectly with no mistakes, privacy is never guaranteed. Once a dataset is public, it is open to privacy attacks including re-identification attacks, differencing, record linkage - all of which I'll briefly explain the various attacks below.&lt;/p&gt;

&lt;p&gt;Any dataset is also open to attacks from unknown or future attacks. A dataset might have been processed using rules that &lt;em&gt;should&lt;/em&gt; guarantee privacy, but that guarantee has either failed immediately or will fail in the near future either because of increases in computing power, new techniques, or new datasets from unrelated organisations that can be used to reveal identities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference attack
&lt;/h2&gt;

&lt;p&gt;If you have some knowledge about an individual, you can use that to examine multiple statistics in which the individual's data is included. In short, a differencing attack can occur where multiple questions on their own do not risk re-identifying an individual, but if two or more of the questions are asked they risk exposing an individual's identity.&lt;/p&gt;

&lt;p&gt;For instance, if we know an individual is male, and vegetarian and attends a dinner where aggregate data of attendees is released, we can directly identify the individual if he is the only man to order a vegetarian meal. This may seem trivial, but the full data record from the event for the individual could be leveraged in a separate attack in different datasets.&lt;/p&gt;

&lt;p&gt;This is a trivial example, easily noticed and understood by humans. Algorithms can quickly process large datasets, combining multiple datapoints, easily exposing an individual's details. A simple task for the algorithm but impossible for a human to notice and avoid before a dataset is released.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-identification attacks
&lt;/h2&gt;

&lt;p&gt;If an attacker knows even a single piece of information about an individual, they can use that to identify an individual's information in a publicly available, anonymised dataset.&lt;/p&gt;

&lt;p&gt;In 2006 Netflix published their user's movie-ranking information. The data had been anonymised - de-identified - by replacing the users names with random numbers, and changing their personal details. &lt;a href="https://www.securityfocus.com/news/11497"&gt;Arvind Narayanan and prof. Vitaly Shmatikov&lt;/a&gt; managed to re-identify individuals in the dataset using publicly available IMDB movie ratings. In fact, it was discovered that knowing the date of two public movie reviews was enough to have a nearly 70% chance of re-identifying an individual in the so-called anonymised dataset.&lt;/p&gt;

&lt;h2&gt;
  
  
  Record Linkage
&lt;/h2&gt;

&lt;p&gt;Record linkage happens when an attacker can connect anonymised, often unrelated, datasets in order to reveal the identity of an individual. This is possible when datasets contain the same information about an individual, called indirect identifiers, or quasi-identifiers.&lt;/p&gt;

&lt;p&gt;Quasi-identifiers do not directly identify an individual, but when combined with other quasi-identifiers will identify that individual.&lt;/p&gt;

&lt;p&gt;A famous example of a linkage attack ocurred in Massachussets in 1997. There was some controversy over patient information released publicly, despite assurances from the governer William Weld that all direct identifiers had been deleted. Famously &lt;a href="https://dataprivacylab.org/people/sweeney/"&gt;Latanya Sweeney&lt;/a&gt; took this publicly available, and supposedly anonymised data, and compared it with another publicly available dataset - the voting register, which she obtained for $20. With these two sets of data she was able to find the Governer's personal medical records. The reason this attack succeeded was the patient's zip code, date of birth, and sex, were untouched in the dataset of hospital attendance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PYHQkXTm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rvefao18bb62akse6dti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PYHQkXTm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/rvefao18bb62akse6dti.png" alt="electronic instrumentation with colourful patch wires connecting modules"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image provided by &lt;a href="https://unsplash.com/@barkiple"&gt;John Barkiple&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reconstruction attack
&lt;/h2&gt;

&lt;p&gt;This last attack is probably the most dangerous because it works not by using the dataset directly, but by relying on statistics from the dataset. Researchers often release statistical aggregations from their publicly available datasets - percentage of people who are married, single, divorced, or income bands, gender, etc. These seem innocuous, but every piece of aggregated data filters the possible set of records that could have contributed to that statistic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://simson.net/page/Main_Page"&gt;Simson Garfinkel&lt;/a&gt; - Senior Scientist on the U.S. Census Bureau team for disclosure avoidance - showed that it is possible to reconstruct the personal data of individuals from a summary of the mean and median age, and frequency count broken down by some demographics - gender, income, marital status.&lt;/p&gt;

&lt;p&gt;Even if the source dataset is never exposed to the public, the more statistics that are released, the more individual's details will be exposed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is honesty the end of privacy?
&lt;/h2&gt;

&lt;p&gt;To gain value from gathered data the answers must be accurate, however as  &lt;a href="http://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf"&gt;Cynthia Dwork and Aaron Roth point out in "The algorithmic foundations of Differential Privacy"&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"overly accurate answers to too many questions will destroy privacy in a spectacular way"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What is the answer then? If everyone lies, all data gathered is useless, which is bad news for your you and your doctor. If you do let him know it hurts when you cough then you'll get proper treatment, but how do you know your personal data is safe? What if it helps others to share statistics your data contributes to? There is a choice to be made between never sharing your data or allowing it to be shared in a safe way with an informed choice on how much privacy risk you'll face for sharing different levels of detail.&lt;/p&gt;

&lt;p&gt;Differential Privacy offers a solution to the problem of balancing privacy and generating useful statistical output from datasets - something I'll explain in another article.&lt;/p&gt;




&lt;p&gt;The cover image of this article was provided by &lt;a href="https://unsplash.com/@clintadair?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Clint Adair&lt;/a&gt;&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>privacy</category>
      <category>dataleaks</category>
    </item>
    <item>
      <title>Face off : Three(.js)</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Mon, 23 Sep 2019 22:30:49 +0000</pubDate>
      <link>https://dev.to/mlennox/face-off-three-js-1olj</link>
      <guid>https://dev.to/mlennox/face-off-three-js-1olj</guid>
      <description>&lt;p&gt;This is a cross-post from &lt;a href="https://www.webpusher.ie/2019/09/23/face-off" rel="noopener noreferrer"&gt;https://www.webpusher.ie/2019/09/23/face-off&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been interested in &lt;a href="https://en.wikipedia.org/wiki/Photogrammetry" rel="noopener noreferrer"&gt;photogrammetry&lt;/a&gt; which involves lots of photos, but what is the least number of photos required? Well, it turns out that all you need is one photo.&lt;/p&gt;

&lt;p&gt;In this article I'll quickly run through how to generate a 3d mesh from a photograph, and then use &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;netlify&lt;/a&gt; to publish a &lt;a href="https://threejs.org/" rel="noopener noreferrer"&gt;threejs&lt;/a&gt; based model viewer to see the final result. The process is entirely manual at the moment!&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create a 3d mesh?
&lt;/h2&gt;

&lt;p&gt;After some failed experiments with mobile photogrammetry apps I decided it was too difficult to easily capture many photos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzmnj14ezaxlk64t5hx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzmnj14ezaxlk64t5hx5.png" alt="bad 3d construction of a guitar using photogrammetry" width="282" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenCV
&lt;/h3&gt;

&lt;p&gt;I then tried &lt;a href="https://docs.opencv.org/3.4/d1/d9f/classcv_1_1stereo_1_1StereoBinarySGBM.html" rel="noopener noreferrer"&gt;OpenCV Stereo SGBM&lt;/a&gt; which uses stereo photos, compares the differences and uses geometry, and some advanced techniques, to estimate a depth map, then colour it uses the original image.&lt;/p&gt;

&lt;p&gt;This was very promising when using the example photos, but despite spending a lot of time on it, I found it impossible to get even barely passable results. The image below shows headphones resting on an orange book - and that is the best angle to view it from!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvurc9ixzuf7wa6z7t2n8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvurc9ixzuf7wa6z7t2n8.png" alt="bad point cloud of Headphones and book" width="294" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is definitely something I will come back to. I didn't try it at the time, but &lt;a href="https://github.com/hitimo/opencv-disparity-map-tuner" rel="noopener noreferrer"&gt;there is a tool to help tweak the parameters&lt;/a&gt;. The other disadvantage is that building OpenCV is an arduous process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Machine Learning to the rescue!
&lt;/h3&gt;

&lt;p&gt;I used the popular PRNet CNN (convolutional neural net) to generate a wire mesh, which met with immediate success! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1rouzix8f71v0rac193.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1rouzix8f71v0rac193.png" alt="gurning face and 3d model of the same gurning face" width="628" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@hyprsense/bridging-the-academia-gap-an-implementation-of-prnet-training-9fa035c27702" rel="noopener noreferrer"&gt;There is an accessible(ish) explanation&lt;/a&gt; of how the process works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this a fake?
&lt;/h3&gt;

&lt;p&gt;More like a deep fake!&lt;/p&gt;

&lt;p&gt;PRNet is trained to generate a &lt;a href="https://en.wikipedia.org/wiki/UV_mapping" rel="noopener noreferrer"&gt;UV map&lt;/a&gt;, which encodes both volume and shape of a 3d object. Three important elements can be generated from this UV map&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sparse feature point prediction - eyebrows, eyes, nose, mouth, lips, and chin&lt;/li&gt;
&lt;li&gt;dense feature point prediction&lt;/li&gt;
&lt;li&gt;full 3-dimensional mesh model, with colors from the input image.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Show me the code!
&lt;/h3&gt;

&lt;p&gt;It's not just an academic paper &lt;a href="https://github.com/YadiraF/PRNet" rel="noopener noreferrer"&gt;there is fully working example code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It takes a little bit of work to get this running I'd recommend using my &lt;a href="https://www.webpusher.ie/2018/09/19/python-dependency-hell-no" rel="noopener noreferrer"&gt;Pyenv configuration advice from a previous article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I stuck to the requirements to get this working - Python 2.7 - so I didn't investigate if more recent versions of Python would work. If you do bump your Python version be aware that as of publishing (September 2019) dependencies of TensorFlow limit Python to version 3.6.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pyenv virtualenv 2.7.14 prnet
&lt;span class="nv"&gt;$ &lt;/span&gt;pyenv &lt;span class="nb"&gt;local &lt;/span&gt;prnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll also need to install &lt;code&gt;dlib&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; dlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'd recommend upgrading &lt;code&gt;pip&lt;/code&gt; and &lt;code&gt;setuptools&lt;/code&gt; to the latest version before you install the project dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; pip setuptools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can install the dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating the mesh
&lt;/h3&gt;

&lt;p&gt;You'll need some images saved in a known directory. Once you have that, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python demo.py &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;the directory holding images with faces&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;output directory &lt;span class="k"&gt;for &lt;/span&gt;the obj files&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll probably see lots of warnings (I did) which would likely be reduced or removed by upgrading your Python version, but I'm not doing to until later in the project!&lt;/p&gt;

&lt;p&gt;In your output folder you should see a &lt;code&gt;.obj&lt;/code&gt; file for each image you provided. Note, you will only see one face per image - there is no automatic support for multiple faces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing the output
&lt;/h2&gt;

&lt;p&gt;I used the free and capable &lt;a href="http://www.meshlab.net/" rel="noopener noreferrer"&gt;MeshLab&lt;/a&gt; to immediately open and view the models - I laughed at my stupid face spinning before me!&lt;/p&gt;

&lt;p&gt;Even though it was not a goal of my mystery side-project, I wanted to leverage my webdev skills to put this online for all to see - everyone should be laughing at my stupid spinning face!&lt;/p&gt;

&lt;h3&gt;
  
  
  Threejs and Netlify to the rescue!
&lt;/h3&gt;

&lt;p&gt;I use Netlify to publish my Gatsby based blog, so I knew it was going to do the heavy-lifting of deploying my new 3d monster gallery.&lt;/p&gt;

&lt;p&gt;I didn't want to be messing about with bundling the 'app' so I just wrote a little shell script to copy the &lt;code&gt;threejs&lt;/code&gt; library and associated support code from the &lt;code&gt;node_modules&lt;/code&gt; directory to the &lt;code&gt;src&lt;/code&gt; folder where I could import it into my es6 modules.&lt;/p&gt;

&lt;p&gt;The netlify build settings I used are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository : github.com/mlennox/three-dee-mee&lt;/li&gt;
&lt;li&gt;Base directory : Not set&lt;/li&gt;
&lt;li&gt;Build command : sh prepare.sh&lt;/li&gt;
&lt;li&gt;Publish directory : src&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://github.com/mlennox/three-dee-mee" rel="noopener noreferrer"&gt;full, working code is on github&lt;/a&gt; and the actual working demo is available at &lt;a href="https://thirsty-hypatia-f27848.netlify.com/" rel="noopener noreferrer"&gt;https://thirsty-hypatia-f27848.netlify.com/&lt;/a&gt; and looks like this (it may take a few seconds to initialise)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2fxmomrb0tj3k4p546y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2fxmomrb0tj3k4p546y.png" alt="Screengrab of model viewer demo showing 3d model and list of thumbnails to click" width="550" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just click the gurning visages in the row of thumbnails to load the associated three-d mesh, and you can control the hideous visage by clicking, dragging, and scrolling to zoom.&lt;/p&gt;

</description>
      <category>photogrammetry</category>
      <category>prnet</category>
      <category>netlify</category>
      <category>threejs</category>
    </item>
    <item>
      <title>(npm) publish, and be damned!</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Sun, 16 Jun 2019 14:00:33 +0000</pubDate>
      <link>https://dev.to/mlennox/npm-publish-and-be-damned-140o</link>
      <guid>https://dev.to/mlennox/npm-publish-and-be-damned-140o</guid>
      <description>&lt;p&gt;This article is a &lt;a href="https://www.webpusher.ie/2019/05/10/publishing-npm-package"&gt;cross-post from my personal blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently &lt;a href="https://www.webpusher.ie/2019/05/04/eslint-npm-package"&gt;published my first npm package&lt;/a&gt; and my colleague, &lt;a href="https://medium.com/@attilavago"&gt;Attila Vágó&lt;/a&gt;, suggested I write up some notes on the process. I'll point out that I am not an expert on this (I don't even play one on TV!) so you should take this with a pinch of salt.&lt;/p&gt;

&lt;p&gt;I'm going to outline why you might want to publish an npm package, then show you how easy it is, and finally, an overview of the configuration options you need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation - why would you ever publish an npm package?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;fun!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h5BKrGFR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b44n21elt1bx67ugfdwl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h5BKrGFR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b44n21elt1bx67ugfdwl.gif" alt="happy, dancing, kid typing on old computer removing sunglasses to reveal another pair "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's fun to learn!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;forking an existing package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Maybe an existing package doesn't do what you need. Maybe it has been abandoned. Maybe you need to add some new configuration and port it to es6 at the same time. Whatever the reason, you want it? you can rebuild it. &lt;em&gt;You have the technology.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;code sharing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You might want to share some code between your own projects. Publishing it as an npm package makes that easier. If you need to restrict access to your published library you can also publish your package to a private registry so that only you and your team can install it - not all the options cost money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing your package in three easy steps
&lt;/h2&gt;

&lt;p&gt;Let's jump right in!&lt;/p&gt;

&lt;p&gt;It is actually really easy to publish an npm package. I'll show you how to do that first and then show you how to properly configure your package so you publish only the files you want, and provide a good description of how to install and use your package.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Login to your npm account from the terminal
&lt;/h3&gt;

&lt;p&gt;You'll need to have an account, so if you don't have one, visit &lt;a href="https://www.npmjs.com/signup"&gt;https://www.npmjs.com/signup&lt;/a&gt; and create one.&lt;/p&gt;

&lt;p&gt;On the terminal logging in is straightforward&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm login
&lt;span class="c"&gt;# prompts you for your email and password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You only need to login once after starting / restarting your terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Increment the version of your package
&lt;/h3&gt;

&lt;p&gt;Unless this is the first time you've published, you'll have to increment the version of the package or npm will reject it as it expects an updated version every time you publish.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt; &lt;span class="c1"&gt;// increment to 1.0.1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Publish!
&lt;/h3&gt;

&lt;p&gt;The command below will publish your package&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm publish

&lt;span class="c"&gt;# npm notice &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 📦  my-colourful-sorter@1.0.1&lt;/span&gt;
&lt;span class="c"&gt;# npm notice === Tarball Contents === &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 1.5kB package.json       &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 1.1kB LICENSE            &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 2.0kB README.md          &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 1.5kB src/sort.js       &lt;/span&gt;
&lt;span class="c"&gt;# npm notice 865B  src/fuzzy.js&lt;/span&gt;
&lt;span class="c"&gt;# npm notice === Tarball Details === &lt;/span&gt;
&lt;span class="c"&gt;# npm notice name:          my-colourful-sorter                     &lt;/span&gt;
&lt;span class="c"&gt;# npm notice version:       1.0.1                                   &lt;/span&gt;
&lt;span class="c"&gt;# npm notice package size:  3.1 kB                                  &lt;/span&gt;
&lt;span class="c"&gt;# npm notice unpacked size: 6.9 kB                                  &lt;/span&gt;
&lt;span class="c"&gt;# npm notice shasum:        d2ffe8d1c9f8f284319efca30e610edee091d993&lt;/span&gt;
&lt;span class="c"&gt;# npm notice integrity:     sha512-zbG1FeJIr3Ec1[...]EZaLTYm8TKaEg==&lt;/span&gt;
&lt;span class="c"&gt;# npm notice total files:   5                                       &lt;/span&gt;
&lt;span class="c"&gt;# npm notice &lt;/span&gt;
&lt;span class="c"&gt;# + my-colourful-sorter@1.0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Congratulations! I told you it would be easy.&lt;/p&gt;

&lt;p&gt;Now for the slightly hard stuff - configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration - package.json
&lt;/h2&gt;

&lt;p&gt;This is where the magic happens. The &lt;code&gt;package.json&lt;/code&gt; file contains all the details npm needs to properly package and publish your library to npm, and then install to the developer's project when they choose to use it.&lt;/p&gt;

&lt;p&gt;Apart from your dependencies, the top three properties of the package.json file you really need for publishing are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;files&lt;/li&gt;
&lt;li&gt;name&lt;/li&gt;
&lt;li&gt;version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are further properties that are optional but usually required for anything more than a simple package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;keywords&lt;/li&gt;
&lt;li&gt;main / browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, there are some less important fields that are also useful - I won't be covering them here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;engine&lt;/li&gt;
&lt;li&gt;homepage&lt;/li&gt;
&lt;li&gt;bugs&lt;/li&gt;
&lt;li&gt;licence&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration - three is the magic number
&lt;/h3&gt;

&lt;h4&gt;
  
  
  files
&lt;/h4&gt;

&lt;p&gt;This is optional, but I consider it &lt;em&gt;the&lt;/em&gt; most important field in package.json, which is why I am putting it first in this list. As it suggests, this property determines what files will be included in your npm package. You will see a lot of suggestions to use &lt;code&gt;.npmignore&lt;/code&gt; to blacklist whatever files you do &lt;em&gt;not&lt;/em&gt; want included in the package - you probably shouldn't use it at all. Anyway, using the &lt;code&gt;files&lt;/code&gt; field &lt;a href="https://blog.npmjs.org/post/165769683050/publishing-what-you-mean-to-publish"&gt;is recommended by npm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;files&lt;/code&gt; field allows you to &lt;em&gt;whitelist&lt;/em&gt; files by directly referencing them or using &lt;a href="https://commandbox.ortusbooks.com/usage/parameters/globbing-patterns"&gt;globbing patterns&lt;/a&gt;. These will override what is in your &lt;code&gt;.gitignore&lt;/code&gt; and &lt;code&gt;.npmignore&lt;/code&gt; file. As an example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"src/**/*.js"&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;Will include all the js files in the root and sub-directories of the &lt;code&gt;src&lt;/code&gt; directory. The &lt;code&gt;**&lt;/code&gt; pattern matches any subdirectory paths.&lt;/p&gt;

&lt;p&gt;The patterns are not just a whitelist, you can exclude files too, making the &lt;code&gt;files&lt;/code&gt; field very powerful. As an example, I like to have my unit tests in the same folder as my source files and these can be excluded using:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"src/**/*.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"!src/**/*.test.js"&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;Regardless of what you have in the &lt;code&gt;files&lt;/code&gt; field, these files are always included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package.json&lt;/li&gt;
&lt;li&gt;README&lt;/li&gt;
&lt;li&gt;CHANGES / CHANGELOG / HISTORY&lt;/li&gt;
&lt;li&gt;LICENSE / LICENCE&lt;/li&gt;
&lt;li&gt;NOTICE&lt;/li&gt;
&lt;li&gt;The file you specify in &lt;code&gt;main&lt;/code&gt; field (see below)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  name
&lt;/h4&gt;

&lt;p&gt;This is the package name, and also what will be used to &lt;code&gt;import&lt;/code&gt; your package into a module, so best to keep it short and memorable. It also needs to be unique, but you should search on &lt;a href="https://npmjs.com"&gt;https://npmjs.com&lt;/a&gt; to check your package name has not already been taken.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2GJi4_NM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/nhty4eadv1mgfzfq4npj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2GJi4_NM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/nhty4eadv1mgfzfq4npj.png" alt="search to check the name my-super-duper-library has not been used"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can have a shorter package name if you &lt;em&gt;scope&lt;/em&gt; your package name with your own npm username. If you want to call your npm package &lt;code&gt;colors&lt;/code&gt; - a package that already exists - you can, if you use a scoped package name.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;paddingtonbear&lt;/span&gt;&lt;span class="sr"&gt;/color&lt;/span&gt;&lt;span class="err"&gt;s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Installing this in a project would be just as simple.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @paddingtonbear/colors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  version
&lt;/h4&gt;

&lt;p&gt;This is &lt;a href="https://semver.org/"&gt;semver&lt;/a&gt; compliant. Keep it simple, start at &lt;code&gt;1.0.0&lt;/code&gt;. Every time you publish your package to npm you will need to increment the version - you can use the handy &lt;code&gt;npm version&lt;/code&gt; command for this. If in doubt, increment the &lt;code&gt;patch&lt;/code&gt; number each time you publish.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm version patch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will increment your version &lt;code&gt;1.0.0&lt;/code&gt; package to version &lt;code&gt;1.0.1&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1.0.1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are npm libraries that help you publish to npm - &lt;a href="https://github.com/sindresorhus/np"&gt;the excellent np, for instance&lt;/a&gt; - but I won't be covering them here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional configuration
&lt;/h3&gt;

&lt;h4&gt;
  
  
  description
&lt;/h4&gt;

&lt;p&gt;Your package's &lt;a href="https://www.dictionary.com/browse/elevator-pitch"&gt;elevator pitch&lt;/a&gt;. Keep it short and to the point, this is what appears in the search results on npmjs.com.&lt;/p&gt;

&lt;p&gt;The description should tell you exactly what problem the package solves.&lt;/p&gt;

&lt;p&gt;This is a bad example.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A super-duper npm package I enjoyed writing and hope you will enjoy using it to sort colourful and other types of lists&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ah, now this is just what I need for my wallpaper database project!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Configurable list sorter that allows sorting by colour&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  keywords
&lt;/h4&gt;

&lt;p&gt;Any keywords you provide will be used to improve search results. Try and include useful keywords - node and nodejs won't help, for instance. In our hypothetical example these might be a good choice&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"sort"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"rainbow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"color-blind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"protanomaly"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"deuteranomaly"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"tritanomaly"&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;h4&gt;
  
  
  main / browser
&lt;/h4&gt;

&lt;p&gt;When your npm package is imported into a module the &lt;code&gt;main&lt;/code&gt; field defines what is returned.&lt;/p&gt;

&lt;p&gt;For instance, if you define &lt;code&gt;main&lt;/code&gt; as follows&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// package.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my-colourful-sorter"&lt;/span&gt;
  &lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"src/sort.js"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Where the &lt;code&gt;src/sort.js&lt;/code&gt; file in your npm package is&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/sort.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;doIt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* magic happens */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you install your package in a project and import it into a module in that project, the import will be the &lt;code&gt;doIt&lt;/code&gt; method from the &lt;code&gt;src/sort.js&lt;/code&gt; file:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// wallpapers/index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;colourfulSorter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'colourful-sorter'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;colourfulSorter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// this will execute the `doIt` function in your src/sort.js file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;browser&lt;/code&gt; property is essentially the same as &lt;code&gt;main&lt;/code&gt; but intended for libraries that will be used in the UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  README
&lt;/h2&gt;

&lt;p&gt;Your &lt;code&gt;readme&lt;/code&gt; file is an essential part of your npm package. It's what helps a developer decide if your package is worth installing. At the very least it should describe what your package does, how to install it, and how to use it. Also, it's optional, but common to include badges highlighting the status of your CI pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  description
&lt;/h3&gt;

&lt;p&gt;You can't go wrong by including the name, and quoting the description from your package.json. Add a short paragraph expanding on the description and you're done.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Configurable list sorter that allows sorting by colour.

This sorter allows sorting colour names based on the hue 
of the colour they represent. It can be configured to sort 
in reverse order and can sort based on hues as affected 
by colour-blindness - protanomaly, deuteranomaly, or tritanomaly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  installation and requirements
&lt;/h3&gt;

&lt;p&gt;Developers need to know if a certain version of nodejs is required, and whether the package is best used as a production or development dependency.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;Requires Node 8 or higher. 

npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @paddingtonbear/colors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  How to use
&lt;/h3&gt;

&lt;p&gt;You should give some working examples to highlight how to configure and use your npm package.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;colorsort&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s2"&gt;`@paddingtonbear/colors`&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;colorList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'mango'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'chartreuse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'vermillion'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'cyan'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'lavender'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// ['vermillion', 'mango', 'chartreuse', 'cyan', 'lavender']&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;colorsort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colorList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;colorsort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reverse&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;p&gt;The usage section should highlight some different ways of using your npm package, and even if you only have a small number of options you should still include an API section to explain them. An incomplete example is shown below.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;colorsort(array, [options])
Returns an array of colours sorted in rainbow order.

options
Should be provided as an object literal. The properties and 
values are listed below

order
Can be `colorsort.normal` or `colorsort.reverse`

etc.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Author
&lt;/h3&gt;

&lt;p&gt;You should probably provide your name, non-private email, twitter, linkedin, blog, etc.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Author
Michelin Mann &amp;lt;mich@tires.fr&amp;gt;
- [@tirechap](https://twitter.com/tirechap)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Licence
&lt;/h3&gt;

&lt;p&gt;Finally, you should list the licence you applied to your repo - the MIT licence is a good choice if you are not sure what to use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How?&lt;/strong&gt;&lt;br&gt;
Github allows you to add a licence to your repo when you create it. This will add a &lt;code&gt;LICENCE&lt;/code&gt; file to your repo that includes the standard MIT licence text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://help.github.com/en/articles/licensing-a-repository"&gt;Github has more information about choosing and applying a licence&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  README template
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://gist.githubusercontent.com/mlennox/820fe27b04fca6f1adbd8f9bb4517e3e/raw/478126e0dfe541d638c9293eaa3bbc49b6ba601d/readme.md"&gt;I've provided a template README.md file&lt;/a&gt; that you can download and use in your own projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>es6</category>
      <category>npm</category>
    </item>
    <item>
      <title>My first npm package - eslint-formatter-complexity</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Mon, 06 May 2019 15:56:14 +0000</pubDate>
      <link>https://dev.to/mlennox/my-first-npm-package-eslint-formatter-complexity-4m3i</link>
      <guid>https://dev.to/mlennox/my-first-npm-package-eslint-formatter-complexity-4m3i</guid>
      <description>&lt;p&gt;Note: this is a cross-post from my personal blog &lt;a href="https://www.webpusher.ie/2019/05/04/eslint-npm-package" rel="noopener noreferrer"&gt;https://www.webpusher.ie/2019/05/04/eslint-npm-package&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've just published my first npm package - &lt;a href="https://www.npmjs.com/package/eslint-formatter-complexity" rel="noopener noreferrer"&gt;eslint-formatter-complexity&lt;/a&gt;. It's an eslint formatter that uses complexity metrics (see below) to highlight the files in your codebase that are in most need of a refactor.&lt;/p&gt;

&lt;p&gt;The code is available in a public repo &lt;a href="https://github.com/mlennox/eslint-formatter-complexity" rel="noopener noreferrer"&gt;https://github.com/mlennox/eslint-formatter-complexity&lt;/a&gt; - issues and pull requests are welcome.&lt;/p&gt;

&lt;p&gt;This is a continuation of work from &lt;a href="https://www.webpusher.ie/2019/02/01/eslint-complexity" rel="noopener noreferrer"&gt;a previous article 'Find the most complex code using eslint'&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;The formatter receives the eslint results, finds the complexity metric related rules that have been broken (see below), sorts the offending files in order according to how many errors and/or warnings were generated, and outputs the list to the console. This differs greatly from the standard eslint output which just lists the files and their broken rules as they are passed to it based on file structure.&lt;/p&gt;

&lt;p&gt;A typical output from the formatter is shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayfjx8clp16usqmargx1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayfjx8clp16usqmargx1.png" width="800" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complexity metrics I refer to are measured by the following eslint rules&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/complexity" rel="noopener noreferrer"&gt;complexity (cyclomatic complexity)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-params" rel="noopener noreferrer"&gt;max-params&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-statements" rel="noopener noreferrer"&gt;max-statements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-statements-per-line" rel="noopener noreferrer"&gt;max-statements-per-line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-nested-callbacks" rel="noopener noreferrer"&gt;max-nested-callbacks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-depth" rel="noopener noreferrer"&gt;max-depth&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eslint.org/docs/rules/max-lines" rel="noopener noreferrer"&gt;max-lines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;For fun! &lt;/p&gt;

&lt;p&gt;Also, I'm working on a &lt;a href="https://www.webpusher.ie/2019/02/06/ast-series" rel="noopener noreferrer"&gt;series of blog posts related to abstract syntax trees&lt;/a&gt; and &lt;a href="https://www.webpusher.ie/tags/eslint" rel="noopener noreferrer"&gt;a few articles about eslint&lt;/a&gt; so I have been aiming to properly write up the code and release it as I go along.&lt;/p&gt;

&lt;p&gt;I have a theory that code standards work best when automated; not really a controversial theory it has to be said. &lt;/p&gt;

&lt;p&gt;Automated enforcement of code standards helps create consistent code, speeds up code reviews, helps reduce errors, and should also facilitate developers in maintaining a mental model of the state of their codebase. I released the &lt;a href="https://www.npmjs.com/package/eslint-formatter-complexity" rel="noopener noreferrer"&gt;eslint-formatter-complexity&lt;/a&gt; package primarily for the last point - to help developers visualise the complexity of their codebase. &lt;/p&gt;

&lt;p&gt;Listing the files in descending order of complexity helps to emphasise which files are in need of a refactor. Ideally it should be added as a step in your CI build, with the results of each build added to quality gates and communicated to the entire team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues
&lt;/h2&gt;

&lt;p&gt;If you have any questions, suggestions for enhancements, or if you find any bugs, please raise them on the repo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mlennox/eslint-formatter-complexity/issues" rel="noopener noreferrer"&gt;https://github.com/mlennox/eslint-formatter-complexity/issues&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>eslint</category>
    </item>
    <item>
      <title>AST selectors rule</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Tue, 30 Apr 2019 21:30:07 +0000</pubDate>
      <link>https://dev.to/mlennox/ast-selectors-rule-286i</link>
      <guid>https://dev.to/mlennox/ast-selectors-rule-286i</guid>
      <description>&lt;p&gt;My &lt;a href="https://www.webpusher.ie/2019/02/07/ast-fun-and-profit/" rel="noopener noreferrer"&gt;previous article on abstract syntax trees&lt;/a&gt; ran through a quick, but relatively broad, overview of syntax trees and how to manipulate them.&lt;/p&gt;

&lt;p&gt;This second article will show you how to use a basic knowledge of abstract syntax trees to enforce code standards by adding simple ESlint rules implemented only using AST selectors, requiring &lt;em&gt;no javascript!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule - 'no-restricted-syntax'
&lt;/h2&gt;

&lt;p&gt;Eslint provides a &lt;code&gt;no-restricted-syntax&lt;/code&gt; rule that allows you add simple rules using AST selectors - which are very similar to CSS selectors.&lt;/p&gt;

&lt;p&gt;I'll run through a couple of examples in this article&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enforce const over var&lt;/li&gt;
&lt;li&gt;ensure &lt;code&gt;FormattedMessage&lt;/code&gt; never renders a &lt;code&gt;span&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples provided here can be found in the &lt;code&gt;AST Selectors&lt;/code&gt; folder in the accompanying github repo &lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit" rel="noopener noreferrer"&gt;https://github.com/mlennox/abstractsyntaxforfunandprofit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AST selectors are &lt;a href="https://github.com/estools/esquery" rel="noopener noreferrer"&gt;implemented using esquery&lt;/a&gt;. Also, the &lt;a href="https://eslint.org/docs/developer-guide/selectors" rel="noopener noreferrer"&gt;eslint documentation on selectors&lt;/a&gt; is indispensable as a reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; Const not var
&lt;/h2&gt;

&lt;p&gt;I'll use an example from a previous article - enforce the use of &lt;code&gt;const&lt;/code&gt; instead of &lt;code&gt;var&lt;/code&gt;. There is already an &lt;a href="https://eslint.org/docs/rules/no-var#require-let-or-const-instead-of-var-no-var" rel="noopener noreferrer"&gt;excellent 'no-var' rule&lt;/a&gt; built-in to eslint. This is implemented as an eslint plugin, which requires some effort to write!&lt;/p&gt;

&lt;p&gt;However, we can reproduce most of the functionality of the &lt;code&gt;no-var&lt;/code&gt; plugin using only AST selectors. As I've already mentioned, AST selectors are based on CSS selectors and won't be a challenge if you have worked with CSS before. I'll explain the construction of the rule in a way that is accessible to those with no knowledge of CSS selectors.&lt;/p&gt;

&lt;p&gt;Using the very simple variable declaration below to test against, we'll write an AST selector that will enforce the 'no var' rule in our IDE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;willIt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start, we'll need to remind ourselves of the structure of the AST for a simple &lt;code&gt;var&lt;/code&gt; variable declaration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qdq3u04k7ko17meetr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qdq3u04k7ko17meetr4.png" alt="abstract syntax tree of variable declaration showing attribute kind is var"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, lets try and state the problem in english&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;highlight, as an error, any &lt;code&gt;VariableDeclaration&lt;/code&gt; of kind &lt;code&gt;var&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the selector
&lt;/h3&gt;

&lt;p&gt;Firstly, we need to know how to select our variable declaration. Remember, the node type for our variable declaration is simply &lt;code&gt;VariableDeclaration&lt;/code&gt;. The AST selector we use is a node type selector - which is simply the type of the node, like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;VariableDeclaration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, as we are selecting against &lt;em&gt;all&lt;/em&gt; the nodes in the abstract syntax tree for every file in your codebase, we need to refine our selection to only those of kind &lt;code&gt;var&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;kind&lt;/code&gt; we refer to is an attribute of the &lt;code&gt;VariableDeclaration&lt;/code&gt; node.&lt;/p&gt;

&lt;p&gt;We can select all nodes that have a &lt;code&gt;kind&lt;/code&gt; attribute using the following selector&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to select any &lt;code&gt;kind&lt;/code&gt; attribute that has the value &lt;code&gt;var&lt;/code&gt; we expand the selector like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;var&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a selector that will select &lt;em&gt;all&lt;/em&gt; &lt;code&gt;kind&lt;/code&gt; attributes with the value &lt;code&gt;var&lt;/code&gt;, but we only want to select &lt;code&gt;VariableDeclaration&lt;/code&gt; nodes that have that attribute and value, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;var&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is our final selector, but how do we add that to our list of eslint rules?&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the rule
&lt;/h3&gt;

&lt;p&gt;To apply the rule to our codebase we add the example &lt;code&gt;no-restricted-syntax&lt;/code&gt; rule to the &lt;code&gt;rules&lt;/code&gt; section of the &lt;code&gt;.eslintrc.js&lt;/code&gt; config file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-restricted-syntax&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration[kind='var']&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces the following error in VS Code&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjyplznufoyek99eibe6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjyplznufoyek99eibe6.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think you'll agree that &lt;code&gt;Using 'VariableDeclaration[kind='var'] is not allowed&lt;/code&gt; is a &lt;em&gt;&lt;strong&gt;really&lt;/strong&gt;&lt;/em&gt; bad error message. &lt;/p&gt;

&lt;h3&gt;
  
  
  Custom error message
&lt;/h3&gt;

&lt;p&gt;Eslint supports a custom message for rule violations, so let's add that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-restricted-syntax&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration[kind='var']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;All variables must be declared as 'const', do not use 'var'&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;This looks a lot better &lt;em&gt;and&lt;/em&gt; the added structure to the configuration has the bonus of easier maintenance of your custom eslint rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9b847zbdlp3drkxv2tw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9b847zbdlp3drkxv2tw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What about a more complex example?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt; React JSX internationalisation - FormattedMessage
&lt;/h2&gt;

&lt;p&gt;If you use &lt;code&gt;react-intl&lt;/code&gt; you will be familiar with the &lt;a href="https://github.com/yahoo/react-intl/wiki/Components#formattedmessage" rel="noopener noreferrer"&gt;FormattedMessage&lt;/a&gt; component that facilitates localised messages in your app.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;FormattedMessage&lt;/code&gt; component wraps the message in a &lt;code&gt;span&lt;/code&gt; by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormattedMessage&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`someMessageId`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="c1"&gt;// results in : &amp;lt;span&amp;gt;some message text&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can avoid the &lt;code&gt;span&lt;/code&gt; by using this construction instead&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormattedMessage&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`someMessageId`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/FormattedMessage&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="c1"&gt;// results in : some message text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't like it when spurious HTML is added to my layout, so let's write an eslint rule to ensure it doesn't happen. As before we'll state our problem goal in plain english&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;highlight, as an error, any FormattedMessage that does not contain child elements&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We make a very reasonable assumption here that &lt;em&gt;any&lt;/em&gt; children will use the general approach that we require, for example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormattedMessage&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`someMessageId`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;labelText&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyComponent&lt;/span&gt;
      &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;labelText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/FormattedMessage&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FormattedMessage&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`anotherMessageId`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messageText&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;renderSomeStuff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageText&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/FormattedMessage&lt;/span&gt;&lt;span class="err"&gt;&amp;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;This saves us from having to consider the types and format of the child components.&lt;/p&gt;

&lt;h3&gt;
  
  
  AST explorer + JSX = problem
&lt;/h3&gt;

&lt;p&gt;The ever useful &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;AST explorer&lt;/a&gt; does not handle &lt;code&gt;JSX&lt;/code&gt; so we'll need to use a different approach to visualise the abstract syntax tree.&lt;/p&gt;

&lt;h4&gt;
  
  
  Babel parser with jsx plugin
&lt;/h4&gt;

&lt;p&gt;The helper file &lt;code&gt;showTree.js&lt;/code&gt; is included in the &lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit/tree/master/ASTselectors/FormattedMessage" rel="noopener noreferrer"&gt;github repo&lt;/a&gt; but you cannot run this helper function from the repo root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;ASTselectors/FormattedMessage
node showTree.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will turn the stateless react component in the file &lt;code&gt;basicReact.js&lt;/code&gt; into a JSON abstract syntax tree. We can use this to try and visualise how we might build a selector that selects only the &lt;code&gt;FormattedMessage&lt;/code&gt; nodes that have no &lt;code&gt;{text =&amp;gt; text}&lt;/code&gt; child function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visualising the tree structure
&lt;/h3&gt;

&lt;p&gt;The simplified abstract syntax tree for the second &lt;code&gt;FormattedMessage&lt;/code&gt; in the file &lt;code&gt;basicReact.js&lt;/code&gt; is shown below. &lt;/p&gt;

&lt;p&gt;Note that the structure is relatively complex - a generic &lt;code&gt;JSXElement&lt;/code&gt; as a parent container with the attributes &lt;code&gt;openingElement&lt;/code&gt; and &lt;code&gt;closingElement&lt;/code&gt; containing instances of the &lt;code&gt;FormattedMessage&lt;/code&gt; tags themselves and the children of the &lt;code&gt;JSXElement&lt;/code&gt; are a &lt;code&gt;JSXEXpressionContainer&lt;/code&gt; containing the anonymous arrow function AST for &lt;code&gt;{text =&amp;gt; text}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openingElement&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attributes&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="cm"&gt;/* not important to us */&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selfClosing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;closingElement&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXClosingElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FormattedMessage&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;children&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXExpressionContainer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;expression&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ArrowFunctionExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;params&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}],&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&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;p&gt;As usual a graphic representation of the simplified abstract syntax tree shows the hierarchy much more clearly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh095c2vha5mlnh6lj0ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh095c2vha5mlnh6lj0ce.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We won't be using the correctly structured &lt;code&gt;FormattedMessage&lt;/code&gt; AST as a reference when building our selector, I supply this to as a reference to ensure we don't construct a selector that will &lt;em&gt;also&lt;/em&gt; select a properly constructed &lt;code&gt;FormattedMessage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now Lets compare that to the self-closing &lt;code&gt;FormattedMessage&lt;/code&gt;. A simplified version of the JSON AST is shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openingElement&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attributes&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="cm"&gt;/* not important to us... */&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selfClosing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;closingElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;children&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;h4&gt;
  
  
  Constructing the selector - approach 1 : JSXElement has no child elements
&lt;/h4&gt;

&lt;p&gt;Referring to the JSON AST, we can see the parent &lt;code&gt;JSXElement&lt;/code&gt; has no child elements we can select on that basis&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;children&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;The selector is simple enough, we want to select the &lt;code&gt;JSXElement&lt;/code&gt; where the &lt;code&gt;children&lt;/code&gt; attribute is empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its important to note here that the &lt;code&gt;children&lt;/code&gt; attribute is slightly confusing as the children it refers to are the children of the &lt;code&gt;openingElement&lt;/code&gt; / &lt;code&gt;closingElement&lt;/code&gt;. In regard to the AST selectors, the &lt;code&gt;openingElement&lt;/code&gt; and &lt;code&gt;closingElement&lt;/code&gt; themselves are the direct descendants (yes, children - hence the confusion) of the parent &lt;code&gt;JSXElement&lt;/code&gt;. So armed with this information we know we can use descendant selectors to select the &lt;code&gt;JSXOpeningElement&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;JSXOpeningElement&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is still too specific. We are still selecting many elements, we only want to select &lt;code&gt;FormattedMessage&lt;/code&gt; elements inside a &lt;code&gt;JSXElement&lt;/code&gt; that has an empty &lt;code&gt;children&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Once again, some explanation is required. As far as AST selectors are concerned, the direct descendants of the &lt;code&gt;JSXOpeningElement&lt;/code&gt; in the abstract syntax tree are not the components referred to in the &lt;code&gt;children&lt;/code&gt; attribute of the parent &lt;code&gt;JSXElement&lt;/code&gt; but the &lt;code&gt;JSXIdentifier&lt;/code&gt; referred to in the &lt;code&gt;name&lt;/code&gt; attribute of the &lt;code&gt;JSXOpeningElement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Because the &lt;code&gt;name&lt;/code&gt; attribute of the &lt;code&gt;JSXOpeningElement&lt;/code&gt; is not a simple string it is not possible to use the attribute selector, as they only allow simple matching rules. For instance, the example below, or similar variations, would not work&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// bad! does not work!&lt;/span&gt;
&lt;span class="nx"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JSXIdentifier.name=FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As far as the AST selectors are concerned, the name attribute element is a descendant element and can be selected using a descendant selector paired with an attribute selector that matches the all important string &lt;code&gt;FormattedMessage&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;JSXOpeningElement&lt;/span&gt; &lt;span class="nx"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will select the self-closing &lt;code&gt;FormattedString&lt;/code&gt; components in the codebase and will ignore those that wrap components. Success!&lt;/p&gt;

&lt;p&gt;But wait, there's more - this can be simpler.&lt;/p&gt;

&lt;p&gt;The selector does not gain any specificity from using the &lt;code&gt;JSXOpeningElement&lt;/code&gt;. We already know that the parent &lt;code&gt;JSXElement&lt;/code&gt; indicates there are no child components, so we don't need to worry that our selector is going to select the &lt;code&gt;JSXClosingElement&lt;/code&gt; as it is not there. We can simplify the selector by removing the reference to &lt;code&gt;JSXOpeningElement&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And our final rule, in place in the eslint config&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXElement[children=''] JSXIdentifier[name='FormattedMessage']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please use {text =&amp;gt; text} function as child of FormattedMessage to avoid spurious span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Constructing the selector - approach 2 : JSXOpeningElement is self-closing
&lt;/h4&gt;

&lt;p&gt;There is a different approach we can take that only selects against the opening element itself without requiring reference to the parent &lt;code&gt;JSXElement&lt;/code&gt; with an empty &lt;code&gt;children&lt;/code&gt; attribute. Look at the JSON AST of the &lt;code&gt;JSXOpeningElement&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;attributes&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="cm"&gt;/* not important to us */&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selfClosing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important property here is &lt;code&gt;selfClosing&lt;/code&gt; if it is &lt;code&gt;true&lt;/code&gt;, as it is here, it means there is no closing tag and therefore no child components.&lt;/p&gt;

&lt;p&gt;Instead of selecting the parent &lt;code&gt;JSXElement&lt;/code&gt; we can now directly select the &lt;code&gt;JSXOpeningElement&lt;/code&gt; that is self-closing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selfClosing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we already know how to filter our selected components to a &lt;code&gt;FormattedMessage&lt;/code&gt; by using a descendant selector combined with an attribute selector.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;JSXOpeningElement&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selfClosing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;JSXIdentifier&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FormattedMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final eslint config would be&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selector&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;JSXOpeningElement[selfClosing=true] JSXIdentifier[name='FormattedMessage']&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please use {text =&amp;gt; text} function as child of FormattedMessage to avoid spurious span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;AST selectors can be very useful in providing a simple way of adding a new ESlint rule, and they also leverage any existing CSS selector knowledge you may have. However, they suffer the same limitations as CSS selectors and quickly become cumbersome for what should be relatively simple selections. The selection of a node based on the contents of the attributes of the children of a sibling node is common, but not simple to achieve using AST selectors; while there is an adjacent and descendant selector there is no &lt;em&gt;previous&lt;/em&gt; selector.&lt;/p&gt;

&lt;p&gt;The next post in this series will look at writing &lt;em&gt;"proper"&lt;/em&gt; ESlint plugins that are much more flexible, and useful.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>eslint</category>
      <category>abstractsyntaxtrees</category>
    </item>
    <item>
      <title>I, for one, welcome our eslint overlords</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Sun, 21 Apr 2019 16:48:22 +0000</pubDate>
      <link>https://dev.to/mlennox/i-for-one-welcome-our-eslint-overlords-2ckp</link>
      <guid>https://dev.to/mlennox/i-for-one-welcome-our-eslint-overlords-2ckp</guid>
      <description>

&lt;p&gt;Functioning teams usually agree to code standards intended to make life easier for everyone. Unfortunately, we constantly flout those agreed rules - to our detriment. Not only does this lead to less manageable code, it can also lead to friction and discord within your team.&lt;/p&gt;

&lt;p&gt;I think &lt;a href="https://en.wikipedia.org/wiki/Alexander_Pope"&gt;Alexander Pope&lt;/a&gt; put it best&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ah ne'er so dire a Thirst of Glory boast,&lt;br&gt;
Nor in the Critick let the Man be lost!&lt;br&gt;
Good-Nature and Good-Sense must ever join;&lt;br&gt;
To err is Humane; to Forgive, Divine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ideally, we'd like to offload the contentious aspects of code review to an objective third-party that knows and understands our agreed rules. If we can rely on trusted code to critique code we write then we can all hate that code instead of each other.&lt;/p&gt;

&lt;p&gt;Fundamentally, using code to check our code is faster and (usually) free from errors or bias. This is why we use linting tools, driven by the rules we agree on pre-defined metrics such as line-length, cyclomatic complexity, nested callbacks and others I've mentioned in &lt;a href="https://www.webpusher.ie/2019/02/01/eslint-complexity/"&gt;an article on finding the most complex files using eslint&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Underline it with a rule
&lt;/h2&gt;

&lt;p&gt;There are already lots and lots of existing rules &lt;a href="https://eslint.org/docs/rules/#best-practices"&gt;https://eslint.org/docs/rules/#best-practices&lt;/a&gt; that you should be using right now. If you use eslint you probably already use a number of these rules either commonly by using &lt;code&gt;eslint:recommended&lt;/code&gt; or &lt;code&gt;airbnb&lt;/code&gt;. Most teams should add their own rules or &lt;a href="https://www.webpusher.ie/2019/04/18/eslint-override"&gt;use &lt;code&gt;overrides&lt;/code&gt;&lt;/a&gt; to change or remove airbnb/recommended rules they don't agree with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7WSSoxwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6u8ha59dnjhqa9w9stv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7WSSoxwT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6u8ha59dnjhqa9w9stv9.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A good approach to use when first introducing eslint rules is to regularly discuss their current use and how well they support your code standards; are the parameters properly tuned (what level of cyclomatic complexity &lt;em&gt;should&lt;/em&gt; you find acceptable? only your team will know...), should they be warnings or errors, and which new rules should be introduced, and which are getting in the way and should be removed. Eventually, it will be a rare event for you to revisit your eslint config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't break the rules - make your own
&lt;/h2&gt;

&lt;p&gt;It is likely that you'll have situations where the standard eslint rules are insufficient. What I'm suggesting here is a small step beyond using pre-defined rules - you can write your own eslint plugins to &lt;strong&gt;&lt;em&gt;enforce your own code standards&lt;/em&gt;&lt;/strong&gt;. There are two main approaches to writing your own eslint rules - both of which I will cover in &lt;a href="https://www.webpusher.ie/2019/02/06/ast-series"&gt;future articles in the series on abstract syntax trees&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AST selectors&lt;/li&gt;
&lt;li&gt;writing a &lt;code&gt;proper&lt;/code&gt; eslint rule&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rules are agreed to as a team and built as a team
&lt;/h2&gt;

&lt;p&gt;Everyone needs to be involved in deciding which rules to use as well as implementing and maintaining the configuration of existing rules. Happy, functioning teams are built on solid communication and a large dose of cross-functional capability - the latter would be important in successfully employing this approach. Practically, it would quickly become a bottleneck if only a small number of developers know how to write the eslint rules, they won't get updated as frequently and they can quickly become a hinderance resulting in them being removed from the codebase.&lt;/p&gt;

&lt;p&gt;Also, more to the point, if a small number of people are responsible for writing the linting rules they will be blamed rather than the code -  however irrational that might be!&lt;/p&gt;

&lt;h3&gt;
  
  
  Can code snippets be used to enforce standards?
&lt;/h3&gt;

&lt;p&gt;Yes, but no.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S0OqoVXz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yt6aqgw1vivy288uzrol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S0OqoVXz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yt6aqgw1vivy288uzrol.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code snippets are great, but there are a number of drawbacks. The main stumbling block, in my opinion, is &lt;a href="https://uxdesign.cc/affordance-in-user-interface-design-3b4b0b361143"&gt;affordance&lt;/a&gt;; developers need to know the snippets are there, and they need to know how to use the snippet. &lt;/p&gt;

&lt;p&gt;Also, this is compounded by the fact that many teams do not enforce use of a single IDE. For instance, my team uses a mix of Webstorm, VS Code, and Sublime. The overhead in adding, maintaining and documenting code snippets for each of those editors is just more friction to the adoption of code snippets.&lt;/p&gt;

&lt;p&gt;As much as possible, code standards checking should be automated, the point being to strengthen the weakest link in the chain: the developer. Relying on a developer to pick a code snippet when writing code, or notice that a snippet should have been used when reviewing code does not address the issue that snippets are meant to fix.&lt;/p&gt;

&lt;p&gt;Not that snippets are not useful - use them if you like them, I do, but don't expect other developers to do the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know your place
&lt;/h2&gt;

&lt;p&gt;In short, to make your life easier, shorten your code reviews (a bit), and promote harmony and good-will within your team (well, probably), let the rules bind you and bend the knee to the eslint overlords!&lt;/p&gt;


</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>eslint</category>
    </item>
    <item>
      <title>Riding rough-shod over your eslint rules</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Sun, 21 Apr 2019 16:43:45 +0000</pubDate>
      <link>https://dev.to/mlennox/riding-rough-shod-over-your-eslint-rules-1c3p</link>
      <guid>https://dev.to/mlennox/riding-rough-shod-over-your-eslint-rules-1c3p</guid>
      <description>

&lt;p&gt;In HMH we have adopted fairly strict eslint rules regarding code complexity. &lt;a href="https://www.webpusher.ie/2019/02/01/eslint-complexity"&gt;I've written about eslint complexity metrics before&lt;/a&gt;, and will no doubt do so again! The rules work well for our code, but do tend to get in the way when we are writing tests. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tests need code standards too!
&lt;/h2&gt;

&lt;p&gt;I'm not saying you should abandon all pretense to code standards for unit test code, but by their nature tests are often larger, more verbose, and complex than the code they are targeting. We've adopted a few approaches to try and keep the tests flexible and maintainable by breaking them into multiple files, adding a dash of &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID principles&lt;/a&gt; and generally using our common sense.&lt;/p&gt;

&lt;p&gt;Even with all that, our test files are a mess of squiggly green lines telling us we have failed to write cromulent code. If only we could relax the rules for our test code!&lt;/p&gt;

&lt;h2&gt;
  
  
  Overrides to the rescue
&lt;/h2&gt;

&lt;p&gt;Luckily, we can indeed have eslint &lt;a href="https://eslint.org/docs/user-guide/configuring#disabling-rules-only-for-a-group-of-files"&gt;apply different rules to different files&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For us, we know that the test files are consistently named &lt;code&gt;somemodule.test.js&lt;/code&gt; so the associated eslint config will be:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* rules here will apply to all files */&lt;/span&gt;
    &lt;span class="s2"&gt;"complexity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;6&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"max-nested-callbacks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"max-lines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;80&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s2"&gt;"overrides"&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="s2"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*.test.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s2"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// we've changed all the errors to warnings&lt;/span&gt;
        &lt;span class="c1"&gt;// and relaxed the rules&lt;/span&gt;
        &lt;span class="s2"&gt;"complexity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;12&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"max-nested-callbacks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;5&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"max-lines"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;200&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="s2"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*.any.other.files.js"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s2"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="cm"&gt;/* add suitable rule configs here */&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;p&gt;As you can see you can have multiple overrides for different file types, although we only override the unit test rules.&lt;/p&gt;


</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>eslint</category>
    </item>
    <item>
      <title>Abstract Syntax Trees for fun and profit</title>
      <dc:creator>Mark Lennox</dc:creator>
      <pubDate>Mon, 08 Apr 2019 21:07:57 +0000</pubDate>
      <link>https://dev.to/mlennox/abstract-syntax-trees-for-fun-and-profit-4mej</link>
      <guid>https://dev.to/mlennox/abstract-syntax-trees-for-fun-and-profit-4mej</guid>
      <description>&lt;h1&gt;
  
  
  Part One - an overview
&lt;/h1&gt;

&lt;p&gt;This article is &lt;a href="https://www.webpusher.ie/2019/02/07/ast-fun-and-profit/" rel="noopener noreferrer"&gt;a cross-post from my blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is part one of a series of articles about abstract syntax trees and their use in javascript. The scope of this article is a quick introduction to ASTs, babel plugins and some simple 'toy' examples.&lt;/p&gt;

&lt;p&gt;I will present the information and instruction using description, code/json and a diagram wherever possible in a bid to make the subject matter easier to comprehend for a wider range of types of learners.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlvuay2o5svc5datxbu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlvuay2o5svc5datxbu4.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Scope of this article
&lt;/h1&gt;

&lt;p&gt;This is a very light introduction to abstract syntax trees and the transformation of very simple code. Future articles will deal with real-world code, investigate static analysis, and look at approaches to creating babel plugins that could be useful in your own codebase, also - &lt;em&gt;codemods&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code
&lt;/h1&gt;

&lt;p&gt;A github repo accompanies this article &lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit" rel="noopener noreferrer"&gt;https://github.com/mlennox/abstractsyntaxforfunandprofit&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  what are abstract syntax trees
&lt;/h1&gt;

&lt;p&gt;These useful data structures represent the &lt;em&gt;abstract&lt;/em&gt; structure of source code regardless of the language. This is possible because despite the syntactic differences, all languages have a very large overlap in terms of the code structure they express: variable assignment, conditions, logic branching etc.&lt;/p&gt;

&lt;p&gt;An abstract syntax tree can be used to facilitate static analysis of code, rewriting code, compiling code (transform from one language to another), or very commonly in web development - transpiling code (transform from one language to another with similar level of abstraction ie. typescript to javascript, or es6+ to es5).&lt;/p&gt;

&lt;p&gt;In this article I'll show some examples of simple source code presented as abstract syntax trees, and also give a working example (see the &lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit" rel="noopener noreferrer"&gt;repo&lt;/a&gt;) by building simple &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;babel&lt;/a&gt; plugins to transform basic code&lt;/p&gt;

&lt;h2&gt;
  
  
  Purity of abstraction
&lt;/h2&gt;

&lt;p&gt;The AST examples I'll be showing are not &lt;em&gt;pure&lt;/em&gt; abstractions as they contain metadata relating to the source code and the elements are named to reflect javascript syntax. In all respects they are abstract syntax trees and closely follow the &lt;a href="https://github.com/estree/estree" rel="noopener noreferrer"&gt;EStree spec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The JSON representations in this article were generated by the &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;AST explorer&lt;/a&gt; listed in the &lt;code&gt;useful resources&lt;/code&gt; section below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful references
&lt;/h2&gt;

&lt;p&gt;Javascript AST viewer - &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;https://astexplorer.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developer docs for babel plugin development - &lt;a href="https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md" rel="noopener noreferrer"&gt;babel plugin handbook&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Babel type reference - &lt;a href="https://babeljs.io/docs/en/next/babel-types.html" rel="noopener noreferrer"&gt;https://babeljs.io/docs/en/next/babel-types.html&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  AST examples
&lt;/h1&gt;

&lt;p&gt;I'll provide some examples here to help visualise the resulting structure when code is parsed into an abstract syntax tree. &lt;/p&gt;

&lt;p&gt;The first will change instances of &lt;code&gt;var&lt;/code&gt; to &lt;code&gt;const&lt;/code&gt; and the second will transform an array into an object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple variable assignment
&lt;/h2&gt;

&lt;p&gt;If we take the simple javascript code snippet below and process it with an AST parser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;willIt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting AST can be expressed in a number of ways, most usefully as JSON . The snippet of code above transformed to an AST is represented by the following JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loc&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declarations&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loc&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loc&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;identifierName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;willIt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;willIt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BooleanLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loc&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;const&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sourceType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON is composed of a series of nodes each with a &lt;code&gt;type&lt;/code&gt; property. The JSON below strips all but the &lt;code&gt;type&lt;/code&gt; properties from the JSON above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declarations&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BooleanLiteral&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll also notice each node contains location data that refers to the position of the associated expression in the source code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loc&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&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;Also note, and this is the key point of interest for us, the variable declaration signifies the kind of variable - in this case a &lt;code&gt;const&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;const&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The graphical representation of the hierarchical nature of the tree is much easier to grasp.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbt1xt0kc95m5k5fakd9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbt1xt0kc95m5k5fakd9e.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Assigning an object
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;favouriteBelt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;material&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;leather&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON in this case is much more complex. I've omitted some of the properties for clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declarations&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;favouriteBelt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;properties&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;material&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;leather&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;length&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NumericLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&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="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;let&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the graphical representation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsqqhqpi0oq4p916w65l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsqqhqpi0oq4p916w65l.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that the hierarchy breaks down into familiar arrangements of nodes despite the relative increase in complexity compared to the simple value assignment.&lt;/p&gt;

&lt;h1&gt;
  
  
  Transforming code
&lt;/h1&gt;

&lt;p&gt;Hopefully, now you have some idea of what an AST looks like and how it relates to the source code. Next, I'll show how you can transform the source code using the AST. The familiar &lt;code&gt;babel&lt;/code&gt; library provides all the tools necessary to parse, transform and re-generate source code so for simplicity the examples provided will be babel plugins.&lt;/p&gt;

&lt;p&gt;One caveat, due to the way babel references plugins, these particular plugins can't easily be integrated into your codebase - ideally you would need a publish npm package. The alternative would be to write scripts to move the 'plugin' to a location accessible to babel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Babel plugins and traversing the AST
&lt;/h2&gt;

&lt;p&gt;Babel plugins use the &lt;a href="https://www.dofactory.com/javascript/visitor-design-pattern" rel="noopener noreferrer"&gt;visitor pattern&lt;/a&gt;, an abstraction which facilitates adding extra functionality to objects without requiring a refactor of the original object. The idea is that the object can 'accept' a visitor function that can alter the properties and, as we'll see, the structure of the object.&lt;/p&gt;

&lt;p&gt;As the AST is traversed each node gets passed to the babel plugin, a simplified version of which is shown below - an object literal implementing a &lt;code&gt;visitor&lt;/code&gt; property which consists of an object of methods named to match the node it should process. The example here has implemented a visitor that will act on all &lt;code&gt;ArrayExpression&lt;/code&gt; nodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ourCustomVisitor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ArrayExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do stuff&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;When the AST is traversed, data about all corresponding nodes will be passed into the corresponding handler method - the order in which they are passed in, how at what point in the hierarchy and how previous transformations might affect the code are concepts that need to be addressed with real-world code, but the simple, 'flat' examples in this article are chosen to focus on basic concepts.&lt;/p&gt;

&lt;p&gt;It is not true to say that the each matching node &lt;em&gt;itself&lt;/em&gt; is passed to the handler, each node handler is passed two parameters, &lt;code&gt;path&lt;/code&gt; (which does contain the node) and &lt;code&gt;state&lt;/code&gt;,which are detailed below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path
&lt;/h3&gt;

&lt;p&gt;The path is an object that represents the link between nodes. As you alter the AST babel will update the paths between all nodes.&lt;/p&gt;

&lt;p&gt;If we take the following example of an &lt;code&gt;ObjectProperty&lt;/code&gt; and the child &lt;code&gt;StringLiteral&lt;/code&gt; value&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gummi bears&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The path that represents the relationship between the nodes would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parent&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gummi bears&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;p&gt;In this case &lt;code&gt;node&lt;/code&gt; is the current element being handled in a &lt;code&gt;StringLiteral&lt;/code&gt; handler in the plugin's visitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;StringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// path is:&lt;/span&gt;
      &lt;span class="c1"&gt;// {&lt;/span&gt;
      &lt;span class="c1"&gt;//   "parent": {&lt;/span&gt;
      &lt;span class="c1"&gt;//     "type": "ObjectProperty",&lt;/span&gt;
      &lt;span class="c1"&gt;//       :&lt;/span&gt;
      &lt;span class="c1"&gt;//   },&lt;/span&gt;
      &lt;span class="c1"&gt;//   "node": {&lt;/span&gt;
      &lt;span class="c1"&gt;//     "type": "StringLiteral",&lt;/span&gt;
      &lt;span class="c1"&gt;//     "value": "gummi bears"&lt;/span&gt;
      &lt;span class="c1"&gt;//        :&lt;/span&gt;
      &lt;span class="c1"&gt;//   }&lt;/span&gt;
      &lt;span class="c1"&gt;//    :&lt;/span&gt;
      &lt;span class="c1"&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;h4&gt;
  
  
  Metadata and methods
&lt;/h4&gt;

&lt;p&gt;The path also contains metadata and methods to allow deleting, adding, or updating nodes within the tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit/blob/master/arrayToObject/arrayToObject.js" rel="noopener noreferrer"&gt;In the &lt;code&gt;arrayToObject&lt;/code&gt; example in the accompanying repo&lt;/a&gt; we use &lt;code&gt;path.replaceWith&lt;/code&gt; inside an &lt;code&gt;ArrayExpression&lt;/code&gt; handler to replace the node defining an array with a node defining an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;ArrayExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ArrayExpression has a property 'elements' that contains the array elements&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objectProps&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;h3&gt;
  
  
  State
&lt;/h3&gt;

&lt;p&gt;This contains details of the plugin - including the visitor declaration, pre and post methods. It also contains details of the file being parsed, the state of the AST etc. These can all be accessed within the plugin. The most commonly used state property is &lt;code&gt;opts&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Options
&lt;/h4&gt;

&lt;p&gt;If you are running the plugin as part of your babel stack, rather than through the &lt;a href="https://github.com/mlennox/abstractsyntaxforfunandprofit/blob/master/compile.js" rel="noopener noreferrer"&gt;'runner' in the associated repo&lt;/a&gt;, you can provide options to the babel plugins using your &lt;code&gt;.babelrc&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;plugins&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;customPlugin&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doIt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;decorate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paint&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;These options will be available in the plugin from &lt;code&gt;state.opts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;doIt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;decorate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Plugin Examples
&lt;/h1&gt;

&lt;p&gt;Keep in mind these are very simple examples that use a single variable assignment meaning we don't need to worry about scope, depth of code blocks etc. Future examples in other articles will use more complex code.&lt;/p&gt;

&lt;p&gt;A good starting template for babel plugins is shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;t&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// add handlers here&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;h2&gt;
  
  
  Convert &lt;code&gt;var&lt;/code&gt; to &lt;code&gt;const&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In this  example, I want to build a simple babel plugin to replace any instance of &lt;code&gt;var&lt;/code&gt; with &lt;code&gt;const&lt;/code&gt; in the example code - only &lt;code&gt;var&lt;/code&gt; should be affected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this 'var' should be replaced with a 'const'&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;itemOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;items&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;things&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gizmos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;widgets&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// this will stay a 'let'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;itemTwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tchotchke&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stuff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yokes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AST for the  &lt;code&gt;itemOne&lt;/code&gt; variable assignment is presented below. The AST below has all the location information removed for clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;var&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declarations&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;itemOne&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ArrayExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elements&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;items&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;things&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gizmos&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;widgets&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="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;leadingComments&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CommentLine&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; this 'var' should be replaced with a 'const'&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;p&gt;The node we are interested in is the top-level node &lt;code&gt;VariableDeclaration&lt;/code&gt;, so lets add a handler for that in the babel plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;t&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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="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 need to recall that the &lt;code&gt;path&lt;/code&gt; is not the node, but the relationship between nodes and metadata etc. To get at the &lt;code&gt;VariableDeclaration&lt;/code&gt; node we reference &lt;code&gt;path.node&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's have a quick look at the AST again, focussing on the point of interest for us&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;var&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 want to update the &lt;code&gt;kind&lt;/code&gt; of variable declaration from a &lt;code&gt;var&lt;/code&gt; to &lt;code&gt;const&lt;/code&gt;. The only other valid option is of course &lt;code&gt;let&lt;/code&gt;. Babel &lt;em&gt;will&lt;/em&gt; let you update that to anything you like, which seems like an oversight, I'm actually not sure why they don't throw an error, or limit the values in some way.&lt;/p&gt;

&lt;p&gt;The updated plugin that updates the variable declaration to &lt;code&gt;const&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; ensures that only &lt;code&gt;var&lt;/code&gt; will be affected. I've removed the &lt;code&gt;types&lt;/code&gt; destructuring as I don't use it in this plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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;kind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;var&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="nx"&gt;path&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;kind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;const&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="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;You can run this example yourself from the accompanying repo. Assuming you have installed the dependencies with &lt;code&gt;npm install&lt;/code&gt; the command to run the transformation is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;varToConst&lt;/span&gt; &lt;span class="nx"&gt;vars&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="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try messing with the code, adding &lt;code&gt;console.log&lt;/code&gt; to see the structure of the path, change the code in &lt;code&gt;vars.source.js&lt;/code&gt; to see how the result is affected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Object from Array
&lt;/h2&gt;

&lt;p&gt;While this is slightly more complex than the 'var to const' example, it is still fairly simple. I'll include some diagrams to be sure the transformation is clear.&lt;/p&gt;

&lt;p&gt;First, the source code that we will transform.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// we'll convert this from an array to an object literal&lt;/span&gt;
&lt;span class="c1"&gt;// that uses the position in the list as the key&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrupenny&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="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;penny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a penny, ya dope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the transformation is complete we want to end up with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrupenny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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="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;penny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a penny, ya dope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that we will need to replace the &lt;code&gt;ArrayExpression&lt;/code&gt; with an &lt;code&gt;ObjectExpression&lt;/code&gt; and convert each of the &lt;code&gt;elements&lt;/code&gt; of the &lt;code&gt;ArrayExpression&lt;/code&gt; into an &lt;code&gt;ObjectProperty&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The AST of the source code is below, with some properties removed for clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;declarations&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;coins&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;init&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ArrayExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;elements&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;thrupenny&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;properties&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;penny&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ObjectProperty&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Identifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a penny, ya dope&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="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NumericLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&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="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;const&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, a simplified diagram of the AST showing each element - the &lt;code&gt;ObjectExpression&lt;/code&gt; in the second element has also been simplified for clarity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylcm0ys49vyl0qi0h23l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylcm0ys49vyl0qi0h23l.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm interested in the &lt;code&gt;elements&lt;/code&gt; of the &lt;code&gt;ArrayExpression&lt;/code&gt;. I will take each element and construct an &lt;code&gt;ObjectProperty&lt;/code&gt; that uses a &lt;code&gt;StringLiteral&lt;/code&gt; of the array index of the element as the &lt;code&gt;Identifier&lt;/code&gt; and uses the element itself as the value. Focussing on the first element in the array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// const coins = ['thrupenny', { name: 'penny', value: 'a penny, ya dope' }, 2];&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;thrupenny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index is zero, so the ObjectProperty - constructed here using &lt;code&gt;babel.types&lt;/code&gt; - looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstArrayElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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;elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;firstObjectProperty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`0`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;firstArrayElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the other elements are different types, the approach is the same. The elements don't need any extra processing to convert them to a different type so we can convert the Array elements into Object properties in one step, using &lt;code&gt;Array.map&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;element&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;A simplified diagram of the resulting AST is shown below. The blue elements have all been created by the code outlined above:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnabtsv8zamflt9t2b1es.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnabtsv8zamflt9t2b1es.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last step is to replace the &lt;code&gt;ArrayExpression&lt;/code&gt; node with an &lt;code&gt;ObjectExpression&lt;/code&gt; constructed using the new array of &lt;code&gt;ObjectProperty&lt;/code&gt;. Luckily the &lt;code&gt;path&lt;/code&gt; includes a number of methods to help in transforming the AST, including &lt;code&gt;replaceWith(replacementNode)&lt;/code&gt; which swaps the current node for the node provided as a param.&lt;/p&gt;

&lt;p&gt;Constructing the &lt;code&gt;ObjectExpression&lt;/code&gt; is simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;objectExpression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objectProps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I can use the &lt;code&gt;replaceWith&lt;/code&gt; method to swap out the &lt;code&gt;ArrayExpression&lt;/code&gt; for the new &lt;code&gt;ObjectExpression&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objectExpression&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which will generate the expected result&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thrupenny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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="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;penny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a penny, ya dope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run this example yourself from the accompanying repo. Assuming you have installed the dependencies with &lt;code&gt;npm install&lt;/code&gt; the command to run the transformation is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;arrayToObject&lt;/span&gt; &lt;span class="nx"&gt;array&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="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>babel</category>
      <category>abstractsyntaxtrees</category>
    </item>
  </channel>
</rss>
