to-esm
v2.27.3
Published
Tool to convert Commonjs files into ESM
Downloads
3,068
Readme
Description
A tool to convert Commonjs files into ESM files. To-esm can be used for generating hybrid modules. Do all of your coding using CommonJs, then convert your code into ESM at build or packaging times.
Notes
🪛 "to-esm" allows generating ESM code from your existing CommonJs code in the least destructive way possible.
As the generated ESM code will still resemble the original code, you can still keep using cjs without worry. You can generate a new ESM version whenever your system needs a build or set up a watcher.
🚫 CommonJs offers many advantages by its dynamic nature as it seems very back-end oriented. On the other hand, ESM is more designed for a front-end approach and module bundling (which often hides the differences between the two systems) .
V8 is likely developed around the idea that Chrome should not touch the OS file system for evident security matters. Therefore, even though switching to ESM seems ideal, many "hiccups" still exist.
Hybrid modules make things easier. Note that to-esm can help with this.
Installation
npm install to-esm -g
Usage
to-esm <filepath> [--output=<dirpath>] [--html=<filepath>] [--noheader] [--target=< browser|esm|package >]
[--prefixpath=<dirpath>] [--bundle=<filepath>] [--watch] [--update-all] [--minify] [--no-bundle-minify]
Examples
📋
Generate ESM code
To generate an .mjs(ES module) file from a .js file do:
# 💻 < Command
$> to-esm example/cjs/input.js
🚫 NOTE: to-esm should run from the project root folder.
Click on the arrow to expand or collapse
📁project ⇽ Ran from here
│
└───📁example
│ │
│ └───📁code
│ │ 📝 library.js
│ │ 📝 demo.js ⇽
│ │ ...
│
📝 library.js ↴
function hi()
{
console.log(`I wanted to say hi!`)
}
module.exports = hi;
📝 demo.js ↴
const hi = require("./library.js");
hi();
./demo.js => ./demo.mjs 📝
📁project
│
└───📁example
│ │
│ └───📁code
│ │ 📄 library.js
│ │ 📄 demo.js
│ │ 📝 library.mjs ⇽
│ │ ...
│
└ 📝 demo.mjs ⇽
📝 library.js ↴
function hi()
{
console.log(`I wanted to say hi!`)
}
export default hi;
📝 demo.js ↴
import hi from "./example/code/library.mjs";
hi();
to-esm will convert the entry point inside the working directory. The others will depend on the source location.
📋
Generate code into a dedicated directory
--output < folder >
# 💻 < Command
$> to-esm example/cjs/input.cjs --output generated/esm
Click on the arrow to expand or collapse
📁project ⇽ Ran from here
│
└───📁example
│ │
│ └───📁code
│ │ 📝 library.js
│ │ 📝 demo.js ⇽ 🚩
│ │ ...
📁project
│
└───📁example
│ │
│ └───📁code
│ │ 📝 library.js
│ │ 📝 demo.js
│ │ ...
│
└───📁generated ⇽ 🚩
│ └───📁esm
│ └───📁example
│ └───📁code
│ 📝 library.mjs ⇽ 🚩
│ 📝 demo.mjs ⇽
│ ...
Checking the conversion has succeeded
node generated/esm/example/code/demo.mjs
📋
Remove automatically generated header
--noheader
# 💻 < Command
$> to-esm example/cjs/input.cjs --output generated --noheader
⏳ - Without the --noheader option
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./example/code/demo.js]{@link ./example/code/demo.js}
*
**/
import hi from "./example/code/library.mjs";
hi();
⌛ With the --noheader option
import hi from "./example/code/library.mjs";
hi();
📋
Generate code for the browser
--target < browser | esm | package >
# Command < 💻
$> to-esm example/cjs/input.cjs --output generated --target browser
Click on the arrow to expand or collapse
1- When generating code for the browser, **
to-esm** will display a warning when the code uses a native Node library.
📝 demo.js ↴
const path = require("path"); // See directives below to see how to remove this call
function hi()
{
console.log(`I wanted to say hi!`)
}
module.exports = hi;
During conversion:
💻 >
to-esm: (1130) ================================================================
to-esm: (1132) Processing: ./example/code/demo.js
to-esm: (1134) ----------------------------------------------------------------
to-esm: (1060) ✔ SUCCESS: Converted [./example/code/demo.js] to [generated-browser\demo.mjs]
to-esm: (1150)
to-esm: (1130) ================================================================
to-esm: (1132) Processing: ./example/code/library.js
to-esm: (1134) ----------------------------------------------------------------
to-esm: (1017) path is a built-in NodeJs module. ⇽ 🚩
to-esm: (1060) ✔ SUCCESS: Converted [./example/code/library.js] to [generated-browser\example\code\library.mjs]
to-esm: (1150)
2- To load your files in the HTML code, you only point to the entry file (demo.js).
The browser will automatically load the other files.
demo.mjs is the entrypoint.
The browser automatically loads all the related files.
Click on the arrow to expand or collapse
When there is a requirement to load libraries from the node_modules folder, to-esm will generate a converted copy of the files to the output directory.
📝 demo.js ↴
const toAnsi = require("to-ansi");
const rgbHex = require("rgb-hex-cjs");
const {COLOR_TABLE, SYSTEM} = require("./some-lib.js");
// ...
📁project
└─── 📁 original
│─── 📝 index.html
│─── 📝 demo.js
│─── 📝 some-lib.js
│
└─── 📁 generated
│─── 📝 demo.mjs ⬅ 🚩
│─── 📝 some-lib.mjs ⬅ 🚩
│
└─── 📁 node_modules ⬅ 🚩
│
└───📁 rgb-hex
│ └── 📝 index.cjs
│
└───📁 to-ansi
└── 📝 index.cjs
The two libraries used will be easily accessible by the system and ease the bundling in production. See the importmap section to have a more modular approach.
📋
Generate importMaps within html files
--html < pattern | html >
# Generates => 📝 ./demo.mjs & update index.html
$> to-esm example/cjs/demo.cjs --html index.html
🚫 NOTE: When this option is used, the target is always "browser". --target.
An import map will allow writing imports like this
import rgbhex from "rgb-hex"
instead of
import rgbhex from "../../../path/to/rgb-hex.mjs"
Click on the arrow to expand or collapse
Before
📝 index.html ↴
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<script type="module" src="actual/demo-test.mjs"></script>
</body>
</html>
After
<!DOCTYPE html>
<html lang="en">
<head>
<script type="importmap">
{
"imports": {
"rgb-hex": "./node_modules/rgb-hex/index.cjs"
}
}
</script>
</head>
<body>
<script type="module" src="actual/demo-test.mjs"></script>
</body>
</html>
importmap allows some more elaborated setups where third party caching will be entirely handled by the browser.
📋
Convert files with patterns
You can have multiple files converted in one go. It can be helpful if some files are not connected.
$> to-esm --input="example/cjs/*.?(c)js" --output=example/esm/
Options to generate code for npm packages --target package
🚫 NOTE: This option is experimental
To generate a non-bundled package code for npm, use this option. It will add an extra prefix ../../ to all relative path to third party modules.
Options to correct relative paths to third party modules
If your code point to a npm module with the option --target browser
, the system will convert the import to
the module location entrypoint.
For instance:
📝 source.cjs ↴
const toAnsi = require("to-ansi");
Will be converted to this path (or similar):
📝 source.mjs ↴
import toAnsi from "../../node_modules/to-ansi/index.mjs";
The path will be okay at conversion time. However, if the generated file (source.mjs
) is required inside a
browser, the path may no longer be valid. It will depend on your server configuration.
The option --prefixpath
allows correcting the issue by prepending some value to the target path.
This way, you can redirect the converted path to point to the correct location on your server.
# 💻 < Command
to-esm source.cjs --output out/ --prefixpath ../somewhere/
📝 source.mjs ↴
import toAnsi from "../somewhere/../../node_modules/to-ansi/index.mjs";
🪛
Options (via command line)
| Options | Description | Expect | default | |---------------------|-------------------------------------------------------------------------------------------------------|--------------------------------|---------| | filepath | File or pattern to convert | file path | | | --bundle | Generate minified bundle for esm environment | file path | | | --bundle-browser | Generate minified bundle for browser environment | file path | | | --bundle-cjs | Generate minified bundle for cjs environment | file path | | | --bundle-esm | Same as above | file path | | | --entrypoint | Explicitely set entry point (otherwise use the first file set in cli) | file path | | | --extension | Set generated files extension | string | .mjs | | --force-lf | Replace CLRF with LF | | | | --html | html files to receive importmaps | glob | | | --keep-external | Do not try to copy files from absolute paths into generated folder | boolean | false | | --keepExisting | Options to skip already converted files | | | | --minify | Options to minify converted files | boolean | | | --nmBrowserImported | Destination folder name for imported third parties when target is "browser" | directory path | | | --no-comments | Options to remove comments from converted files | boolean | false | | --no-bundle-minify | Options to not minify bundled files | boolean | false | | --noHeader | Options to not generate automatic header | boolean | false | | --output | Output directory | directory path | | | --prefixpath | Add a path to paths targeting third party modules | directory path | | | --resolve-absolute | Extra folders to look for when trying to solve absolute imported paths | string | | | --skipEsmResolution | Do not try to resolve third party libraries | boolean | false | | --skipLinks | Don't follow links (It will not convert linked files, but resulting links will need manual updates) | boolean | false | | --target | Setting the targeted environment | esm / browser / package | esm | | --update-all | Automatically update package.json to set entry points | | | | --use-bundle | When updating package.json use bundled/minified code | | | | --watch | Watch mode to automatically apply conversions when changes detected | directory path | | | ~~--subRootDir~~ | ~~Allow to retarget the output sub-directory~~ | ~~true~~ | |
💎
Advanced Options (via config file)
To apply advanced options, create a config file (.to-esm, .to-esm.json or .to-esm.cjs) and it will be automatically loaded. Otherwise, you can create a file with a custom name and explicitly tell the system to load it.
to-esm --config=.my-to-esm-config.cjs
Keys within the config file are case sensitive.
Options to replace strings before and after every conversion
[replaceStart, replaceEnd]
📝 .toesm.cjs ↴
module.exports = {
replaceStart: [
{
search : "const chalk = require(\"chalk\");",
replace: "// ***"
},
{
search : /const\s+colors\s*=\s*require\(.colors.\);/g,
replace: "// ***"
}
],
replaceEnd : [
{
search : `// ***`,
replace: "// --------- chalk and colors were replaced ----------------"
}
]
}
| Properties | Description | |----------------------|-----------------------------------------------------------------------| | replaceStart | will perform a replacement before doing the conversion to ESM | | replaceEnd | will perform a replacement after doing the conversion to ESM | | replaceStart.search | The regex pattern or string to replace | | replaceStart.replace | The replacement sentence |
Options to use two different modules of the same library.
"replaceModules": ...
Sometimes, you may find libraries where only ESM is available when CJS was available on older versions.
This option allows setting a different version depending on the environment used.
For instance, the module "chalk" uses ESM for its Export on its latest version (5.0.0) and CJS for the older version (4.
1.2).
You can setup toesm to use the appropriate version:
📝 .toesm.cjs ↴
module.exports = {
replaceModules:
{
"rgb-hex":
{
cjs: {
name: "rgb-hex-cjs", // ⬅ 🚩 .cjs files will use
// ... = require("rgb-hex-cjs")
// to load the module (v3.0.0)
version: "@^3.0.0"
},
esm: {
version: "@latest" // ⬅ 🚩 .mjs files will use
// import ... from "rgb-hex"
// to load the module
}
}
},
}
In the .cjs file to convert, you would write:
const rgbhex = require("rgb-hex-cjs");
Which is going to be transformed to:
import rgbhex from "rgb-hex";
| Properties | Description | |-----------------------------------|---------------------------------------------------------| | replaceModules[<moduleName>] | The module we want to use two different versions with | | replaceModules[<moduleName>].cjs | The module version to use with CommonJs files | | replaceModules[<moduleName>].mjs | The module version to use with converted files |
Options to set HTML sources and manipulate importmaps.
"html": ...
module.exports =
{
html:
{
pattern : "/index.html",
importmap :
{
"my-project": "../node_modules/my-project/src/esm/add.mjs",
"lodash" : "https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"
},
importmapReplace: [
{
search : "./node_modules",
replace: `/node_modules`,
}
],
}
}
| Properties | Description | |------------------|----------------------------------------------------| | pattern | HTML file pattern where importmap needs updating | | importmap | value to add to HTML files | | importmapReplace | Apply replacements on the importmap list |
The options above will be deployed as below:
<script type="importmap">
{
"imports": {
"my-project": "../node_modules/my-project/src/esm/add.mjs",
"lodash": "https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js" // ← Example
}
}
</script>
Allowing to write this:
import {add} from "my-project"
**NOTE: You can imagine improved caching offered by browsers soon **
💉
Directives
Directives allow more control over the generated code.
Directives to replace code directly from the source.
You can, if you want, also use some to-esm directives within the code. For instance, the code below will not appear when the target is a browser.
/** to-esm-browser: remove **/
const path = require("path");
const fs = require("fs");
const os = require("os");
/** to-esm-browser: end-remove **/
Directives to add code to the source.
It is also possible to add code.
📝 code.cjs ↴
/** to-esm-browser: add
this.realConsoleLog("LogToFile is not supported in this environment. ")
**/
In this example, after conversion, the above code will become this:
📝 code.mjs (with target browser) ↴
this.realConsoleLog("LogToFile is not supported in this environment. ")
Directives to ignore code during the parsing so that it won't be converted by mistake.
/** to-esm-all: skip **/
console.log("Skip this");
/** to-esm-all: end-skip **/
Directives to keep the target file as it is.
/** to-esm-all: do-not-overwrite **/
If the .mjs file already exists and contains this directive, it will not be overwritten.
Remove comments from generated code
--no-comments
The example below will remove all comments from the scanned .cjs files.
# 💻 < Command
$> to-esm example/**/*.cjs --output generated --target cjs
💡
Working with both CJS and ESM
You may want to work with both CommonJs and ESM together. So, you benefit from both worlds.
The CommonJs approach is a dynamic one. So, for example, you can do things like:
if (a)
{
// load module a
require(a);
}
else
{
// load module b
require(b)
}
With ESM and its static approach, loading both modules is necessary.
// load module a
import "a";
// load module b
import "b";
💡
Some conventions to write code for both CommonJs and ES Modules
Here are a few guides to writing code easily convertible.
Use named exports
For having the best compatibility between the two systems, it is best to use named exports.
Replace structures like:
module.exports = {
TABLE1 : ...,
TABLE2 : ...,
otherKey: ...
}
with:
module.exports.TABLE1 =
...
;
module.exports.TABLE2 =
...
;
module.exports.otherKey =
...
;
Or, if you want to provide a default export too:
// Default export
module.exports = {
TABLE1, TABLE2, ...
}
// Named export
module.exports.TABLE1 =
...
;
module.exports.TABLE2 =
...
;
module.exports.otherKey =
...
;
Use simple "require"
Rather than using "requires" like below forms (or more complex ones)
🤏 ↴
const Something = require("electron-data-exchanger").myThing;
const anything = require("electron-data-exchanger")(...);
Which may introduce temporary variables (_toesmTemp1)
import _toesmTemp1 from "electron-data-exchanger";
const Something = _toesmTemp1.myThing;
It is best to have them uncomplicated, so the conversion is straightforward.
👍 ↴
const MySomething = require("electron-data-exchanger");
const myAnything = require("electron-data-exchanger");
// ... The code that uses what was required
Assignment during declaration
to-esm will not convert the below code as it would require some refactoring that would make the generated code not resemble the original code.
Ambiguous form for to-esm
let myVar = "something";
// ...
myVar = require("my-module")
Expected form:
let myVar = require("my-module");
Use directives to solve issues with environments
Library targeting both Node and the Browser
If it needs to do an import in an ESM environment but not in the Browser, you can use directives to solve the issue.
/** to-esm-browser: add
let myMod = () => { return "somethings"; };
**/
/** to-esm-browser: remove **/
let myMod = require("my-mod");
/** to-esm-browser: end-remove **/
The code above will convert to:
Node
import myMod from "my-mod";
Browser
let myMod = () =>
{
return "somethings";
};
💡
Create a Hybrid Library with to.esm
1- Use the .cjs extension instead of .js
📁project
└─── 📝 index.cjs ⬅ 🚩
└─── 📝 package.json
└─── 📁example
│ │
│ └───📁code
│ └─── 📝 library.cjs ⇽ 🚩
│ ...
│
└─── 📁 node_modules
│ └── ...
2- Run to-esm against the entry point and update package.json
$> to-esm index.cjs --update-all
🚫 The option --update-all will modify your package.json to make it point to your entrypoint.
// Will point to .index.cjs require("your-module-name") // Will point to .index.mjs import("your-module-name")
Click on the arrow to expand or collapse
📝 ./package.json ↴
{
"name": "my-project",
"main": "./index.cjs",
"scripts": {
"build": "to-esm index.cjs"
},
"devDependencies": {
"to-esm": "file:.."
}
}
📝 ./index.cjs ↴
const hi = require("./example/code/library.cjs");
hi();
📝 ././example/code/library.cjs ↴
function hi()
{
console.log(`I wanted to say hi!`)
}
module.exports = hi;
📝 ./package.json ↴
{
"name": "my-project",
"main": "./index.cjs",
"scripts": {
"build": "to-esm index.cjs"
},
"devDependencies": {
"to-esm": "file:.."
},
"module": "./index.mjs",
⬅
🚩
"type": "module",
⬅
🚩
// (Change to commonjs if you don't want to use .cjs extension)
"exports": {
".": {
"require": "./index.cjs",
⬅
🚩
"import": "./index.mjs"
⬅
🚩
}
}
}
📝 ./index.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./index.cjs]{@link ./index.cjs}
*
**/
import hi from "./example/code/library.mjs";
hi();
📝 ././example/code/library.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./example/code/library.cjs]{@link ./example/code/library.cjs}
*
**/
function hi()
{
console.log(`I wanted to say hi!`)
}
export default hi;
3- Your code is generated.
To test it in NodeJs.
node index.mjs
💡
Create a Hybrid Library with to.esm supporting the browser
1- Use .cjs extensions instead of .js
📁project
└─── 📝 index.cjs ⬅ 🚩
└─── 📝 package.json
└─── 📁example
│ │
│ └───📁code
│ └─── 📝 library.cjs ⇽ 🚩
│ ...
│
└─── 📁 node_modules
│ └── ...
2- Run to-esm against en entry point
For the browser
$> to-esm index.cjs --output ./generated --target browser --bundle-browser dist/index.min.js
Click on the arrow to expand or collapse
📝 ./index.cjs ↴
const hi = require("./example/code/library.cjs");
hi();
📝 ././example/code/library.cjs ↴
function hi()
{
console.log(`I wanted to say hi!`)
}
module.exports = hi;
📝 ./index.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./index.cjs]{@link ./index.cjs}
*
**/
import hi from "./example/code/library.mjs";
hi();
📝 ././example/code/library.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./example/code/library.cjs]{@link ./example/code/library.cjs}
*
**/
function hi()
{
console.log(`I wanted to say hi!`)
}
export default hi;
📝 ./dist/index.min.js ↴ (Generated because of the --bundle option)
const c = {"95c93": {}};
c["95c93"].default = function ()
{
console.log("I wanted to say hi!")
};
{
c.bbc7e = {};
let b = c["95c93"].default;
b()
}
3- Your code is generated.
📁project
└─── 📝 index.cjs
└─── 📝 package.json
└─── 📁generated
│ │
│ └─── 📝 index.mjs ⬅ 🚩
│ │
│ └─── 📝 ...
│
└─── 📁 dist
│ └── index.min.js ⬅ 🚩
Insert the JavaScript browser version
...
<body>
<script type="module" src="generated/index.mjs"></script>
</body>...
Usage for the ESM version
import "..."
from
"index.mjs"
💡
Make your CJS module ESM compatible in one go.
Start by creating a .cjs file (or migrate your code) to have this structure.
📁project
└─── 📝 package.json
└─── 📁 cjs
│ └── 📝 index.cjs
Run to-esm against en entry point
$> to-esm cjs/index.cjs --output esm/ --bundle-esm bundle/mycode.min.mjs --bundle-cjs bundle/mycode.min.cjs
--bundle-browser dist/mycode-browser.min.js --update-all --use-bundle --watch
📁project
└─── 📝 package.json
└─── 📁 cjs
│ └── 📝 index.cjs ⬅ 🚩 Original code
└─── 📁 mjs
│ └── 📝 mycode.mjs ⬅ ESM Converted code (--output esm/)
└─── 📁 bundle
│ └── 📝 mycode.min.mjs ⬅ Bundled and minified code for ESM (--bundle-esm bundle/mycode.min.mjs)
│ └── 📝 mycode.min.cjs ⬅ Bundled and minified code for CommonJs (--bundle-cjs bundle/mycode.min.mjs)
└─── 📁 dist
│ └── 📝 mycode-browser.min.mjs ⬅ Bundled and minified code for browsers (--bundle-browser bundle/mycode.min.
mjs)
The option
--update-all
will automatically modify your package.json to make your module load the correct file depending on the environmentThe option
--use-bundle
will make --update-all configure the module to use minified and bundled versions ("mycode.min.mjs", "mycode.min.cjs") when a "require" or "import" is done against your module (Otherwise, it loads " index. cjs" and "mycode.mjs")The option
--watch
will automatically regenerate files when a change happens to the original cjs file (. /cjs/index.cjs)
This is it. Your module is fully hybrid, and you can keep working with CommonJs while not worrying about ESM.
Click on the arrow to expand or collapse
📝 ./index.cjs ↴
const hi = require("./example/code/library.cjs");
hi();
📝 ././example/code/library.cjs ↴
function hi()
{
console.log(`I wanted to say hi!`)
}
module.exports = hi;
📝 ./index.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./index.cjs]{@link ./index.cjs}
*
**/
import hi from "./example/code/library.mjs";
hi();
📝 ././example/code/library.mjs ↴
/**
* DO NOT EDIT THIS FILE DIRECTLY.
* This file is generated following the conversion of
* [./example/code/library.cjs]{@link ./example/code/library.cjs}
*
**/
function hi()
{
console.log(`I wanted to say hi!`)
}
export default hi;
📝 ./dist/index.min.js ↴ (Generated because of the --bundle option)
const c = {"95c93": {}};
c["95c93"].default = function ()
{
console.log("I wanted to say hi!")
};
{
c.bbc7e = {};
let b = c["95c93"].default;
b()
}
3- Your code is generated.
📁project
└─── 📝 index.cjs
└─── 📝 package.json
└─── 📁generated
│ │
│ └─── 📝 index.mjs ⬅ 🚩
│ │
│ └─── 📝 ...
│
└─── 📁 dist
│ └── index.min.js ⬅ 🚩
Insert the JavaScript browser version
...
<body>
<script type="module" src="generated/index.mjs"></script>
</body>...
Usage for the ESM version
import "..."
from
"index.mjs"
💡
Some thoughts
When you bundle your code, you usually introduce code from other third parties. Therefore, it may create implicit code repetition.
Tree shaking eliminates unnecessary code; however, it is done at "compile" time. It means it can not detect what has been repeated (Even though Tree shaking technics seem to go beyond simple dead code elimination).
Also, most IDEs detect the use of dead code, which also mitigates tree shaking greatness.
For instance, let's say you use two libraries. Lib1.js and Lib2.js.
Lib1 uses lodash and has been minified into lib1.min.js Lib2 also uses lodash and has been minified into lib2.min.js.
When you bundle your code containing lib1.js and lib2.js, you add lodash two times (or some functions of it).
Therefore, there are advantages to not systematically using bundled code.
1- Letting the browser cache all shared libraries is one of them; therefore, having the best caching system > (Chrome or Firefox would surely know the best way to cache files coming from a common ground).
2- Avoiding automated code repetition
3- Less painful and lengthy wait when the codebase becomes enormous.
4- Make Hot Reloading obsolete. Instead, use Cold Reloading (you reload when you save, when not, the bundler has finished its compilation).
5- Working directly on the "original code" rather than an unmaintainable one (even using source maps sometimes > does not solve all the issues).
💊🔥
Why use to-esm?
- You can keep on working with CommonJs as usual and generates your ESM code when necessary
- If CommonJs ever becomes obsolete, you can remove your CommonJs code and use the generated one directly
- The generated ESM code (non-bundled) looks close to the original CommonJs one.
🔥💥
Plus
Benefits:
- You do not need a source map when working in development mode.
- You do not need to bundle your code in development.
- You benefit directly from your browser caching ability (No more bundling of shared libraries)
- The generated code looks like the original code.
- ...
Changelog
current:
- Fix aliases conversion
- Fix conversion when an exported name does not match a function name
- Fix options --skipLinks
2.27.0:
- Allow changing extension of generated files
2.26.5:
- Fix error 3109 when scripts start with a shell bang symbol
2.26.4:
- Fix comments disappearance
- Fix [to-esm add] directive applied too soon
2.26.3:
- Keep line breaks in package.json on update-all
2.26.2:
- Add support for some Uglify options on non-bundled generated files --beautify, --braces, --comments, --dead_code, --drop_debugger, --drop_console, --inline, --indent_level, --indent_start, --keep_fargs, --keep_fnames, --keep_quoted, --max_line_len, --preserve_line, --quote_keys, --quote_style, --v8, --expression, --reserved, --ie, --annotations, --module, --nameCache, --semicolons, --sourcemap, --toplevel, --warnings, --webkit, --width, --wrap_iife
- Add option --no-bundle-minify to not minify generated bundled files
- Add --minify option to minify non-bundled generated files
- Add --no-comments option to remove comments from generated code
- Add --force-lf option to replace CLRF with LF
2.24.1:
- Remove duplicate export on the same line
- Add options --skipLinks to avoid following linked files
2.24.0:
- Add options --skipLinks to avoid following linked files
2.23.1:
- Fix an undefined source variable error during some parsing
- Fix undefined options errors
- Fix async functions exported incorrectly
- Allow skipping third-party module resolution with the skipEsmResolution option
- Fix no displayed output
- Set length for displayed log ids to 4
- Display help with the PageTerm module
- Fix --version and --help not displaying correctly
- Fix cjs minification not generated when conversion is not browser compatible
- Fix wrong path calculations for third-party browser modules
- Fix modules detected as installed
- Fix a broken directive
- Reduce output directories' depth
- Update documentation
- Add option --nmBrowserImported to rename imported node_modules