hyperformula icon indicating copy to clipboard operation
hyperformula copied to clipboard

[DO NOT MERGE!] Fix language files for Node+ESM

Open sequba opened this issue 1 year ago • 7 comments

Context

  • changed babel configuration to produce the ESM build with .mjs extensions and adjust the import and export statements in the output (custom babel plugin)
  • added exports property to package.json that 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" in tsconfig. 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 mjs files
  • [x] ESM in webpack v5 project
  • [x] ESM in webpack v5 project with Typescript -> Works, but requires special configuration ("moduleResolution": "node16" in tsconfig)
  • [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.

sequba avatar Feb 15 '24 14:02 sequba

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%

github-actions[bot] avatar Feb 15 '24 14:02 github-actions[bot]

  • 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 missing
ERROR 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.

sequba avatar Feb 29 '24 15:02 sequba

I have retested all the demos available on https://github.com/handsontable/hyperformula-demos/tree/import-demos image

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

magierg avatar Mar 27 '24 07:03 magierg

TODO: verify it with the code example in issue https://github.com/handsontable/hyperformula/issues/1143

sequba avatar Apr 12 '24 12:04 sequba

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.

sequba avatar Apr 25 '24 19:04 sequba

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

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1377   +/-   ##
========================================
  Coverage    97.36%   97.36%           
========================================
  Files          169      169           
  Lines        14421    14421           
  Branches      3021     3021           
========================================
  Hits         14041    14041           
  Misses         380      380           

codecov[bot] avatar Aug 07 '24 11:08 codecov[bot]

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.

sequba avatar Aug 08 '24 07:08 sequba