Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transformer.js must export a "process" function - jester v2.0.1 jest 27 #65

Closed
kevpye-fabdata opened this issue Aug 12, 2021 · 33 comments
Closed

Comments

@kevpye-fabdata
Copy link

kevpye-fabdata commented Aug 12, 2021

Hey guys,

I just updated to the new jester version - 2.0.1 and jest 27 and all tests are now failing with the following error:

Jest: synchronous transformer ......\node_modules\svelte-jester\src\transformer.js must export a "process" function.

      at invariant (node_modules/@jest/transform/build/ScriptTransformer.js:1092:11)
      at assertSyncTransformer (node_modules/@jest/transform/build/ScriptTransformer.js:1098:3)
      at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:611:7)
      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:758:40)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:815:19)

Here is a sample test - just rendering a static page

import '@testing-library/jest-dom/extend-expect';
import { render, screen } from '@testing-library/svelte';
import Demo from './demo.svelte';

describe('Demo page test', () => {
	test('shows proper heading when rendered', async () => {
		render(Demo);
		expect(screen.getByText('DEMO PAGE')).toBeInTheDocument();
	});
});

I'm running node LTS 14.17.0.

Any ideas?

Thanks

@micschwarz
Copy link

You have to use jest with es modules. Which brings its own challanges, especially with external dependencies

@kevpye-fabdata
Copy link
Author

kevpye-fabdata commented Aug 12, 2021

Thanks for the reply @micschwarz . This is not written anywhere on the current readme - unless i'm going blind. I think this should be made clearer as its a pretty major change not to be mentioned at all in the current documentation. However, even after changing jest to use es modules as per the jest documentation I still get the same problem regarding the synchronous transformer.

The jest documentation says to disable code transforms by passing transform: {} or otherwise configure your transformer to emit ESM. The current documentation instructs us to use

"transform": {
    "^.+\\.svelte$": [
         "svelte-jester",
	{
		"preprocess": true
	}
    ]
}

I am using typescript, and thus ts-jest, so I changed my preset to "preset": "ts-jest/presets/default-esm" to configure the transformer to emit esm. I have tried leaving the transform as shown above and in the readme, I have tried setting the transform to the jest suggestion of transform: {} but I get the same error either way.

I can tell node is running in experimental mode as I get the warnings " ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time" in my console when executing.

Here is my full jest setup following the jest suggestions to enable ESM - as I mentioned I also tested with the transform: {} shown above with the same results

"jest": {
		"preset": "ts-jest/presets/default-esm",
                "globals": {
			"ts-jest": {
				"useESM": true
			}
		},
		"moduleNameMapper": {
			"\\$lib\\/(.*)$": "<rootDir>/src/lib/$1"
		},
		"transform": {
			"^.+\\.svelte$": [
				"svelte-jester",
				{
					"preprocess": true
				}
			]
		},
		"moduleFileExtensions": [
			"js",
			"ts",
			"svelte"
		],
		"setupFilesAfterEnv": [
			"@testing-library/jest-dom/extend-expect"
		]
	}

@sebastianrothe
Copy link
Collaborator

Quick response: have a look over here #59 (comment)

You need to tell ts-node to not transform your jest.config.ts config, which is really weird btw.

@micschwarz
Copy link

micschwarz commented Aug 13, 2021

TLDR:
Put this in your tsconfig.json

  "ts-node": {
    "moduleTypes": {
      "jest.config.ts": "cjs"
    },
    "transpileOnly": true
  }

@micschwarz
Copy link

micschwarz commented Aug 13, 2021

Is there any chance to get this running without experimental vm modules? Using experimental flags for professional projects is not that great. And jests automock does not work with esm.
In addition some imports don't work.

import {Dropdown} from 'bootstrap'; does not work, as jest with node expects something like import bootstrap from 'bootstrap';, but that is not working for rollup.

Edit: import * as bootstrap from 'bootstrap'; works. But you have to think about it and not let the IDE just import it

@kevpye-fabdata
Copy link
Author

kevpye-fabdata commented Aug 13, 2021

TLDR:
Put this in your tsconfig.json

  "ts-node": {
    "moduleTypes": {
      "jest.config.ts": "cjs"
    },
    "transpileOnly": true
  }

Thanks guys but i'm not using a jest.config.ts file. My jest config is in my package.json..... Of course I could create one and move the config but I shouldn't be forced to. I',m also not using ts-node, just ts-jest. I feel like this project should not have switched to using ESM at this point. I was previously having the issue with import.meta not being supported - due to jest26 - which is why I upgraded but that issue only existed in one file so I was happy to mock it for testing. This new version seems like we are having to jump through all sorts of hoops and still failing. Plus as @micschwarz pointed out using experimental flags for production projects is not great.

Working with Sveltekit has been awesome so far with the exception of testing support. I know Sveltekit is still pre 1.0 software so its going to have gaps and issues but getting this setup is by far the biggest problem so far.

@sebastianrothe
Copy link
Collaborator

sebastianrothe commented Aug 13, 2021

Yes, the switch to esm was more problematic then we thought. We are going to change the versioning again and offer ESM support in a version next. We will support async and commonjs with version 2.x. See #61

Nevertheless, esm support is not happening without the experimental flag. This is also enforced by jest itself.

You can have the same config in your package.json.

Also, ts-Node is implicit, if you use typescript and jest.

@kevpye-fabdata
Copy link
Author

@sebastianrothe thanks for the info. I'm fairly new to typescript so didn't realize ts-node was implicit. I think offering a next version for testing ESM is a good move. Do you have a timeframe as to when the next release will come that will revert back to the old CJS way but with support for jest 27? Just wondering if I should revert back to jest 26 the old 1.x version for the time being if its going to take a while? Thanks again for the support

@sebastianrothe
Copy link
Collaborator

@sebastianrothe thanks for the info. I'm fairly new to typescript so didn't realize ts-node was implicit. I think offering a next version for testing ESM is a good move. Do you have a timeframe as to when the next release will come that will revert back to the old CJS way but with support for jest 27? Just wondering if I should revert back to jest 26 the old 1.x version for the time being if its going to take a while? Thanks again for the support

I'll try to find some time next week.

@jakobrosenberg
Copy link

@kevpye-fabdata have you tried

npm i -D svelte-jester@1.8.2 --force

That works for me with Jest 27.

@kevpye-fabdata
Copy link
Author

@kevpye-fabdata have you tried

npm i -D svelte-jester@1.8.2 --force

That works for me with Jest 27.

I tested this and it gives me several warnings on install - which is not surprising as the dependency versions do not match between this and ts-jest

npm WARN ERESOLVE overriding peer dependency
npm WARN Found: jest@27.0.6
npm WARN node_modules/jest
npm WARN   peer jest@"^27.0.0" from ts-jest@27.0.4
npm WARN   node_modules/ts-jest
npm WARN     dev ts-jest@"^27.0" from the root project
npm WARN   1 more (the root project)
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer jest@"<= 26" from svelte-jester@1.8.2
npm WARN node_modules/svelte-jester
npm WARN   dev svelte-jester@"1.8.2" from the root project

But it does seem to work when I run my tests so I will leave it for now and update this once the next version is out. As the 2.x version that @sebastianrothe is going to try and work on this week will revert back to CJS I still had to go back to mocking my app settings file that uses the import meta syntax as it seems that is only supported for ESM imports with jest without doing some other trickery with babel. For me it was much simpler to simply mock my settings file using a setuptests file and adding it setupFilesAfterEnv setting in package.json.

@GHesericsu
Copy link

I resolved this issue by downgrading svelte-jester to 1.8.2 and added jsdom.

@peterczg
Copy link

It seems that the newest version of the svelte-jester is not compatible with jest library for the lack of process function, by degrading svelte-jester and adding jsdom, everything will works fine. @GHesericsu Thank you for the suggestion.

@Dan1ve
Copy link

Dan1ve commented Aug 26, 2021

Downgrading to 1.8.2 helped for me, too. In addition, I had to also downgrade jest and ts-jest to version 26.x.x to have my tests passing again.

@benmccann
Copy link
Collaborator

2.1.0 is out now with the CJS build. Is this fixed as a result?

@peterczg
Copy link

Downgrading to 1.8.2 helped for me, too. In addition, I had to also downgrade jest and ts-jest to version 26.x.x to have my tests passing again.

perhaps there are some incompatible apis between the versions.

@TeemuKoivisto
Copy link

Hey what's happening? I upgraded to 2.1.0 from the 2.0.something which threw that weird process error. Yet now I get even more serious looking error:

Module svelte-jester in the transform option was not found.
         <rootDir> is: xxx

Going into the node_modules/svelte-jester folder and looking at the package.json I see:

  "main": "src/transformer.cjs",
  "module": "src/transformer.mjs",

Yet inside the folder there is only dist folder. Did you guys forget to update the paths?

@kevpye-fabdata
Copy link
Author

I haven't had a chance to test 2.1.0 yet in my project. I will try to look at it early next week and will report if I see the same problem as @TeemuKoivisto

@benmccann
Copy link
Collaborator

Doh! Thanks for pointing that out. That should have been updated. PR here: #69. If you change the package.json in node_modules/svelte-jester manually does it fix it for you?

@TeemuKoivisto
Copy link

@benmccann Hey, good to hear. Updating the paths to dist fixes it but it still throws the process error.

/node_modules/svelte-jester/dist/transformer.cjs must export a "process" function.

I wonder what's up with that.

@benmccann

This comment has been minimized.

@TeemuKoivisto

This comment has been minimized.

@benmccann
Copy link
Collaborator

Hmm. It looks like you can't use processAsync with CJS jestjs/jest#11458. I guess we'd have to restore all the old code from before #57 if we want to support CJS

Maybe transpiling isn't the way to go then and we'd be better off including two separate code bases for CJS and for ESM where CJS uses process and ESM uses processAsyn. It might result in some duplication, but this is a small enough library that maybe that's okay

@TeemuKoivisto
Copy link

Not sure if it's a problem with CJS per se. I am importing the mjs file and removed my commonjs plugin as well as changed the module in my tsconfig to es2020 to no avail. It just seems that Jest it not playing well with the async processing. Granted this whole thing is quite messy so I'm not sure exactly what causes what. Having sync version in the cjs file would seem reasonable as otherwise I'm forced to downgrade 👍.

@benmccann
Copy link
Collaborator

@TeemuKoivisto would you be able to share a reproduction?

@benmccann
Copy link
Collaborator

2.1.1 is out now which fixes the file paths in package.json

@TeemuKoivisto
Copy link

@TeemuKoivisto would you be able to share a reproduction?

Ahh. Well. I must say I can't put too much effort into this but here's a library https://github.com/teemukoivisto/svelte-tree-view I've been working on and just made public. It's kinda ready just missing tests, hence I'm here posting.

So to reproduce what I've been doing you'd have to clone it, then yarn to install deps, go to the node_modules/svelte-jester and change the package.json paths to dist instead of src. Or just install that new version you published.

After that, go to core folder and try yarn test and you should receive the error. I have tried various combinations of things with that setup, mainly changing the file in the svelte-jester main block to include only the mjs file, removing the commonjs plugin and changing the tsconfig's modules to es2020 and also adding "type": "module" to the core/package.json (and doing a fresh yarn install) yet nothing seems to change the error. It does seem jest tries to load the cjs file in the main block but switching to mjs doesn't seem to have effect.

Anyway, don't know much else. I'll use the 1.8 version for now and make some tests.

@brianbancroft
Copy link

brianbancroft commented Sep 1, 2021

Hi there, I'm relatively new to svelte, and I've been running head-first into this problem for the past couple of days. If you want to reproduce this error, one way is to make a new scaffolded svelte app with TS support according to the svelte pages, then to follow this tutorial: (https://web.archive.org/web/20210127075453/https://timdeschryver.dev/blog/how-to-test-svelte-components). I've archived it just in case the author edits.

image

The tutorial doesn't suggest specific versions of any library, but rather the latest.

@gyurielf
Copy link

gyurielf commented Sep 3, 2021

@benmccann > 2.1.1 is out now which fixes the file paths in package.json

I still got the same error :(

@benmccann
Copy link
Collaborator

Here's instructions to make it work in ESM mode: rossyman/svelte-add-jest#19 (comment)

@jacobbogers
Copy link

jacobbogers commented Sep 6, 2021

Hello you all,

In the Jest documentation (to write custom transformers) it is stated that (quote) "...As can be seen, only process is mandatory to implement..." read here in jestdoc

Also looking at the typescript decl (same page), it is the only mandatory member function in interface SyncTransformer

PS: in interface AsyncTransformer it is processAsync is mandatory and all others are optional

interface SyncTransformer<OptionType = unknown> {

  canInstrument?: boolean;  //OPTIONAL
  createTransformer?: (options?: OptionType) => SyncTransformer<OptionType>; //OPTIONAL

  getCacheKey?: ...  //OPTIONAL

  getCacheKeyAsync?: ... //OPTIONAL

  process: (      //MANDATORY
    sourceText: string,
    sourcePath: Config.Path,
    options: TransformOptions<OptionType>,
  ) => TransformedSource;

  processAsync?...  //(OPTIONAL)
}

@benmccann
Copy link
Collaborator

process was added back in 2.1.2

@rmunn
Copy link

rmunn commented Sep 13, 2021

Looks like the 2.1.2 change may have a regression: #74.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests