rdkcentral / firebolt-apis

The Firebolt API OpenRPC schemas and SDK artifact configurations.
Apache License 2.0
13 stars 24 forks source link

SyntaxError: Unexpected token 'export' when running Jest #36

Open mrclapham opened 2 years ago

mrclapham commented 2 years ago

I am currently blocked developing a major Sky Q app. Please see the link below for a bare-bones example of the issue.

https://github.com/mrclapham/firebolt-issues/tree/master

The app needs to use the firebolt-sdk and I'm hitting severe problems when it comes to testing using Jest.

I'm using v0.6.1 of the SDK

Adding import { Metrics, Discovery } from "@firebolt-js/sdk"; makes every single test fail due to the .mjs imports.

I get:

    SyntaxError: Unexpected token 'export'

    > 1 | import { Metrics, Discovery } from "@firebolt-js/sdk";
        | 

I tried v0.6.0 – this compiled to .js not .mjs but caused a different issue, it threw an Error saying global had been declared twice.

The application builds correctly via WebPack and the functionality appears to work correctly from the console.logs.

Our app requires node >15 – I have tried higher version but had the same results.

I have tried every permutation, altering: jest.config; babel.config; version of Node; importing via absolute paths with the '.mjs' suffix, adding transformIgnorePatterns: ["/node_modules/(?!@firebolt-js/*)"] to the jest.config, you name it, nothing works.

Help appreciated as it is a major blocker.

mrclapham commented 2 years ago

I updated the bare bones repo and managed to get Jest to run but still remain blocked on out main App - even having updated the jest.config to reflect the changes (see below).

const config = { verbose: true, transformIgnorePatterns: ["/node_modules/(?!@firebolt-js/).*/"], transform: { "^.+\\.m?js$": "babel-jest" }, moduleFileExtensions: ["js", "mjs"], };

Is it not possible to export as regular umd so it imports like a regular node module, without jumping through hoops with elaborate tooling?

jlacivita commented 2 years ago

Firebolt uses Jest for unit tests as well.

I will take a look tomorrow and get back to you end of day.

mrclapham commented 2 years ago

Thanks @jlacivita. You may be fine on your codebase as you are working on your source-code, pre-compiled. The issue is trying to use the library after it is pulled from NPM and compiled at the client end. The hope would be it could be imported without jumping through any build-tooling hoops and complex configuration. As a rule libraries seem to go for Universal Module Definition (UMD) format that just import without any issues.

I managed to get my bare bones version building - applying it to the main app is more of a challenge – even though I tried the same parameters. We have a fairly involved setup with configs being pulled in from internal NPM packages.

jlacivita commented 2 years ago

Hi @mrclapham : It looks like sample repository is working now, so I'm not able to see the errors you're mentioning.

There'a couple things you'll need to do to use Jest w/ Firebolt:

  1. use 0.6.2, which fixes a weird Jest 26 issue:

Fixed incompatibility with Jest 26 due to jest/issues/10565

  1. We stopped using web pack for exporting our library in version 0.6.1 as you noted, but you'll need to use ES6 imports in your Jest tests. We do this by using:
node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.json --detectOpenHandles

and our jest.config.json has transform turned off:

{
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|js?|tsx?|ts?)$",
    "transform": {},
    "testPathIgnorePatterns": ["<rootDir>/build/", "<rootDir>/node_modules/"],
    "moduleFileExtensions": ["js", "jsx", "mjs"],
    "verbose": true
  }

If these don't work for you, could you give me more details on what you're seeing in your full project?

mrclapham commented 2 years ago

Thanks @jlacivita

I'm getting the same.

I upped to "@firebolt-js/sdk": "0.6.2".

I ran "node --experimental-vm-modules node_modules/jest/bin/jest.js --detectOpenHandles --config=jest.config.js"

What I get is:

Details:

    /Users/gclapham/Documents/APPS/cd-tv-client-discoveryplus/node_modules/@firebolt-js/sdk/dist/lib/firebolt.mjs:19
    export { default as Accessibility } from './Accessibility/index.mjs'
    ^^^^^^

    SyntaxError: Unexpected token 'export'

    > 1 | import { Metrics, Discovery } from "@firebolt-js/sdk";
        | ^ 

Here is the jest.config (the ui-library.config which it extends is below)

jest.config

const config = require("@discovery-dni/cd-tv-dev.jest/ui-library.config");

process.env.TZ = "GMT";

module.exports = {
  ...config,

  moduleFileExtensions: ["js", "jsx", "mjs"],
  modulePaths: ["<rootDir>"],
  moduleNameMapper: {
    // Mocking CSS modules to work with Webpack
    ...config.moduleNameMapper,
    "^@tve/organisms(.*)$": "<rootDir>/src/components/organisms$1",
    "^@tve/molecules(.*)$": "<rootDir>/src/components/molecules$1",
    "^@tve/atoms(.*)$": "<rootDir>/src/components/atoms$1"
  },
  testEnvironment: "jsdom",
  transformIgnorePatterns: [
    "/node_modules/(?!ramda)",
    "/node_modules/(?!@firebolt-js/).*/"
  ],
  roots: ["<rootDir>/src"],
  collectCoverageFrom: [
    "<rootDir>/src/**/*.js",
    "!<rootDir>/src/mocks/fixtures/**/index.js"
  ],
  coverageThreshold: {
    global: {
      branches: 15,
      functions: 15,
      lines: 25,
      statements: 25
    }
  },
  setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
  resetModules: true
};

@discovery-dni/cd-tv-dev.jest/ui-library.config

const path = require("path");

const config = {
  testEnvironment: "node",
  moduleFileExtensions: ["js", "json", "mjs"],
  moduleNameMapper: {
    // Mocking CSS modules to work with Webpack
    "\\.(css)$": path.resolve(__dirname, "./css-transform.js")
  },
  moduleDirectories: ["node_modules", "src"],
  transform: {
    "^.+\\.m?js$": path.resolve(__dirname, "./transformer-ui-library.js")
  },
  roots: ["<rootDir>/src", "<rootDir>/tests"],
  testMatch: ["**/?(*.)+(test).(js)"],
  collectCoverageFrom: ["<rootDir>/src/**/*.js"],
  coverageThreshold: {
    global: {
      branches: 20,
      functions: 30,
      lines: 30,
      statements: 30
    }
  },
  coverageDirectory: "coverage",
  coverageReporters: [["lcov", { projectRoot: "../" }], "text"],
  clearMocks: true,
  globals: {
    __DEV__: false
  }
};

module.exports = config;
jlacivita commented 2 years ago

It looks like you're still using babel transforms to run jest. I can't be sure, because I can't see @discovery-dni/cd-tv-dev.jest/ui-library.config.

You can read more about running jest in pure ES6 mode here: https://jestjs.io/docs/ecmascript-modules

mrclapham commented 2 years ago

I'm still in a world of misery and have lost best part of a week on this. I've had colleagues looking at this too – we're all senior devs – and no joy.

I do need to transform most of the code, if I set transform: {} I get an even longer litany of errors, possibly not on Firebolt but the tests take so long to run and throw so many errors I've not checked.

The way you have set this library up is demonstrably not working. The expectation of NPM packages is that you install and import them and they all work in the same way and require no special treatment, tooling, jumping through hoops and ideally, with production code, no reliance on experimental features.

I followed your link and it shows running on Jest requires using experimental, potentially buggy and not fully supported features.

I get the desire to not use WebPack or RollUp – JavaScript tooling is a pain - but you are passing the pain onto your end users.

This is a mature code-base I'm working on, currently tied to Node 14, and with established pipelines for testing and deployment. Every other NPM module we've added has dropped in without a hitch.

I will continue the trial and error trying to get the config planets to align but can't you just export as UMD like everyone else?

jlacivita commented 2 years ago

@mrclapham Wanted to let you know this is still on my radar. I'll get back to you tomorrow with more.

chiefcll commented 2 years ago

👋

I checked out your sample project and ran it with node 14.19.3

Screen Shot 2022-06-23 at 11 46 38 AM

I'm using a "fresh" laptop. Can you confirm your node version? Also check your parent path for any .babel files which maybe being included as well.

mrclapham commented 2 years ago

Hi @chiefcll

We are tied to Node 14 on this project. The project paths are all good - this is a mature and stable project - everthing works barring Firebolt.

I did get my bare bones project (the one you mention) to run - the problem is it only contains Firebolt so isn't the complex mass of code the main project is.

The problem I have is I'm trying to integrate Firebolt in an exiting project which is large and which has been worked on by a number of devs for a number of years. As ever with this kind of thing the tooling and dependencies have become increasingly complicated as it has been added to, with babel/webpack/jest/internal repos and dependencies etc evolving over the life of the project.

I'm now trying to rebuild the jest config from scratch - no mean feat as it pulls internal node modules which in turn pull other modules. I have no guarantee this will get me anywhere, but I'm blocked on this project pending a solution.

I'd just like to be able to add FireBolt as a dependency – just do...

yarn add @firebolt-js/sdk

import { Metrics, Discovery } from "@firebolt-js/sdk";

...and have it work, like every other NPM package that doesn't have me shaving the yak for weeks.

I see the appeal of getting rid of WebPack/Parcel/RollUp etc at your end and just importing modules from .mjs files. I often do it when I'm writing a PoC and don't want to set up all the tooling and, after the past week, I never want to see another .config file. The problem is you are shipping code that needs to be production ready, compatible with your end users. If it requires setting --experimental flags or any other non-standard setup it's a huge problem.

Please, bring back WebPack or RollUp and build a UMD file like all the other libraries on NPM so I can just import it, plug and play.

chiefcll commented 2 years ago

I've done a lot of Yak shaving myself and also like when things just work. I've spent my time setting up Jest as well and when things like this don't just work its frustrating.

1) You shouldn't need to use the experimental flag as of Node 13

2) It seems like you can build fine - jest does everything differently... What version of jest are you using in that project? Good thread for them getting support https://github.com/facebook/jest/issues/9430

mrclapham commented 2 years ago

I'm on Jest 26.6.3

jlacivita commented 2 years ago

@mrclapham :

I'm sure you're already trying the latest Firebolt, but just to be sure, please check.

We added a workaround for a Jest 26 bug in Firebolt 0.6.2.

Here's the bug we worked around: https://github.com/facebook/jest/issues/10565

I noticed that your sample project was using a newer version of Jest, so I didn't think to mention this.

Ideally if you could get the sample project updated to show the issue you're having by adding the conflicting config or code, or at least provide some error output, we'd be able to look more closely at the issue.

hungerregnuh commented 1 year ago

In case anyone stumbles upon this... this seemed to work for me

  "jest": {
    "preset": "jest-preset-angular",
    "extensionsToTreatAsEsm": [
      ".ts"
    ],
    "globals": {
      "ts-jest": {
        "useESM": true
      }
    },
    "setupFilesAfterEnv": [
      "./setup-jest.ts"
    ],
    "testEnvironment": "jsdom",
    "testPathIgnorePatterns": [
      "<rootDir>/e2e",
      "<rootDir>/node_modules",
      "<rootDir>/dist"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!tslib|rxjs)"
    ]
  }

and make sure to run jest with node --experimental-vm-modules $(yarn bin jest) if you're using yarn, if not use the node_modules path.

Tested with Jest v28.1.3

mpoisot commented 1 year ago

@mrclapham did you ever figure this out? I'm running into the same issue.