glennsl/rescript-jest

Problem with es6 modules

ZielonyBuszmen opened this issue ยท 10 comments

Hi!
I have small problem with bs-jest.

In my bsconfig.json I have es6 modules:

  "package-specs": {
    "module": "es6",
    "in-source": true
  },

When I run tests, it gives me the error like below:

$ jest
 FAIL  __tests__/Template_test.bs.js
  โ— Test suite failed to run

    ....../node_modules/@glennsl/bs-jest/src/jest.js:3
    import * as List from "bs-platform/lib/es6/list.js";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | // Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
      2 | 
    > 3 | import * as Jest from "@glennsl/bs-jest/src/jest.js";
        | ^
      4 | 
      5 | Jest.describe("TestSuite", (function (param) {
      6 |         return Jest.test("test", (function (param) {

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at Object.<anonymous> (__tests__/Template_test.bs.js:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.468s, estimated 2s
Ran all test suites.

When I change module to commonjs, everything starts working. (I can't do this permamently, because I have own bindings, that not compatible with commonjs)

I'm pretty sure this is an issue with jest in general. You might find some useful information at jestjs/jest#6229 or jestjs/jest#2081

I know I've encountered similar issues before, but I can't remember exactly what the issue was or how I solved it. Sorry I can't be of more help, but if you do figure it out, please add a comment of it here so we get a record of how to fix it.

ijcd commented

I hit this and took awhile to sort it out. The solution presented by @jchavarri presented here (https://reasonml.chat/t/bs-jest-or-vanilla-jest/1608/13) is what helped.

There's a demo repo here: (https://github.com/jchavarri/example-bsb-jest-es6)

The key parts are the babel.config.js and package.json fragments and the usage of babel-plugin-transform-es2015-modules-commonjs:

babel.config.js

+module.exports = {
+  env: {
+    test: {
+      plugins: ["transform-es2015-modules-commonjs"]
+    }
+  }
+};

package.json

+"jest": {
+  "transformIgnorePatterns": [
+    "/node_modules/(?!@glennsl/bs-jest|bs-platform).+\\.js$"
+  ]
+}

You may want to mention this in the README.md -- I had a hard time finding this issue.

ijcd commented

And, actually, I encountered a some issues with that setup. The one in bs-enzyme seems to cover more cases: (https://github.com/rhysforyou/bs-enzyme)

jest.config.js

module.exports = {
  testMatch: [
    "**/src/**/*_test.js"
  ],
  moduleFileExtensions: ['js'],
  transform: {
    '^.+\\.js$': './jest-transform.js',
  },
  transformIgnorePatterns: [
    // transform ES6 modules generated by BuckleScript
    // https://regexr.com/46984
    '/node_modules/(?!(@.*/)?(bs-.*|reason-.*)/).+\\.js$',
  ],
};

jest-transform.js

module.exports = require('babel-jest').createTransformer({
  presets: [
    ['@babel/preset-env', {
      modules: 'cjs',
      targets: {
        node: 11,
      }
    }]
  ],
});

@ijcd so you ended up using the latter setup?

I've been having to use commonjs in order to have everything working fine. I'm thinking about trying out your approach. Although seems like you are still finding easter eggs

"package-specs": [
    {
      "module": "commonjs",
      "in-source": true
    }
  ],```

You may want to mention this in the README.md -- I had a hard time finding this issue.

Sure. I'm definitely open for a PR!

ijcd commented

@vasco3 Yes, I'm using the second setup now. I'm not sure what the issue with the first one was, but the second seems more direct and obvious. The first is trying to avoid depending on babel (I think) but my project is using it anyway.

This worked for me.

npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
// babel.config.js
module.exports = {
  env: {
    test: {
      plugins: ["transform-es2015-modules-commonjs"],
    },
  },
};
// package.json
"jest": {
    "transformIgnorePatterns": [
      "/node_modules/(?!@glennsl/bs-jest|bs-platform|@rescript).+\\.js$"
    ]
  }

Now I only test functions in files that don't contain React components. That stopped the import bug from showing up.

This worked for me.

npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
// babel.config.js
module.exports = {
  env: {
    test: {
      plugins: ["transform-es2015-modules-commonjs"],
    },
  },
};
// package.json
"jest": {
    "transformIgnorePatterns": [
      "/node_modules/(?!@glennsl/bs-jest|bs-platform).+\\.js$"
    ]
  }

Just want to note that this still works but for the latest version of rescript you have to add @rescript to the regex like so:

"/node_modules/(?!@glennsl/bs-jest|bs-platform|@rescript).+\\.js$"

So far, I am having good luck with using the jest instructions for enabling esm in node, combined with setting appropriate babel jest settings in jest config. I will return and document the details once the dust has settled.