<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://metaron.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 30 Aug 2026 22:37:15 GMT</lastBuildDate><atom:link href="https://metaron.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Getting Jest to work with your ESM-based npm library for React Native]]></title><description><![CDATA[Introduction
It was all so easy. Simply run the react-native init command, set the preset in your Jest config as 'react-native', and voila, npm test works like a charm. But, things aren't as rosy when you want to publish npm libraries and Jest is you...]]></description><link>https://metaron.hashnode.dev/getting-jest-to-work-with-your-esm-based-npm-library-for-react-native</link><guid isPermaLink="true">https://metaron.hashnode.dev/getting-jest-to-work-with-your-esm-based-npm-library-for-react-native</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[npm]]></category><category><![CDATA[React Native]]></category><category><![CDATA[Jest]]></category><category><![CDATA[javascript modules]]></category><dc:creator><![CDATA[Ronil Mehta]]></dc:creator><pubDate>Thu, 21 Jul 2022 11:31:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1658401678900/Rg3FWrGuo.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>It was all so easy. Simply run the <code>react-native init</code> command, set the preset in your Jest config as <code>'react-native'</code>, and voila, <code>npm test</code> works like a charm. But, things aren't as rosy when you want to publish npm libraries and Jest is your chosen test suite. </p>
<p>While we all love the modern ESM <code>import from</code> and <code>export default</code> syntax, Jest - not so much. It is very much still in love with CommonJS syntax. This along with the fact that <a target="_blank" href="https://github.com/facebook/react-native/blob/main/index.js#L8">react-native code uses Flow</a>, made my life not-so-easy when trying to publish my npm library. It wasn't just me experiencing these issues. Based on these discussions - <a target="_blank" href="https://github.com/react-native-community/upgrade-support/issues/152">Issue 152</a>, <a target="_blank" href="https://github.com/facebook/jest/issues/10111">Issue 10111</a> - many of my fellow devs were facing similar roadblocks. </p>
<p>To introduce some order to all the above chaos, here are some steps to get Jest working with your ESM-based npm library for React Native:</p>
<h3 id="heading-setting-up-your-packagejson">Setting up your package.json</h3>
<pre><code class="lang-json">{
{
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"my-react-native-library"</span>,
    <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.1"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A useful library"</span>,
    <span class="hljs-attr">"main"</span>: <span class="hljs-string">"dist/index.js"</span>,
    <span class="hljs-attr">"scripts"</span>: {
      <span class="hljs-attr">"test"</span>: <span class="hljs-string">"jest"</span>,
      <span class="hljs-attr">"prepare"</span>: <span class="hljs-string">"npm run build"</span>,
      <span class="hljs-attr">"build"</span>: <span class="hljs-string">"BABEL_ENV=production babel &lt;folder-path-with-your-code&gt; --out-dir dist"</span>,
    },
    <span class="hljs-attr">"keywords"</span>: [
      <span class="hljs-string">"useful"</span>
    ],
    <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Ronil Mehta"</span>,
    <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>,
  <span class="hljs-attr">"dependencies"</span>: {
    <span class="hljs-attr">"@react-native-async-storage/async-storage"</span>: <span class="hljs-string">"~1.15.0"</span>,
    <span class="hljs-attr">"react-native-get-random-values"</span>: <span class="hljs-string">"~1.7.0"</span>,
    <span class="hljs-attr">"uuid"</span>: <span class="hljs-string">"^8.3.2"</span>
  },
  <span class="hljs-attr">"devDependencies"</span>: {
    <span class="hljs-attr">"@babel/cli"</span>: <span class="hljs-string">"^7.18.9"</span>,
    <span class="hljs-attr">"@babel/core"</span>: <span class="hljs-string">"^7.18.9"</span>,
    <span class="hljs-attr">"@babel/preset-env"</span>: <span class="hljs-string">"^7.18.9"</span>,
    <span class="hljs-attr">"@babel/preset-flow"</span>: <span class="hljs-string">"^7.18.6"</span>,
    <span class="hljs-attr">"jest"</span>: <span class="hljs-string">"^27.5.1"</span>,
    <span class="hljs-attr">"jsdoc-to-markdown"</span>: <span class="hljs-string">"^7.1.1"</span>
  }
  }
}
</code></pre>
<h3 id="heading-setting-up-your-babelconfigjs">Setting up your babel.config.js</h3>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">presets</span>: [
        <span class="hljs-string">"@babel/preset-env"</span>,
        <span class="hljs-string">"@babel/preset-flow"</span>
    ],
    <span class="hljs-attr">env</span>: {
        <span class="hljs-attr">production</span>: {
            <span class="hljs-attr">ignore</span>: [
                <span class="hljs-string">"&lt;folder-path-with-your-code&gt;/**/*.test.js"</span>
            ]
        }
    }
}
</code></pre>
<p>It's important to know that babel runs the <code>presets</code> array from right to left. Meaning, it will first run <code>@babel/preset-flow</code> and then <code>@babel/preset-env</code>. <code>@babel/preset-flow</code> first converts any Flow syntax in react-native to ESM. <code>@babel/preset-env</code> then converts this ESM code to CommonJS, which is then used by Jest. </p>
<p><em>Note: Jest had issues when the babel configs were in <code>.babelrc</code> or in <code>package.json</code>. Please make sure to write your babel config in <code>babel.config.js</code>.</em></p>
<h3 id="heading-setting-up-your-jestconfigjs">Setting up your jest.config.js</h3>
<p>Run <code>npx jest --init</code> in the project root directory to begin the config file generator wizard. The following are the inputs you should provide:</p>
<pre><code>$ npx jest <span class="hljs-comment">--init</span>
The following questions will <span class="hljs-keyword">help</span> Jest <span class="hljs-keyword">to</span> <span class="hljs-keyword">create</span> a suitable configuration <span class="hljs-keyword">for</span> your <span class="hljs-keyword">project</span>
✔ Would you <span class="hljs-keyword">like</span> <span class="hljs-keyword">to</span> <span class="hljs-keyword">use</span> Typescript <span class="hljs-keyword">for</span> the configuration <span class="hljs-keyword">file</span>? … <span class="hljs-keyword">no</span>
✔ <span class="hljs-keyword">Choose</span> the <span class="hljs-keyword">test</span> environment that will be used <span class="hljs-keyword">for</span> testing › jsdom (browser-<span class="hljs-keyword">like</span>)
✔ <span class="hljs-keyword">Do</span> you want Jest <span class="hljs-keyword">to</span> <span class="hljs-keyword">add</span> coverage reports? … yes
✔ Which provider should be used <span class="hljs-keyword">to</span> instrument code <span class="hljs-keyword">for</span> coverage? › babel
✔ Automatically <span class="hljs-keyword">clear</span> mock calls, instances <span class="hljs-keyword">and</span> results <span class="hljs-keyword">before</span> every <span class="hljs-keyword">test</span>? … yes
</code></pre><p>Once the config is generated, set <code>preset: 'react-native'</code>.</p>
<p>By default, Jest ignores libraries in <code>node_modules</code> when transforming code using babel. But since react-native contains <code>Flow</code> code that needs to be transpiled, a special regex needs to be added to <code>transformIgnorePatterns</code> in the config. One of the most important things <code>preset: 'react-native' does is force Jest to transform the react-native libraries in</code>node_modules<code>to a form Jest can understand.  It does this by presetting the value of</code>transformIgnorePatterns<code>in</code>jest.config.js`. </p>
<h3 id="heading-running-jest">Running Jest</h3>
<p>Now that you have carefully followed the above instructions and set up the configs, it is time to run some unit tests:
Execute <code>npm test</code> and hopefully, you see a whole lot of green text!</p>
]]></content:encoded></item></channel></rss>