Open Firionus opened 3 years ago
unit tests work find for commits in master and local, see "yarn test" in: https://github.com/ngduc/react-tabulator/blob/master/.github/workflows/node.js.yml
I think this error is from an older version "tabulator_tables_1.default is not a constructor", upgrade react-tabulator to the lastest version should fix it.
With the current release, I can still reproduce on another machine:
CI aside, can't you reproduce on your machine?
Yes, there is some issue when it runs in local, sometimes it fails to launch puppeteer and got stuck there. You may want to kill node processes and try to run the unit tests again. Updated here: https://github.com/ngduc/react-tabulator/blob/master/docs/development.md#unit-tests
Here we are, half a year later and with react-tabulator version 0.15.0, and I still see this issue, while writing Jest tests. Since half of my app depends on (react-)tabulator, I'm pretty much lost when it comes to writing tests for that part.
Is there any progress happening meanwhile? Or is a workaround available? Since I also had trouble with monaco-editor, I tried to apply the same trick, first to tabulator-tables then to react-tabulator:
"transformIgnorePatterns": [
"/node_modules/(?!monaco-editor)/",
"/node_modules/(?!react-tabulator)/"
],
"moduleNameMapper": {
"^monaco-editor$": "monaco-editor/esm/vs/editor/editor.api",
"^react-tabulator$": "react-tabulator/lib/index.js",
}
but that didn't help. Note: react-tabulator works without trouble in the application (many thanks for that, btw.!), just not in Jest tests.
Sorry about this intermittent puppeteer launching issue in local. I think upgrading to a newer version of puppeteer may help solve this one. If you could help upgrade it, it'd be great. I will try to do that also.
I'm pretty sure the issue I have is related to this and https://github.com/ngduc/react-tabulator/issues/204 so rather than write a new bug report, I'll just add my thoughts here.
I've been looking at adding a iOS app to our desktop webapp using the Meteor Cordova framework which essentially runs in a webview served over a local web server and I was seeing an error like Unhandled Promise Rejection: TypeError: undefined is not a constructor (evaluating 'new tabulator_tables_1["default"]')
from one of our components that used React-tabulator which was odd seeing as our desktop app using the same code was working fine.
Looking in the network tab in devtools I discovered that the only difference was in the way the tabulator-tables
dependency was being loaded. Specifically, desktop safari was loading {"module": "dist/js/tabulator.es2015.js"}
while in iOS safari, it was loading {"main": "dist/js/tabulator.js"}
in package.json
. Apparently, the package author added ESM support from 4.8.0 if you read the other GH issue I linked above.
But why was it loading different modules? To answer that question you have to understand that Meteor builds 2 separate bundles, one for modern web browsers called web.browser
and the other for older browser support called 'web.browser.legacy'. When building for mobile aka web.cordova
it's the same as the legacy build. So in desktop, it used the newer ESM module but in mobile, it was falling back to CJS.
So I tried forcing Cordova to use the ESM module by cloning the tabulator-tables
repo into my project to force Meteor to build it. I updated the main field in package.json
to point to tabulator.es2015.js
and lo and behold it worked. Ugly workaround but it worked.
Next I looked at why this error was occurring in the first place. Turns out, after much hair pulling that there's a bunch of interoperability issues with ESM and CJS modules. React-tabulator
uses ESM and when it tries to import tabulator.js
, ie. the CJS module from tabulator-tables
, it blows up.
The solution? TypeScript has the esModuleInterop
compiler option that smooths out default CJS imports, precisely what React-tabulator is doing:
Tested this out by running the repro in this issue and npm linking to a React-tabulator 0.15.0 rebuild:
// package.json
build: "npm run clean && tsc --esModuleInterop --outDir ./lib --jsx react --declaration ./src/index.ts && npm run postbuild"
I've created a npm fork @timiscoding/react-tabulator if anyone wants to test the fix. But ideally, you'll probably want to use patch-package so you don't have to update all your imports in the code base.
As you can see from the diff, the require('tabulator-tables')
import is now applied to __importDefault()
which falls back to creating an object with a default property to the module.
@timiscoding Thanks for working this out! I'd prefer, however, that @ngduc takes this in to the original react-tabulator node module. Would make things easier on my end.
In any case, I'm happy to see there's a solution.
@mike-lischke Of course, the best way would be to update the original package. Hoping to get confirmation that it indeed fixes it for others.
@timiscoding - I downloaded your fork today to see if it fixed the issues we were having with React unit tests failing. Indeed it did! Would be GREAT if this was incorporated into an update in the original package. Thank you for addressing the issue.
@timiscoding I also found the time finally to test your fork and also for me it worked. Many thanks!
However, I see a problem with mounting the underlying tabulator table in my componentDidMount
and componentDidUpdate()
methods (running from Jest tests). The table
field of my ref.current
is undefined in both cases, as if tabulator was never mounted.
I don't know if that's a specific problem of your fork or something that @ngduc should look at. Is it possible to "force" mounting the underlying tabulator when the ReactTabulator
is mounted?
@mike-lischke Good to hear it! Are you using react-test-renderer? Refs don’t work because it doesn’t mimic a full dom environment. So you have to mock the refs using ‘create NodeMock’ api https://reactjs.org/docs/test-renderer.html#ideas
https://github.com/facebook/react/issues/7740
The only change I made in the fork was in the build step so apart from that, the code would be functionally identical to 0.15.0
Thanks for the hint. Yes, I'm using react-test-render but also enzyme, where I can mount
components. But right, that doesn't mean they also have a DOM. Looks like I need to see what I can do with createNodeMock
or similar.
Doesn't belong to the discussion here, however. I hope your changes will be taken over to the main repo sooner than later. Have a good time!
I haven’t used enzyme in a while but could be related to incompatible adapters?
The current
member is set in my tests. What's missing is the current.table
, i.e. the underlying Tabulator instance is not yet created.
@timiscoding is it safe to use your package?
The only change is adding a ts compiler option in the build script and running it. I haven't used the original package since my last comment so I'd try the latest release to see if it has already fixed this issue.
https://github.com/timiscoding/react-tabulator/commit/0decbd201e4433dde19313a6fc4e169c36dba305
Title
TypeError: tabulator_tables_1.default is not a constructor
Environment Details
Long Description To reproduce:
npx create-react-app test_tabulator --template typescript
cd test_tabulator
npm i react-tabulator
npm test
Result:
Expected Result: No Warnings
Test can even be made to fail by making it async:
yielding the test result:
Unfortunately, the test works in Codesandbox (https://codesandbox.io/s/vr3in).
Workaround
No idea right now.
Related Issue https://github.com/ngduc/react-tabulator/issues/204
I tried
npm cache clean --force
, followed by deletingnode_modules
andnpm install
, butnpm test
still gives the same FAIL.