0

I'm trying to follow the Jest getting started guide but with ES6 Modules and Babel.My root folder has two javascript files sumfn.js and sum.test.js. My sum.test.js file looks like this:

import { sum } from 'sumfn';

test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3);
});

However it seems like Jest is having trouble resolving sumfn, even though it clearly does find the file sunfn.js.

  ● Test suite failed to run

    Cannot find module 'sumfn' from 'sum.test.js'

    However, Jest was able to find:
        './sumfn.js'

    You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

If I change the import line to use ./sumfn, it works. However, from what I read about ES6 imports, it seems like it should be able to find files in the same directory. Is this not supported in Jest perhaps?

woojoo666
  • 7,801
  • 7
  • 45
  • 57

2 Answers2

1

You need to add the ./ to tell JavaScript The module you're looking for can be found in the following file path, relative to the current file. So you need to add ./ to say Look for sumfn.js in the current directory.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
  • but in [this popular guide](https://24ways.org/2014/javascript-modules-the-es6-way/) it says "It’s also important to note that `from 'mymodule'` will look for a file called mymodule.js in the same directory as the file you are requesting the import from. There is no need to add the .js extension." – woojoo666 Apr 14 '19 at 08:35
  • also, if you look at the [react Jest guide](https://jestjs.io/docs/en/tutorial-react) it seems like they import from `react` without specifying a directory – woojoo666 Apr 14 '19 at 08:35
  • Yes, but JS is looking for `sumfn` as a module *in the current file*, **not** in the current directory, which is why you need the `./`. – Jack Bashford Apr 14 '19 at 08:37
  • again, the guide that I linked said it will look in the "same directory", not same file – woojoo666 Apr 14 '19 at 08:38
  • I found the answer, it seems like these "bare" specifiers aren't supported yet in browsers, but are supported in WebPack/BabelJS, albeit they follow a different convention, which is why it was so confusing. I posted the full details in a separate answer – woojoo666 Apr 14 '19 at 11:05
1

So one of the main reasons why I was confused is because there are a lot of out-dated ES6 module guides out there. In fact, many of the top results on Google seem to be outdated. I was looking at guides like this, this, and this, and they all said that you can import from a module name, without specifying the path, eg

import { double } from 'mymodule';

These are called "bare" import specifiers, and the guides said that it will by default search the current directory for a matching module. However, it seems like right now they are not supported in browsers.

Where it gets extremely confusing is that they are supported in BabelJS and Webpack, but it follows a different convention. For example, Webpack searches the paths specified in resolve.modules, which by default includes the node_modules folder. This is why the Create-React-App example can use statements like

import React from 'react';

It seems like the plan going forward is to let the environment determine how to resolve these "bare" specifiers (Source). Seems dangerous to let every environment resolve these specifiers differently, which could make it hard to make cross-compatible modules, but I guess that's the current plan for now.

woojoo666
  • 7,801
  • 7
  • 45
  • 57