standard-things / esm

Tomorrow's ECMAScript modules today!
Other
5.27k stars 145 forks source link

Not working with Jasmine #887

Open Neutrino-Sunset opened 4 years ago

Neutrino-Sunset commented 4 years ago

I'm having troubel getting this to work with Jasmine. I have one large project that works in which I'm having unrelated issues with debugging. I'm attemtping to resolve those issues in a simpler test project and in that project I can't even get Jasmine to run tests in the ES modules.

node --version 12.18.0

jasmine version jasmine v3.6.1 jasmine-core v3.6.0

npm init npm install --save-dev jasmine npx jasmine init npm i esm

package.json

{
  "name": "vscodetesting2",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "type": "module",
  "scripts": {
    "test": "jasmine"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "jasmine": "^3.6.1"
  },
  "dependencies": {
    "esm": "^3.2.25"
  }
}

jasmine.json

{
  "spec_dir": "src",
  "spec_files": [
    "**/*[sS]pec.js"
  ],
  "helpers": [
    "helpers/**/*.js",
    "node_modules/esm"
  ],
  "stopSpecOnExpectationFailure": false,
  "random": true
}

test1.spec.js

import { HelloWorld } from './module1';

describe('test suite 1', function() {
   it('test2', function() {
      expect(HelloWorld()).toBe('Hello World');
   })
})

module1.js

export function HelloWorld() {
   return 'Hello World';
}

npm test


vscodetesting2@1.0.0 test C:\Home\Development\Workspaces\Scratch\VsCodeTesting2
jasmine

C:\Home\Development\Workspaces\Scratch\VsCodeTesting2\src\test1.spec.js:1 import { HelloWorld } from './module1'; ^^^^^^

SyntaxError: Cannot use import statement outside a module at wrapSafe (internal/modules/cjs/loader.js:1054:16) at Module._compile (internal/modules/cjs/loader.js:1102:27) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10) at Module.load (internal/modules/cjs/loader.js:986:32) at Function.Module._load (internal/modules/cjs/loader.js:879:14) at Module.require (internal/modules/cjs/loader.js:1026:19) at require (internal/modules/cjs/helpers.js:72:18) at C:\Home\Development\Workspaces\Scratch\VsCodeTesting2\node_modules\jasmine\lib\jasmine.js:89:5 at Array.forEach () at Jasmine.loadSpecs (C:\Home\Development\Workspaces\Scratch\VsCodeTesting2\node_modules\jasmine\lib\jasmine.js:88:18) npm ERR! Test failed. See above for more details.

Neutrino-Sunset commented 4 years ago

I have got to the bottom of the problem.

TLDR: Esm works with differently with Jasmine 3.5.0 than with 3.6.1

package.json

  "devDependencies": {
    "jasmine": "3.5.0"
  },

jasmine.json

{
  "spec_dir": "",
  "spec_files": [
    "src/**/*.spec.js"
  ],
  "helpers": [
    "helpers/**/*.js",
    "node_modules/esm"
  ],
  "stopSpecOnExpectationFailure": false,
  "random": true
}

The above config works with Jasmine 3.5.0, although one almighty gotcha (that took me weeks to notice) is that if in jasmine.json you have your paths configured like this

  "spec_dir": "src",
  "spec_files": [
    "**/*.spec.js"
  ],

...then it won't work at all and will fail with "export not valid in CommonJS module" type errors.

By 'works' I mean that 'import' can be used to import es6 modules into CommonJs modules.

However, update to Jasmine 3.6.1 and the above configuration doesn't work at all and always fails with import errors.

Using Jasmine 3.6.1 you can still import the esm require function directly and use it like this:

require = require("@std/esm")(module);
module.exports = require("./hi-web.mjs").default;

But that's messy, you'd either have to do it in every module or somehow install a helper to do it globally. However another approach that does work in Jasmine 3.6.1 is to configure Jasmine to import Esm on the commandline instead, e.g. in package.json

  "scripts": {
    "test": "jasmine --require=esm"
  },

With this configuration the import statement can again be used to import es6 modules into CommonJS modules. The "node_modules/esm" helper in jasmine.json is not required, and specifying a directory in the jasmine.json "spec_dir" also works.

This command line configuration also works in Jasmine 3.5.0 so it probably makes sense to use it exclusively.

I'll submit a patch to update the documentation in the near future, assuming there's still anyone around to accept a PR.