Skip to content

Commit

Permalink
Merge branch 'develop' into feature/issue-1300
Browse files Browse the repository at this point in the history
  • Loading branch information
sequba authored Nov 13, 2024
2 parents 012ce21 + c27a9d5 commit ed8c31e
Show file tree
Hide file tree
Showing 9 changed files with 634 additions and 14 deletions.
90 changes: 90 additions & 0 deletions .config/babel/add-import-extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Based on https://github.com/handsontable/handsontable/blob/bd7628544ff83d6e74a9cc949e2c3c38fef74d76/handsontable/.config/plugin/babel/add-import-extension.js

const { existsSync, lstatSync } = require('fs');
const { dirname, resolve } = require('path');
const { types } = require('@babel/core');
const { declare } = require('@babel/helper-plugin-utils');

const VALID_EXTENSIONS = ['js', 'mjs'];

const hasExtension = moduleName => VALID_EXTENSIONS.some(ext => moduleName.endsWith(`.${ext}`));
const isCoreJSPolyfill = moduleName => moduleName.startsWith('core-js');
const isLocalModule = moduleName => moduleName.startsWith('.');
const isProcessableModule = (moduleName) => {
return !hasExtension(moduleName) && (isCoreJSPolyfill(moduleName) || isLocalModule(moduleName));
};

const createVisitor = ({ declaration, origArgs, extension = 'js' }) => {
return (path, { file }) => {
const { node: { source, exportKind, importKind } } = path;
const { opts: { filename } } = file;
const isTypeOnly = exportKind === 'type' || importKind === 'type';

if (!source || isTypeOnly || !isProcessableModule(source.value)) {
return;
}

const { value: moduleName } = source;
const absoluteFilePath = resolve(dirname(filename), moduleName);
const finalExtension = isCoreJSPolyfill(moduleName) ? 'js' : extension;

let newModulePath;

// Resolves a case where "import" points to a module name which exists as a file and
// as a directory. For example in this case:
// ```
// import { registerPlugin } from 'plugins';
// ```
// and with this directory structure:
// |- editors
// |- plugins
// |- filters/
// |- ...
// +- index.js
// |- plugins.js
// |- ...
// +- index.js
//
// the plugin will rename import declaration to point to the `plugins.js` file.
if (existsSync(`${absoluteFilePath}.js`)) {
newModulePath = `${moduleName}.${finalExtension}`;

// In a case when the file doesn't exist and the module is a directory it will
// rename to `plugins/index.js`.
} else if (existsSync(absoluteFilePath) && lstatSync(absoluteFilePath).isDirectory()) {
newModulePath = `${moduleName}/index.${finalExtension}`;

// And for other cases it simply put the extension on the end of the module path
} else {
newModulePath = `${moduleName}.${finalExtension}`;
}

path.replaceWith(declaration(...origArgs(path), types.stringLiteral(newModulePath)));
};
};

module.exports = declare((api, options) => {
api.assertVersion(7);

return {
name: 'add-import-extension',
visitor: {
// It covers default and named imports
ImportDeclaration: createVisitor({
extension: options.extension,
declaration: types.importDeclaration,
origArgs: ({ node: { specifiers } }) => [specifiers],
}),
ExportNamedDeclaration: createVisitor({
extension: options.extension,
declaration: types.exportNamedDeclaration,
origArgs: ({ node: { declaration, specifiers } }) => [declaration, specifiers],
}),
ExportAllDeclaration: createVisitor({
extension: options.extension,
declaration: types.exportAllDeclaration,
origArgs: () => [],
}),
}
};
});
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Changed

- **Breaking change**: Change ES module build to use `mjs` files and `exports` property in `package.json` to make importing language files possible in Node environment. [#1344](https://github.com/handsontable/hyperformula/issues/1344)
- **Breaking change**: Removed the `binarySearchThreshold` configuration option. [#1439](https://github.com/handsontable/hyperformula/issues/1439)
- **Breaking change**: Changed the default value of the `precisionRounding` configuration option to `10`. [#1300](https://github.com/handsontable/hyperformula/issues/1300)

Expand Down
4 changes: 3 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ module.exports = {
},
// Environment for transpiling files to be compatible with ES Modules.
es: {
plugins: [],
plugins: [
['./.config/babel/add-import-extension.js', { extension: 'mjs' }],
],
},
},
};
3 changes: 2 additions & 1 deletion docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ module.exports = {
children: [
['/guide/release-notes', 'Release notes'],
['/guide/migration-from-0.6-to-1.0', 'Migrating from 0.6 to 1.0'],
['/guide/migration-from-1.0-to-2.0', 'Migrating from 1.x to 2.0'],
['/guide/migration-from-1.x-to-2.0', 'Migrating from 1.x to 2.0'],
['/guide/migration-from-2.x-to-3.0', 'Migrating from 2.x to 3.0'],
]
},
{
Expand Down
6 changes: 3 additions & 3 deletions docs/guide/localizing-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ register the language like so:

```javascript
// import the French language pack
import frFR from 'hyperformula/es/i18n/languages/frFR';
import frFR from 'hyperformula/i18n/languages/frFR';

// register the language
HyperFormula.registerLanguage('frFR', frFR);
```

::: tip
To import the language packs, use the module-system-specific dedicated bundles at:
* **ES**: `hyperformula/es/i18n/languages/`
* **CommonJS**: `hyperformula/commonjs/i18n/languages/`
* **ES**: `hyperformula/i18n/languages/`
* **CommonJS**: `hyperformula/i18n/languages/`
* **UMD**: `hyperformula/dist/languages/`

For the UMD build, the languages are accessible through `HyperFormula.languages`, e.g., `HyperFormula.languages.frFR`.
Expand Down
File renamed without changes.
78 changes: 78 additions & 0 deletions docs/guide/migration-from-2.x-to-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,84 @@

To upgrade your HyperFormula version from 2.x.x to 3.0.0, follow this guide.

## Importing language files

We changed the way of importing language files in ES module system to a more modern way using `mjs` files and `exports` property. This change is required to make HyperFormula compatible with newer ESM configurations in Node and browser environments.

The previous import paths became deprecated. For most environments they still work in version 3.0.0, but it will be removed in the future. To avoid any issues, update your code to use the new paths.

### New import paths for ES and CommonJS module systems

For ES and CommonJS modules, use the path `hyperformula/i18n/languages`, to import the language files. E.g.:

```javascript
import { frFR } from "hyperformula/i18n/languages"; // ESM

const { frFR } = require('hyperformula/i18n/languages'); // CommonJS
```
If you use the UMD module system, you don't need to change anything.

### Additional steps for projects using Angular

1. Make sure you use Typescript 5 or newer
2. In your `tsconfig.json`, set:

```
"moduleResolution": "bundler",
```

### Additional steps for projects using Typescript

In your `tsconfig.json`, set:

```
"module": "node16",
"moduleResolution": "node16",
```

### Additional steps for projects using Webpack 4 or older

1. In your code, use the legacy paths for importing language files. Unfortunately, Webpack 4 does not support `exports` property. E.g.:

```javascript
import { frFR } from "hyperformula/es/i18n/languages";
```

2. In your `webpack.config.js`, add the following configuration to handle `.mjs` files properly:

```javascript
module: {
rules: [
{
test: /\.m?js$/,
include: /node_modules/,
type: "javascript/auto",
},
],
}
```

### Additional steps for projects using Parcel

1. Make sure you use Parcel 2.9 or newer. Older versions of Parcel do not support `exports` property.
2. In your `package.json`, add the [following configuration](https://parceljs.org/blog/v2-9-0/#new-resolver):

```
"@parcel/resolver-default": {
"packageExports": true
}
```

If you don't want to upgrade Parcel, you can keep using the legacy import paths for language files, but they will be removed in one of the upcoming releases. E.g.:

```javascript
import { frFR } from "hyperformula/es/i18n/languages";
```

### Other projects

We tested the changes with the most popular bundlers and frameworks. If you use a different configuration, and you encounter any issues, please contact us via GitHub. We will try to make it work for you, although for older versions of bundlers and frameworks, it might be impossible.

## Removal of the `binarySearchThreshold` configuration option (deprecated since version 1.1.0)

The `binarySearchThreshold` has no effect since version 1.1.0. If your codebase still uses this option, please remove it.
Expand Down
Loading

0 comments on commit ed8c31e

Please sign in to comment.