Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix language files for Node+ESM #1377

Merged
merged 26 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
636ccaa
Add babel script add-import-extension
sequba Feb 15, 2024
c09c336
Adjust check-publish-package script to new way of building ES
sequba Feb 15, 2024
1ba6009
Make babel output ES build with mjs extensions
sequba Feb 15, 2024
2dc845f
Add exports property to package.json
sequba Feb 15, 2024
bdbc35e
Fix the exports property
sequba Feb 15, 2024
fe9f96e
Tweaking package.json exports for cjs modules
sequba Feb 21, 2024
d25db4e
Adjust package.json exports for individual language files in CJS
sequba Feb 21, 2024
1962234
Add info about the source of the add-import-extension babel script
sequba Feb 21, 2024
4bf3f07
Add changelog entry
sequba Feb 21, 2024
36b997e
Move types key to be the first key in JSON object (exports property)
sequba Feb 22, 2024
5348bf7
Fix publint suggestions
sequba Feb 22, 2024
bccb945
Add paths ./i18n/languages/xxXX to exports property in package.json
sequba Feb 28, 2024
8a6d108
Use path ./i18n/languages/xxXX to import languages in the docs
sequba Feb 28, 2024
0cd4e05
Add paths with .js extensions to exports in package.json
sequba Feb 28, 2024
b309044
Merge branch 'develop' of github.com:handsontable/hyperformula into f…
sequba Aug 7, 2024
6f32832
Add migration guide for 3.0
sequba Aug 7, 2024
89159a5
Working on the migration guide
sequba Sep 5, 2024
3c29512
Unpolished vershion of the migration guide
sequba Oct 29, 2024
4c3d108
Upgrade migration instructions for Angular projects
sequba Oct 29, 2024
f0cea7b
Add more explenations to the migration guide
sequba Oct 30, 2024
51732b7
Add a fallback option for parcel projects to the migration guide
sequba Oct 31, 2024
5128ba3
Undo the version number change in package.json
sequba Oct 31, 2024
152b0dd
Update migration guide
sequba Nov 5, 2024
44e9d56
Remove unnsecessary step from the parcel section of the migration guide
sequba Nov 7, 2024
a07d548
Merge branch 'develop' into feature/issue-1344
sequba Nov 12, 2024
fecd03a
Rephrase CHANGELOG.md
sequba Nov 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: () => [],
}),
}
};
});
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Fixed

- Fix ES module build to make importing language files possible in Node environment. [#1344](https://github.com/handsontable/hyperformula/issues/1344)

## [2.6.2] - 2024-02-15

### Changed
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' }],
],
},
},
};
200 changes: 194 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,18 @@
"last 2 op_mob versions"
],
"license": "GPL-3.0-only",
"module": "es/index.js",
"type": "commonjs",
"module": "es/index.mjs",
"main": "commonjs/index.js",
"jsnext:main": "es/index.js",
"jsnext:main": "es/index.mjs",
"jsdelivr": "dist/hyperformula.min.js",
"unpkg": "dist/hyperformula.min.js",
"typings": "./typings/index.d.ts",
"scripts": {
"docs:dev": "npm run typedoc:build-api && vuepress dev docs --silent --no-clear-screen --no-cache",
"docs:build": "npm run bundle-all && npm run typedoc:build-api && vuepress build docs",
"bundle-all": "cross-env HF_COMPILE=1 npm-run-all clean compile bundle:** verify-bundles",
"bundle:es": "(node script/if-ne-env.js HF_COMPILE=1 || npm run compile) && cross-env-shell BABEL_ENV=es env-cmd -f ht.config.js babel lib --out-dir es",
"bundle:es": "(node script/if-ne-env.js HF_COMPILE=1 || npm run compile) && cross-env-shell BABEL_ENV=es env-cmd -f ht.config.js babel lib --out-file-extension .mjs --out-dir es",
"bundle:cjs": "(node script/if-ne-env.js HF_COMPILE=1 || npm run compile) && cross-env-shell BABEL_ENV=commonjs env-cmd -f ht.config.js babel lib --out-dir commonjs",
"bundle:development": "(node script/if-ne-env.js HF_COMPILE=1 || npm run compile) && cross-env-shell BABEL_ENV=dist NODE_ENV=development env-cmd -f ht.config.js webpack ./lib/index.js",
"bundle:production": "(node script/if-ne-env.js HF_COMPILE=1 || npm run compile) && cross-env-shell BABEL_ENV=dist NODE_ENV=production env-cmd -f ht.config.js webpack ./lib/index.js",
Expand Down Expand Up @@ -95,6 +96,10 @@
"check:licenses": "license-checker --production --excludePackages=\"[email protected]\" --onlyAllow=\"MIT; Apache-2.0; BSD-3-Clause; BSD-2-Clause; ISC; BSD; Unlicense\"",
"tsnode": "ts-node --transpile-only -O {\\\"module\\\":\\\"commonjs\\\"}"
},
"dependencies": {
"chevrotain": "^6.5.0",
"tiny-emitter": "^2.1.0"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.4",
Expand Down Expand Up @@ -154,8 +159,191 @@
"webpack-cli": "^3.3.11",
"webpackbar": "^4.0.0"
},
"dependencies": {
"chevrotain": "^6.5.0",
"tiny-emitter": "^2.1.0"
"exports": {
".": {
"types": "./typings/index.d.ts",
"import": "./es/index.mjs",
"require": "./commonjs/index.js"
},
"./es/i18n/languages": {
"types": "./typings/i18n/languages/index.d.ts",
"import": "./es/i18n/languages/index.mjs",
"require": "./commonjs/i18n/languages/index.js"
},
"./commonjs/i18n/languages": {
"types": "./typings/i18n/languages/index.d.ts",
"import": "./es/i18n/languages/index.mjs",
"require": "./commonjs/i18n/languages/index.js"
},
"./es/i18n/languages/csCZ": {
"types": "./typings/i18n/languages/csCZ.d.ts",
"import": "./es/i18n/languages/csCZ.mjs",
"require": "./commonjs/i18n/languages/csCZ.js"
},
"./commonjs/i18n/languages/csCZ": {
"types": "./typings/i18n/languages/csCZ.d.ts",
"import": "./es/i18n/languages/csCZ.mjs",
"require": "./commonjs/i18n/languages/csCZ.js"
},
"./es/i18n/languages/daDK": {
"types": "./typings/i18n/languages/daDK.d.ts",
"import": "./es/i18n/languages/daDK.mjs",
"require": "./commonjs/i18n/languages/daDK.js"
},
"./commonjs/i18n/languages/daDK": {
"types": "./typings/i18n/languages/daDK.d.ts",
"import": "./es/i18n/languages/daDK.mjs",
"require": "./commonjs/i18n/languages/daDK.js"
},
sequba marked this conversation as resolved.
Show resolved Hide resolved
"./es/i18n/languages/deDE": {
"types": "./typings/i18n/languages/deDE.d.ts",
"import": "./es/i18n/languages/deDE.mjs",
"require": "./commonjs/i18n/languages/deDE.js"
},
"./commonjs/i18n/languages/deDE": {
"types": "./typings/i18n/languages/deDE.d.ts",
"import": "./es/i18n/languages/deDE.mjs",
"require": "./commonjs/i18n/languages/deDE.js"
},
"./es/i18n/languages/enGB": {
"types": "./typings/i18n/languages/enGB.d.ts",
"import": "./es/i18n/languages/enGB.mjs",
"require": "./commonjs/i18n/languages/enGB.js"
},
"./commonjs/i18n/languages/enGB": {
"types": "./typings/i18n/languages/enGB.d.ts",
"import": "./es/i18n/languages/enGB.mjs",
"require": "./commonjs/i18n/languages/enGB.js"
},
"./es/i18n/languages/enUS": {
"types": "./typings/i18n/languages/enUS.d.ts",
"import": "./es/i18n/languages/enUS.mjs",
"require": "./commonjs/i18n/languages/enUS.js"
},
"./commonjs/i18n/languages/enUS": {
"types": "./typings/i18n/languages/enUS.d.ts",
"import": "./es/i18n/languages/enUS.mjs",
"require": "./commonjs/i18n/languages/enUS.js"
},
"./es/i18n/languages/esES": {
"types": "./typings/i18n/languages/esES.d.ts",
"import": "./es/i18n/languages/esES.mjs",
"require": "./commonjs/i18n/languages/esES.js"
},
"./commonjs/i18n/languages/esES": {
"types": "./typings/i18n/languages/esES.d.ts",
"import": "./es/i18n/languages/esES.mjs",
"require": "./commonjs/i18n/languages/esES.js"
},
"./es/i18n/languages/fiFI": {
"types": "./typings/i18n/languages/fiFI.d.ts",
"import": "./es/i18n/languages/fiFI.mjs",
"require": "./commonjs/i18n/languages/fiFI.js"
},
"./commonjs/i18n/languages/fiFI": {
"types": "./typings/i18n/languages/fiFI.d.ts",
"import": "./es/i18n/languages/fiFI.mjs",
"require": "./commonjs/i18n/languages/fiFI.js"
},
"./es/i18n/languages/frFR": {
"types": "./typings/i18n/languages/frFR.d.ts",
"import": "./es/i18n/languages/frFR.mjs",
"require": "./commonjs/i18n/languages/frFR.js"
},
"./commonjs/i18n/languages/frFR": {
"types": "./typings/i18n/languages/frFR.d.ts",
"import": "./es/i18n/languages/frFR.mjs",
"require": "./commonjs/i18n/languages/frFR.js"
},
"./es/i18n/languages/huHU": {
"types": "./typings/i18n/languages/huHU.d.ts",
"import": "./es/i18n/languages/huHU.mjs",
"require": "./commonjs/i18n/languages/huHU.js"
},
"./commonjs/i18n/languages/huHU": {
"types": "./typings/i18n/languages/huHU.d.ts",
"import": "./es/i18n/languages/huHU.mjs",
"require": "./commonjs/i18n/languages/huHU.js"
},
"./es/i18n/languages/itIT": {
"types": "./typings/i18n/languages/itIT.d.ts",
"import": "./es/i18n/languages/itIT.mjs",
"require": "./commonjs/i18n/languages/itIT.js"
},
"./commonjs/i18n/languages/itIT": {
"types": "./typings/i18n/languages/itIT.d.ts",
"import": "./es/i18n/languages/itIT.mjs",
"require": "./commonjs/i18n/languages/itIT.js"
},
"./es/i18n/languages/nbNO": {
"types": "./typings/i18n/languages/nbNO.d.ts",
"import": "./es/i18n/languages/nbNO.mjs",
"require": "./commonjs/i18n/languages/nbNO.js"
},
"./commonjs/i18n/languages/nbNO": {
"types": "./typings/i18n/languages/nbNO.d.ts",
"import": "./es/i18n/languages/nbNO.mjs",
"require": "./commonjs/i18n/languages/nbNO.js"
},
"./es/i18n/languages/nlNL": {
"types": "./typings/i18n/languages/nlNL.d.ts",
"import": "./es/i18n/languages/nlNL.mjs",
"require": "./commonjs/i18n/languages/nlNL.js"
},
"./commonjs/i18n/languages/nlNL": {
"types": "./typings/i18n/languages/nlNL.d.ts",
"import": "./es/i18n/languages/nlNL.mjs",
"require": "./commonjs/i18n/languages/nlNL.js"
},
"./es/i18n/languages/plPL": {
"types": "./typings/i18n/languages/plPL.d.ts",
"import": "./es/i18n/languages/plPL.mjs",
"require": "./commonjs/i18n/languages/plPL.js"
},
"./commonjs/i18n/languages/plPL": {
"types": "./typings/i18n/languages/plPL.d.ts",
"import": "./es/i18n/languages/plPL.mjs",
"require": "./commonjs/i18n/languages/plPL.js"
},
"./es/i18n/languages/ptPT": {
"types": "./typings/i18n/languages/ptPT.d.ts",
"import": "./es/i18n/languages/ptPT.mjs",
"require": "./commonjs/i18n/languages/ptPT.js"
},
"./commonjs/i18n/languages/ptPT": {
"types": "./typings/i18n/languages/ptPT.d.ts",
"import": "./es/i18n/languages/ptPT.mjs",
"require": "./commonjs/i18n/languages/ptPT.js"
},
"./es/i18n/languages/ruRU": {
"types": "./typings/i18n/languages/ruRU.d.ts",
"import": "./es/i18n/languages/ruRU.mjs",
"require": "./commonjs/i18n/languages/ruRU.js"
},
"./commonjs/i18n/languages/ruRU": {
"types": "./typings/i18n/languages/ruRU.d.ts",
"import": "./es/i18n/languages/ruRU.mjs",
"require": "./commonjs/i18n/languages/ruRU.js"
},
"./es/i18n/languages/svSE": {
"types": "./typings/i18n/languages/svSE.d.ts",
"import": "./es/i18n/languages/svSE.mjs",
"require": "./commonjs/i18n/languages/svSE.js"
},
"./commonjs/i18n/languages/svSE": {
"types": "./typings/i18n/languages/svSE.d.ts",
"import": "./es/i18n/languages/svSE.mjs",
"require": "./commonjs/i18n/languages/svSE.js"
},
"./es/i18n/languages/trTR": {
"types": "./typings/i18n/languages/trTR.d.ts",
"import": "./es/i18n/languages/trTR.mjs",
"require": "./commonjs/i18n/languages/trTR.js"
},
"./commonjs/i18n/languages/trTR": {
"types": "./typings/i18n/languages/trTR.d.ts",
"import": "./es/i18n/languages/trTR.mjs",
"require": "./commonjs/i18n/languages/trTR.js"
}
}
}
6 changes: 3 additions & 3 deletions script/check-publish-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ const FILES_CHECKLIST = [
'commonjs/index.js',
'commonjs/HyperFormula.js',
'dist/hyperformula.js',
'es/index.js',
'es/HyperFormula.js',
'es/index.mjs',
'es/HyperFormula.mjs',
'typings/index.d.ts',
'typings/HyperFormula.d.ts',
'dist/languages/plPL.js',
'es/i18n/languages/plPL.js',
'es/i18n/languages/plPL.mjs',
'commonjs/i18n/languages/plPL.js',
]

Expand Down
Loading