<?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: Steve Ruiz</title>
    <description>The latest articles on DEV Community by Steve Ruiz (@steveruizok).</description>
    <link>https://dev.to/steveruizok</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%2F184938%2F0459a4d2-bbe5-49e9-8025-8fea5bea3352.jpg</url>
      <title>DEV Community: Steve Ruiz</title>
      <link>https://dev.to/steveruizok</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/steveruizok"/>
    <language>en</language>
    <item>
      <title>Jest and ESM: Cannot use import statement outside a module</title>
      <dc:creator>Steve Ruiz</dc:creator>
      <pubDate>Fri, 25 Jun 2021 10:27:09 +0000</pubDate>
      <link>https://dev.to/steveruizok/jest-and-esm-cannot-use-import-statement-outside-a-module-4mmj</link>
      <guid>https://dev.to/steveruizok/jest-and-esm-cannot-use-import-statement-outside-a-module-4mmj</guid>
      <description>&lt;p&gt;This post describes a fix for a common issue with &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; and &lt;a href="https://jestjs.io/docs/ecmascript-modules"&gt;ESM modules&lt;/a&gt;. The available help is not very good: I found many variations on the same question while searching for an answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;In a Next.js project, I kept running into an error while using dependencies with ESM modules (.mjs). In my case, this dependency was &lt;code&gt;sucrase&lt;/code&gt;, which I was using as part of my app.&lt;/p&gt;

&lt;p&gt;The error I saw was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /Users/.../node_modules/sucrase/dist/index.mjs:1
    ({"Object.&amp;lt;anonymous&amp;gt;":function(module,exports,require,__dirname,__filename,jest){import CJSImportProcessor from "./CJSImportProcessor";
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;After much trial and error, here's what worked.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; jest @babel/core babel-jest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create a babel.config.js
&lt;/h3&gt;

&lt;p&gt;By default, a Next.js project uses a file called &lt;code&gt;.babelrc&lt;/code&gt; to configure Babel. We need to &lt;strong&gt;replace&lt;/strong&gt; this with a file named &lt;code&gt;babel.config.js&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="c1"&gt;// babel.config.js&lt;/span&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;presets&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="s1"&gt;next/babel&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;h3&gt;
  
  
  3.
&lt;/h3&gt;

&lt;p&gt;Finally, the important part. In your &lt;code&gt;jest.config.js&lt;/code&gt;, include the following lines.&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;// jest.config.js&lt;/span&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="p"&gt;{&lt;/span&gt;  
  &lt;span class="na"&gt;transformIgnorePatterns&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="s1"&gt;node_modules/(?!(sucrase)/)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;transform&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="s1"&gt;^.+&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;.(js|jsx|ts|tsx|mjs)$&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;babel-jest&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="c1"&gt;// ...the rest of your config&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, the two packages that were causing problems was &lt;code&gt;sucrase&lt;/code&gt;. In the config above, we are telling Jest to transform modules using &lt;code&gt;babel-jest&lt;/code&gt;, and to ignore everything in &lt;code&gt;node_modules&lt;/code&gt; folder &lt;strong&gt;except for&lt;/strong&gt; those two modules.&lt;/p&gt;

&lt;p&gt;In your case, it may be other modules that are causing the problem: replace &lt;code&gt;sucrase&lt;/code&gt; with the names of your module or, if more than one, each module's name separated by a &lt;code&gt;|&lt;/code&gt; (e.g. &lt;code&gt;(module-a|module-b)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.
&lt;/h3&gt;

&lt;p&gt;If a module is still causing problems, you'll need to take other measures. In my case, the solution above worked for &lt;code&gt;sucrase&lt;/code&gt; but not for &lt;a href="https://github.com/GoogleChromeLabs/browser-fs-access"&gt;browser-fs-access&lt;/a&gt;, another module that used ESM modules. I was able to fix the error by dynamically importing the module (e.g. &lt;code&gt;await import("browser-fs-access")&lt;/code&gt;) but still cannot test that part of my code. &lt;/p&gt;

&lt;p&gt;If you have a fix for that, I'd love to hear it!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
