<?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: Takanori Ishikawa</title>
    <description>The latest articles on DEV Community by Takanori Ishikawa (@ishikawa).</description>
    <link>https://dev.to/ishikawa</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%2F568057%2F5069401c-7d6e-4f89-b36c-381eedb9b9e7.jpeg</url>
      <title>DEV Community: Takanori Ishikawa</title>
      <link>https://dev.to/ishikawa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ishikawa"/>
    <language>en</language>
    <item>
      <title>Exports dependencies in Elixir 1.11</title>
      <dc:creator>Takanori Ishikawa</dc:creator>
      <pubDate>Wed, 27 Jan 2021 20:57:57 +0000</pubDate>
      <link>https://dev.to/ishikawa/exports-dependencies-in-elixir-1-11-35c0</link>
      <guid>https://dev.to/ishikawa/exports-dependencies-in-elixir-1-11-35c0</guid>
      <description>&lt;p&gt;&lt;a href="https://unsplash.com/photos/I_ZGCGoodhM"&gt;Photo&lt;/a&gt; by &lt;a href="https://unsplash.com/@lazares?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;LĂZĂRESCU ALEXANDRA&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last year, in October 2020, &lt;a href="https://elixir-lang.org/blog/2020/10/06/elixir-v1-11-0-released/"&gt;Elixir 1.11 was released&lt;/a&gt; 🎉 I looked at one of the compiler improvements, &lt;em&gt;Exports dependencies&lt;/em&gt;, including its behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the "&lt;em&gt;Exports dependencies"&lt;/em&gt; improves compilation?
&lt;/h2&gt;

&lt;p&gt;Prior to Elixir 1.11, if &lt;code&gt;module A&lt;/code&gt; depends on &lt;code&gt;module B&lt;/code&gt; by &lt;code&gt;import&lt;/code&gt; or &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;module B&lt;/code&gt; was considered as &lt;em&gt;Compile time dependencies&lt;/em&gt; of &lt;code&gt;module A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since Elixir 1.11, if &lt;code&gt;module A&lt;/code&gt; uses only the public interface of &lt;code&gt;module B&lt;/code&gt; (struct or public functions) is now &lt;em&gt;Exports dependencies&lt;/em&gt;, and there is no need to recompile &lt;code&gt;module A&lt;/code&gt; unless the public interface  of &lt;code&gt;module B&lt;/code&gt; changes. &lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;This will reduce the number of files that need to be recompiled when the source code is changed, shortening the "fix - build - run" cycle. This is great because the compilation time required for a build is an important indicator that directly affects development productivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Exports dependencies in example
&lt;/h2&gt;

&lt;p&gt;You can get an idea about Exports dependencies from coding an example. Consider the two modules below. &lt;sup id="fnref2"&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;moduleA.ex&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;ElixirV11&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ModuleA&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;ElixirV11&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ModuleB&lt;/span&gt;

  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="no"&gt;ModuleB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;fetch_name:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="no"&gt;ModuleB&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;fetch_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Who?"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;moduleB.ex&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;ElixirV11&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ModuleB&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_name&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_name&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ModuleA depends on the struct and &lt;code&gt;fetch_name/1&lt;/code&gt; functions of ModuleB. This is why &lt;code&gt;import ModuleB, only: [fetch_name: 1]&lt;/code&gt; in &lt;code&gt;moduleA.ex&lt;/code&gt; was &lt;em&gt;Compile time dependencies&lt;/em&gt; before Elixir 1.10. However, since these two are public interfaces, starting with Elixir 1.11, they will be &lt;em&gt;Exports dependencies&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So, when you change &lt;code&gt;moduleB.ex&lt;/code&gt;, you need to recompile &lt;code&gt;moduleA.ex&lt;/code&gt; in Elixir 1.10, but not in Elixir 1.11.&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="c"&gt;# Elixir 1.10&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;lib/moduleB.ex    
&lt;span class="nv"&gt;$ &lt;/span&gt;mix compile &lt;span class="nt"&gt;--verbose&lt;/span&gt;
Compiling 1 file &lt;span class="o"&gt;(&lt;/span&gt;.ex&lt;span class="o"&gt;)&lt;/span&gt;
Compiled lib/moduleB.ex
Compiled lib/moduleA.ex

&lt;span class="c"&gt;# Elixir 1.11&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;lib/moduleB.ex 
&lt;span class="nv"&gt;$ &lt;/span&gt;mix compile &lt;span class="nt"&gt;--verbose&lt;/span&gt;
Compiling 1 file &lt;span class="o"&gt;(&lt;/span&gt;.ex&lt;span class="o"&gt;)&lt;/span&gt;
Compiled lib/moduleB.ex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's change the implementation of &lt;code&gt;ModuleB&lt;/code&gt; without changing the public interface.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;moduleB.ex&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;ElixirV11&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;ModuleB&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;defstruct&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;check_name!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_name&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fetch_name&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;check_name!&lt;/span&gt;&lt;span class="p"&gt;(%&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;is_binary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Added a private function called &lt;code&gt;check_name!/1&lt;/code&gt; and changed it to be used in &lt;code&gt;new/1&lt;/code&gt;. Since this does not change the public interface, it should not need to be recompiled.&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="c"&gt;# Elixir 1.10&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mix compile &lt;span class="nt"&gt;--verbose&lt;/span&gt;
Compiling 1 file &lt;span class="o"&gt;(&lt;/span&gt;.ex&lt;span class="o"&gt;)&lt;/span&gt;
Compiled lib/moduleB.ex
Compiled lib/moduleA.ex

&lt;span class="c"&gt;# Elixir 1.11&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mix compile &lt;span class="nt"&gt;--verbose&lt;/span&gt;
Compiling 1 file &lt;span class="o"&gt;(&lt;/span&gt;.ex&lt;span class="o"&gt;)&lt;/span&gt;
Compiled lib/moduleB.ex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As expected, &lt;code&gt;ModuleA&lt;/code&gt; do not need to be compiled in Elixir 1.11.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exports dependencies in a real project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/elixir-lang/elixir/commit/9a6db666a107b42c1242cf727eafe7638674f3cc"&gt;The commit&lt;/a&gt; says as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;making imports more feasible for large projects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As this commit says, it will be easy to use &lt;code&gt;import/2&lt;/code&gt; in large projects.&lt;/p&gt;

&lt;p&gt;In fact, in the project I'm working on now, I changed the modules that manipulate Repo, which is imported at various points, to find out the number of files that are recompiled.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Elixir 1.10&lt;/strong&gt; - 48&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elixir 1.11&lt;/strong&gt; - 14&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The number of recompiled files had decreased dramatically 🎉&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;However, if you are using macros, it will be Compile time dependencies. This is explained in detail in &lt;strong&gt;Dependencies types&lt;/strong&gt; on the &lt;a href="https://hexdocs.pm/mix/Mix.Tasks.Xref.html"&gt;mix xref&lt;/a&gt; page. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;The change to the compiler is probably this. &lt;a href="https://github.com/elixir-lang/elixir/commit/9a6db666a107b42c1242cf727eafe7638674f3cc"&gt;Do not make requires/imports compile-time dependencies · elixir-lang/elixir@9a6db66&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>elixir</category>
    </item>
    <item>
      <title>Testing Expo apps with Jest in TypeScript</title>
      <dc:creator>Takanori Ishikawa</dc:creator>
      <pubDate>Sat, 16 Jan 2021 08:57:09 +0000</pubDate>
      <link>https://dev.to/ishikawa/testing-expo-apps-with-jest-in-typescript-175l</link>
      <guid>https://dev.to/ishikawa/testing-expo-apps-with-jest-in-typescript-175l</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://unsplash.com/photos/-DnKOro7GaQ"&gt;Cover image&lt;/a&gt; by &lt;a href="https://unsplash.com/@quinietjie?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Quinton Coetzee&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Recently I've been working on a new project with &lt;a href="https://expo.io/"&gt;Expo&lt;/a&gt; and &lt;a href="https://reactnative.dev/"&gt;React Native&lt;/a&gt; 🙂&lt;/p&gt;

&lt;p&gt;I want to test my Expo project with Jest. Basically, you can follow &lt;a href="https://docs.expo.io/guides/testing-with-jest/"&gt;Testing with Jest - Expo Documentation&lt;/a&gt;, but in the case of TypeScript, you have to change some settings in following points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jest configuration for Expo project in TypeScript&lt;/li&gt;
&lt;li&gt;Writing Jest configuration file with TypeScript&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, let me show what the version. of Expo in my machine.&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;expo &lt;span class="nt"&gt;--version&lt;/span&gt;                                              
4.0.17
&lt;span class="nv"&gt;$ &lt;/span&gt;npm list expo
my-expo-app
└── expo@40.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring Jest and add a simple test
&lt;/h2&gt;

&lt;p&gt;First of all, install the necessary packages; it is the Expo way to install &lt;a href="https://www.npmjs.com/package/jest-expo"&gt;jest-expo&lt;/a&gt; instead of the jest package.&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;npm i jest-expo react-test-renderer &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since it is a TypeScript project, we should install &lt;code&gt;.d.ts&lt;/code&gt; of the package too.&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;npm i @types/jest @types/react-test-renderer &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the Jest configuration to &lt;code&gt;package.json&lt;/code&gt; as mentioned in the documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"preset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest-expo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"transformIgnorePatterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice &lt;code&gt;transformIgnorePatterns&lt;/code&gt; contains a long regular expression 🤔&lt;/p&gt;

&lt;p&gt;Jest doesn't transpile files under the &lt;code&gt;node_modules&lt;/code&gt; directory by default, but there are some React Native libraries that are distributed without being transpiled. By setting &lt;a href="https://jestjs.io/docs/en/configuration#transformignorepatterns-arraystring"&gt;&lt;code&gt;transformIgnorePatterns&lt;/code&gt;&lt;/a&gt; as above, we can make them the target of the transpile. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x(?!y)&lt;/code&gt; &lt;strong&gt;Negative lookahead assertion:&lt;/strong&gt; Matches "x" only if "x" is not followed by "y". Such long regular expressions should be commented like Perl, but unfortunately the &lt;code&gt;/x&lt;/code&gt; modifier is not available in JavaScript. &lt;sup id="fnref1"&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's write a sample test &lt;code&gt;App.test.tsx&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-test-renderer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;App /&amp;gt;&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;has 1 child&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="o"&gt;=&amp;gt;&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;tree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&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;App&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;toJSON&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// @ts-ignore&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&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="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 fact, the above code can't be compiled by a type error, but here I've ignored it with &lt;code&gt;@ts-ignore&lt;/code&gt;. This is because fixing the type error is out of the scope of this article, and in the future I will use the &lt;a href="https://testing-library.com/docs/react-testing-library/%20intro/"&gt;React Testing Library&lt;/a&gt; instead of using react-test-renderer directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running test and configuring Jest properly
&lt;/h2&gt;

&lt;p&gt;Okay, let's run the test.&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;npx jest
 FAIL  ./App.test.tsx
  &amp;lt;App /&amp;gt;
    ✕ has 1 child &lt;span class="o"&gt;(&lt;/span&gt;45ms&lt;span class="o"&gt;)&lt;/span&gt;

  ● &amp;lt;App /&amp;gt; › has 1 child

    Element &lt;span class="nb"&gt;type &lt;/span&gt;is invalid: expected a string &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;built-in components&lt;span class="o"&gt;)&lt;/span&gt; or a class/function &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;composite components&lt;span class="o"&gt;)&lt;/span&gt; but got: object.

      at createFiberFromTypeAndProps &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16180:21&lt;span class="o"&gt;)&lt;/span&gt;
      at createFiberFromElement &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16208:15&lt;span class="o"&gt;)&lt;/span&gt;
      at reconcileSingleElement &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5358:23&lt;span class="o"&gt;)&lt;/span&gt;
      at reconcileChildFibers &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5418:35&lt;span class="o"&gt;)&lt;/span&gt;
      at reconcileChildren &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7991:28&lt;span class="o"&gt;)&lt;/span&gt;
      at updateHostRoot &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8547:5&lt;span class="o"&gt;)&lt;/span&gt;
      at beginWork &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9994:14&lt;span class="o"&gt;)&lt;/span&gt;
      at performUnitOfWork &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13800:12&lt;span class="o"&gt;)&lt;/span&gt;
      at workLoopSync &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13728:5&lt;span class="o"&gt;)&lt;/span&gt;
      at renderRootSync &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13691:7&lt;span class="o"&gt;)&lt;/span&gt;

  console.error
    Warning: React.createElement: &lt;span class="nb"&gt;type &lt;/span&gt;is invalid &lt;span class="nt"&gt;--&lt;/span&gt; expected a string &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;built-in components&lt;span class="o"&gt;)&lt;/span&gt; or a class/function &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;composite components&lt;span class="o"&gt;)&lt;/span&gt; but got: object.

       6 | describe&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;App /&amp;gt;"&lt;/span&gt;, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       7 |   it&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"has 1 child"&lt;/span&gt;, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  8 |     const tree &lt;span class="o"&gt;=&lt;/span&gt; renderer.create&lt;span class="o"&gt;(&lt;/span&gt;&amp;lt;App /&amp;gt;&lt;span class="o"&gt;)&lt;/span&gt;.toJSON&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         |                                  ^
       9 |     expect&lt;span class="o"&gt;(&lt;/span&gt;tree.children.length&lt;span class="o"&gt;)&lt;/span&gt;.toBe&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      10 |   &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      11 | &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      at printWarning &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react/cjs/react.development.js:315:30&lt;span class="o"&gt;)&lt;/span&gt;
      at error &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react/cjs/react.development.js:287:5&lt;span class="o"&gt;)&lt;/span&gt;
      at Object.createElementWithValidation &lt;span class="o"&gt;[&lt;/span&gt;as createElement] &lt;span class="o"&gt;(&lt;/span&gt;node_modules/react/cjs/react.development.js:1788:7&lt;span class="o"&gt;)&lt;/span&gt;
      at Object.&amp;lt;anonymous&amp;gt; &lt;span class="o"&gt;(&lt;/span&gt;App.test.tsx:8:34&lt;span class="o"&gt;)&lt;/span&gt;

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.254s
Ran all &lt;span class="nb"&gt;test &lt;/span&gt;suites.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It failed. The error is also mysterious.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Getting a warning that the &lt;code&gt;App&lt;/code&gt; component is an &lt;code&gt;object&lt;/code&gt;. When I run Jest, I get this error on the line below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&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 error was happened because the &lt;code&gt;import&lt;/code&gt; loads &lt;strong&gt;&lt;code&gt;app.json&lt;/code&gt; instead of &lt;code&gt;App.tsx&lt;/code&gt;&lt;/strong&gt;. To prevent this, configure Jest's &lt;a href="https://jestjs.io/docs/ja/configuration#"&gt;&lt;code&gt;moduleFileExtensions&lt;/code&gt;&lt;/a&gt; to prioritize &lt;code&gt;.tsx&lt;/code&gt; and &lt;code&gt;.ts&lt;/code&gt; over &lt;code&gt;.json&lt;/code&gt; when loading modules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"moduleFileExtensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"tsx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"jsx"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After making this change, the test will pass successfully.&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;npx jest
 PASS  ./App.test.tsx
  &amp;lt;App /&amp;gt;
    ✓ has 1 child &lt;span class="o"&gt;(&lt;/span&gt;2341ms&lt;span class="o"&gt;)&lt;/span&gt;

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.855s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Googled and found that someone has the same issue &lt;sup id="fnref2"&gt;2&lt;/sup&gt;, so I posted a &lt;a href="https://github.com/expo/expo/pull/11580"&gt;PR&lt;/a&gt; to the documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Jest configuration file with TypeScript
&lt;/h2&gt;

&lt;p&gt;Okay, I was able to run the test, but the configuration became a bit complicated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"preset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest-expo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"transformIgnorePatterns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@sentry/.*)"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"moduleFileExtensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"tsx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"jsx"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In particular, &lt;code&gt;transformIgnorePatterns&lt;/code&gt; is complex, and I'd rather take it out than put it in &lt;code&gt;package.json&lt;/code&gt;. And I want to write it with TypeScript if possible.&lt;/p&gt;

&lt;p&gt;From Jest version &lt;a href="https://github.com/facebook/jest/blob/master/CHANGELOG.md#2660"&gt;26.6.0&lt;/a&gt;, &lt;strong&gt;TypeScript configuration file is supported&lt;/strong&gt;. &lt;a href="https://www.npmjs.com/package/ts-node"&gt;ts-node&lt;/a&gt; is required and must be installed.&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;npm i ts-node &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the jest which jest-expo depends on is old, install it as well.&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;npm list jest           
my-expo-app
└─┬ jest-expo@40.0.1
  └── jest@25.5.4 
&lt;span class="nv"&gt;$ &lt;/span&gt;npm i jest &lt;span class="nt"&gt;--save-dev&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a new &lt;code&gt;jest.config.ts&lt;/code&gt; and migrate the configuration in &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Config } from "@jest/types";

// By default, all files inside `node_modules` are not transformed. But some 3rd party
// modules are published as untranspiled, Jest will not understand the code in these modules.
// To overcome this, exclude these modules in the ignore pattern.
const untranspiledModulePatterns = [
  "(jest-)?react-native",
  "@react-native-community",
  "expo(nent)?",
  "@expo(nent)?/.*",
  "react-navigation",
  "@react-navigation/.*",
  "@unimodules/.*",
  "unimodules",
  "sentry-expo",
  "native-base",
  "react-native-svg",
];

const config: Config.InitialOptions = {
  preset: "jest-expo",
  transformIgnorePatterns: [
    `node_modules/(?!${untranspiledModulePatterns.join("|")})`,
  ],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
};

export default config;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simplifing the lengthy regex expression made things look a lot better. Compared to &lt;code&gt;package.json&lt;/code&gt;, which doesn't allow comments, it's nice to be able to write comments😅.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[2021.01.24]&lt;/strong&gt; Actually, &lt;code&gt;transformIgnorePatterns&lt;/code&gt; is &lt;a href="https://github.com/expo/expo/blob/9f1c0850d814e131cb565dd3d0fc9a91481e1e06/packages/jest-expo/jest-preset.js#L40"&gt;included&lt;/a&gt; in the preset of jest-expo, so there is no need to specify them if you are fine with the default. However, since this list needs to be added depending on the library used, I personally use this method. The above example has been updated with the latest list.&lt;/p&gt;

&lt;p&gt;One last point: if you re-installed jest instead of the version that the jest-expo depends on, you will have two versions of jest mixed under your &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check it with the &lt;code&gt;npm list&lt;/code&gt; command.&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;npm list jest        
my-expo-app
├── jest@26.6.3 
└─┬ jest-expo@40.0.1
  └── jest@25.5.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that there are two versions of Jest. There is one problem with this: &lt;strong&gt;we don't know which version the npx command will execute&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The npx command executes commands placed under &lt;code&gt;node_modules/.bin&lt;/code&gt;. These are symbolic links to files in each package, and they will be overwritten depending on the order of installation.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;./node_modules/.bin/jest&lt;/code&gt;  is now pointing to &lt;code&gt;. /node_modules/.bin/jest/bin/jest.js&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;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ./node_modules/.bin/jest
lrwxr-xr-x  1 takanori_is  staff  19  1 16 16:31 ./node_modules/.bin/jest -&amp;gt; ../jest/bin/jest.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if you re-install &lt;code&gt;jest-expo&lt;/code&gt;, &lt;code&gt;./node_modules/jest-expo/bin/jest.js&lt;/code&gt; will replace it.&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;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ./node_modules/.bin/jest
lrwxr-xr-x  1 takanori_is  staff  24  1 16 16:34 ./node_modules/.bin/jest -&amp;gt; ../jest-expo/bin/jest.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, until the version of &lt;code&gt;jest&lt;/code&gt; on which &lt;code&gt;jest-expo&lt;/code&gt; depends is upgraded, it is safe to run &lt;code&gt;. /node_modules/jest/bin/jest.js&lt;/code&gt; directly instead of via npx command. Let's register it as a script in &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./node_modules/jest/bin/jest.js"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now run it with &lt;code&gt;npm test&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;npm &lt;span class="nb"&gt;test&lt;/span&gt;                  

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; @ &lt;span class="nb"&gt;test&lt;/span&gt; /Users/ishikawasonkyou/Developer/Workspace/my-expo-app
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./node_modules/jest/bin/jest.js

 PASS  ./App.test.tsx
  &amp;lt;App /&amp;gt;
    ✓ has 1 child &lt;span class="o"&gt;(&lt;/span&gt;150 ms&lt;span class="o"&gt;)&lt;/span&gt;

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.767 s, estimated 1 s
Ran all &lt;span class="nb"&gt;test &lt;/span&gt;suites.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet"&gt;Regular expression syntax cheatsheet - JavaScript | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/65549722/jest-expo-crashes-on-example-react-createelement-type-is-invalid-expected-a"&gt;reactjs - Jest-Expo crashes on example (React.createElement: type is invalid -- expected a string) - Stack Overflow&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>typescript</category>
      <category>jest</category>
    </item>
  </channel>
</rss>
