[DO NOT MERGE!] Fix language files for Node+ESM
Context
- changed babel configuration to produce the ESM build with
.mjsextensions and adjust the import and export statements in the output (custom babel plugin) - added
exportsproperty topackage.jsonthat lists all valid ways of importing HyperFormula
Breaking change
This will be a breaking change for devs that use Webpack 4 or Parcel
Webpack 4 projects
Will need to configure babel-loader for mjs files
{
test: /\.m?js$/,
include: /node_modules/,
type: "javascript/auto",
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
configFile: path.resolve(ROOT_DIRECTORY, 'config/babel.config.js'),
},
},
},
Parcel projects
Will need to update parcel to v2.9 or newer and configure:
"@parcel/resolver-default": {
"packageExports": true
}
TODO
- [ ] add migration guide
- [ ] validate by publint
- [ ] test with https://arethetypeswrong.github.io/
- [ ] CR
- [ ] QA approval by @magierg
How did you test your changes?
Tested importing HF in scenarios:
- [x] ESM in node project
- [x] ESM in react project (with Typescript)
- [x] ESM in angular project -> works but only with Typescript 5 and
"moduleResolution": "bundler"intsconfig. Doesn't work with Typescipt 4 - [x] ESM in webpack v4 project -> Works but only with legacy paths. Webpack 4 does not support "exports". And requires special configuration for handling
mjsfiles - [x] ESM in webpack v5 project
- [x] ESM in webpack v5 project with Typescript -> Works, but requires special configuration (
"moduleResolution": "node16"intsconfig) - [x] ESM in parcel v2.11 project -> parcel does not support "exports" by default, since v2.9 it can be configured to support it
- [x] CJS in node project
- [x] CJS in parcel v2.11 project
- [x] UMD in browser
Demo projects are available in the hyperformula-demos repo.
Tested by @budnix:
Vite ^5.1.4 - OK Parcel2 ^2.0.0 - Does not support "exports" so the language file has to be imported with /es/ or /commonjs/ prefixes; Webpack5 ^5.8.0 - OK Webpack4 ^4.42.0 - I getting an error. Seems the webpack has the problem with importing values from "chevrotain".
Types of changes
- [x] Breaking change (a fix or a feature because of which an existing functionality doesn't work as expected anymore)
- [x] New feature or improvement (a non-breaking change that adds functionality)
- [x] Bug fix (a non-breaking change that fixes an issue)
- [ ] Additional language file, or a change to an existing language file (translations)
- [ ] Change to the documentation
Related issues:
Fixes #1344
Checklist:
- [x] I have reviewed the guidelines about Contributing to HyperFormula and I confirm that my code follows the code style of this project.
- [ ] I have signed the Contributor License Agreement.
- [x] My change is compliant with the OpenDocument standard.
- [x] My change is compatible with Microsoft Excel.
- [x] My change is compatible with Google Sheets.
- [x] I described my changes in the CHANGELOG.md file.
- [ ] My changes require a documentation update.
- [x] My changes require a migration guide.
Performance comparison of head (b3090446dac7330a5c5ed4c6b0ec5909414ad1f1) vs base (67bae9e8d22054aa3617910e4f353141efb553f5)
testName | base | head | change
------------------------------------------------------------------------
Sheet A | 513.39 | 513.49 | +0.02%
Sheet B | 163.46 | 163.71 | +0.15%
Sheet T | 146.86 | 143.44 | -2.33%
Column ranges | 511.78 | 512.37 | +0.12%
Sheet A: change value, add/remove row/column | 15.21 | 14.5 | -4.67%
Sheet B: change value, add/remove row/column | 137.39 | 132.18 | -3.79%
Column ranges - add column | 154.29 | 151.63 | -1.72%
Column ranges - without batch | 445.7 | 448.58 | +0.65%
Column ranges - batch | 111.53 | 116.86 | +4.78%
- Webpack4 ^4.42.0 - I getting an error. Seems the webpack has the problem with importing values from "chevrotain".
// /node_modules/hyperformula/es/parser/FormulaParser.mjs import { EmbeddedActionsParser, EMPTY_ALT, Lexer, tokenMatcher } from 'chevrotain'; // EmbeddedActionsParser, EMPTY_ALT and others are missingERROR in ./node_modules/hyperformula/es/parser/FormulaParser.mjs 689:125-137 Can't import the named export 'tokenMatcher' from non EcmaScript module (only default export is available) @ ./node_modules/hyperformula/es/parser/index.mjs @ ./node_modules/hyperformula/es/ArraySize.mjs @ ./node_modules/hyperformula/es/index.mjs @ ./src/index.js ERROR in ./node_modules/hyperformula/es/parser/FormulaParser.mjs 708:29-41 Can't import the named export 'tokenMatcher' from non EcmaScript module (only default export is available) @ ./node_modules/hyperformula/es/parser/index.mjs @ ./node_modules/hyperformula/es/ArraySize.mjs @ ./node_modules/hyperformula/es/index.mjs @ ./src/index.js
I found out that webpack 4 does not support exports, and there seems to be no easy workaround for that. By tweaking the webpack configuration, I managed to make the project import HyperFormula correctly using the legacy paths. Working demo.
I have retested all the demos available on https://github.com/handsontable/hyperformula-demos/tree/import-demos
plus the bundlers mentioned by @budnix getting the same results.
On top of the above I have tested:
- Webpack 5.9 + TS - tsconfig.js setting change required:
"module": "node16",
"moduleResolution": "node16",
- React 18^ + TS - same tsconfig.js change required
- Angular 16.0.2 + TS 4.4.3 - @sequba to investigate tsconfig changes required
- Angular 17.3.1 + TS 5.2 - same issue with TS
- Svelte 3.5.4 + vite 4 - getting this error - might be user error - @sequba to investigate
Error: Language already registered.
at HyperFormula.registerLanguage (/Users/magierg/repos/hyperformula-demos/svelte-demo/node_modules/hyperformula/commonjs/HyperFormula.js:287:13)
at Hyperformula.svelte:18:15
at Object.$$render (/node_modules/svelte/internal/index.mjs:1892:22)
at eval (/src/routes/+page.svelte:24:148)
at Object.$$render (/node_modules/svelte/internal/index.mjs:1892:22)
at Object.default (root.svelte:41:38)
at eval (/node_modules/@sveltejs/kit/src/runtime/components/layout.svelte:8:41)
at Object.$$render (/node_modules/svelte/internal/index.mjs:1892:22)
at root.svelte:40:37
at $$render (/node_modules/svelte/internal/index.mjs:1892:22)
- Vue 3.3.4 + vite 4.4.9 - OK
TODO: verify it with the code example in issue https://github.com/handsontable/hyperformula/issues/1143
Svelte 3.5.4 + vite 4 - getting this error - might be user error - @sequba to investigate
It works correctly. The issue you reported was caused by running the setup code twice. I created a demo for svelte: https://github.com/handsontable/hyperformula-demos/tree/import-demos/import-demo-esm-svelte
Angular case is still to be verified.
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 97.36%. Comparing base (
e32e132) to head (0cd4e05). Report is 33 commits behind head on develop.
Additional details and impacted files
@@ Coverage Diff @@
## develop #1377 +/- ##
========================================
Coverage 97.36% 97.36%
========================================
Files 169 169
Lines 14421 14421
Branches 3021 3021
========================================
Hits 14041 14041
Misses 380 380
Angular 16.0.2 + TS 4.4.3 - @sequba to investigate tsconfig changes required Angular 17.3.1 + TS 5.2 - same issue with TS
Angular issue can be resolved by setting "moduleResolution": "bundler" in tsconfig.json. Tested with Angular 16, 17 and 18 and Typescript 5. Demo
Unfortunately, I couldn't make combination Angular + Typescript 4 work. I'm afraid we need to ask our clients to upgrade to Typescript 5 if they want to use HyperFormula 3.x with Angular.