react-textarea-code-editor icon indicating copy to clipboard operation
react-textarea-code-editor copied to clipboard

Bug: Code Editor + Jest not working

Open activenode opened this issue 2 years ago • 15 comments

Hey! Thanks for this library.

The Code Editor does not work when using Jest. One reason is Jest not supporting import statements natively but what I am not understanding is that it should be using cjs - but it is not.

I created a down-to-earth, super-easy repository (it literally does nothing but importing your library and console.log). Just do npm i and run yarn jest to trigger jest.

https://github.com/activenode-bugs/uiw-react-textarea-code-editor-jest

You will see the error message of Cannot use import statement outside a module.

I googled this for hours and tried multiple things but maybe I'm overlooking something. It will always end up in trying to load unified from the rehype library with an import statement instead of going for a non-module approach.

What works (which is not a satisfying solution):

I've looked into your package folder which contains esm, cjs AND a dist folder. If you use jest with moduleNameMapper and then map @uiw/react-textarea-code-editor to @uiw/react-textarea-code-editor/dist/editor.js it will work / run.

moduleNameMapper: {
    // if you use the following, it will work
    // '@uiw/react-textarea-code-editor':
    //   '<rootDir>/node_modules/@uiw/react-textarea-code-editor/dist/editor.js',
  },

But the question is WHY? My first thought then is: Shouldn't your repo point main: "dist/editor.js" if this works seamlessly?

Which triggers my follow up question why there even is esm, cjs AND dist (can you clarify the differentiation?) and why does dist/editor.js work but cjs does not?

I feel like there is something weird going on which you can probably clarify as I am not as deep into this as you are :) Thank you so much in advance!

activenode avatar Apr 14 '22 10:04 activenode

You'll find easy reproduction steps in the README file of https://github.com/activenode-bugs/uiw-react-textarea-code-editor-jest

activenode avatar Apr 14 '22 10:04 activenode

@activenode

  • dist The ones in dist belong to UMD, UMD builds can be used directly in the browser via a
  • cjs CommonJS: CommonJS builds are intended for use with older bundlers like browserify or webpack 1. The default file for these bundlers (pkg.main) is the Runtime only CommonJS build
  • esm ES Module: ES module builds are intended for use with modern bundlers like webpack 2 or rollup. The default file for these bundlers (pkg.module) is the Runtime only ES Module build

jaywcjlove avatar Apr 14 '22 10:04 jaywcjlove

Thanks for clarifying the difference. Can you imagine why the error of import appears even though commonjs shouldn't lead to that? Like this is really confusing. I've tried it in at least 5 different setups, with and without TypeScript, with and without nextjs and it's always the exact same thing.

Once you are using your library anywhere with jest (no matter if just jest, babel-jest or ts-jest or both) it will always lead to this exact problem that you face when you run the related repo.

activenode avatar Apr 14 '22 10:04 activenode

The current repo test case is running fine, it has nothing to do with the library. This has a lot to do with build tools. @activenode

jaywcjlove avatar Apr 14 '22 10:04 jaywcjlove

I get that. But many people that use react also use jest. And since jest does not natively support ESM modules (only very experimental support) it leads to problems when it detects an import statement.

And now I'm trying to figure out why this only happens with this specific library. I tried it with react-simple-code-editor before and that one worked fine.

And I was expecting this one to work fine as well because your main says cjs/index.js so it should (and does) point to the cjs file. However then again it somehow tries to access (somewhere in between) rehype package which then contains a import statement and I'm really trying hard to grasp the underlying problem as it really only appears with this library.

activenode avatar Apr 14 '22 11:04 activenode

Okay so rehype package only contains ESM and that is why your library (which has rehype as dependency) will not work in this context as rehype doesn't have the cjs version apparently.

image

activenode avatar Apr 14 '22 11:04 activenode

The official documentation confirms that

image

https://www.npmjs.com/package/rehype#compatibility

Which implies your package essentially can only support ESM as it depends on rehype. Your CJS version essentially mixes with ESM

activenode avatar Apr 14 '22 11:04 activenode

So I can see 3 possible options here:

  1. Remove CJS support in your library (as it won't work together with rehype)
  2. Pre-compile rehype with the CJS version for the cjs dist
  3. Use a different package than rehype

If you choose option 1 that's completely fine, I just need the transparency so that I can switch back to our old react-simple-code-editor

Thank you so much!

activenode avatar Apr 14 '22 11:04 activenode

https://github.com/uiwjs/react-textarea-code-editor/blob/9288db6203a3ae07d4876e61bcefc81c0494bace/package.json#L56-L58

Can be used together, depending on the build tool and your code. Iteration takes a while and is not that aggressive at the moment.

@activenode

It has some ways to do compatibility.

image

jaywcjlove avatar Apr 14 '22 11:04 jaywcjlove

Thanks for the hints.

activenode avatar Apr 14 '22 11:04 activenode

https://github.com/jaywcjlove/markdown-to-html-cli

This is also a solution. jest test cases are separated from pkg.

@activenode

jaywcjlove avatar Apr 14 '22 11:04 jaywcjlove

Thank you, I will look into the suggestions.

activenode avatar Apr 14 '22 11:04 activenode

Hey @activenode which suggestion did you end up going with?

simon-v-swyftx avatar Oct 25 '22 05:10 simon-v-swyftx

@swyftx-simon Actually, since this turned to show more problems the more "workarounds" we tried to add , we had a large discussion and there are only 3 things I can recommend simply because of their convenience:

Try:

  • Switch on experimental ESM support in Jest (https://jestjs.io/docs/ecmascript-modules)
  • Switch to vitest which in many cases is super low effort because it's mainly compatible to Jest

Or else: We and the teams switched to vitest but also we switched to @codemirror as we experienced more and more problems we couldn't solve with this react-textarea-code-editor .

@codemirror is freaking good but it's documentation isn't that easy. Everything's an extension in the newest CodeMirror but feel free to ping me directly for further questions. We basically switched to CodeMirror and used the useCodeMirror hook as a basis.

activenode avatar Oct 25 '22 06:10 activenode

I managed to fix this issue by changing the import.

Instead of import CodeEditor from '@uiw/react-textarea-code-editor';

used: import CodeEditor from '@uiw/react-textarea-code-editor/esm';

CiprianDraghici avatar Nov 01 '23 15:11 CiprianDraghici