Is there a ESM version?
Can you provide a link to ESM version, please? Also perhaps adding it to the README.
Oh, did they finally decide to fix Node?
Jokes aside, how would that work? I.e. supporting CommonJS and ESM at the same time.
That works via providing separate sprintf.esm.js file. Which would use export sprintf, not module.exports.
I use it with modern browsers and with rollup.js, not in node.
I run rollup.js in Deno.
One may look how underscore.js provides their esm distribution, for example.
I didn't know about that, and I'm even more confused today than I was yesterday: I thought the way to do it was .mjs?
.mjs extension is optional one (for disambiguation), it's not required. Chrome / Firefox load ES modules finely from ordinary .js file ES modules.
https://underscorejs.org/underscore-esm.js
Deno works with ES modules natively, although it's typescript (.ts) by default.
https://deno.land/manual/examples/import_export
So let me get this straight: first there was CJS, then AMD showed up for whatever reason, then that evolved into UMD. Now we have ESM. Browsers don't mind .js, but Node wants .mjs. And now this: .esm.js which I still don't understand where it came from and the Internet doesn't help either. This looks like a mess I don't want to deal atm. Sorry!
As you wish. If one does not like esm.js, you may create sprintf.mjs though. It will work with modern browsers and with Deno. By the way, the author of Deno hopes that Deno will replace node.js at some point.
For example, underscore.js is major library which provides different versions, including ESM one.
Is there any documentation about this?
See underscore.js build setup for example:
https://github.com/jashkenas/underscore/blob/97f4cb42a1125e160f8aac1bedcd4969745dffec/rollup.config.js
// Monolithic ESM bundle for browsers and deno.
{
input: 'modules/index-all.js',
treeshake: false,
output: monolithConf({
file: 'underscore-esm.js',
format: 'esm',
}),
},
It will be nice if we could support ESM version, I have to see this warning everyday ...
copyright.component.ts depends on 'sprintf-js'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
Many are just doing a major release and ship it as esm-only
ppl stuck with cjs can use dynamic import() or stay on the later version.
As you wish. If one does not like esm.js, you may create sprintf.mjs though. It will work with modern browsers and with Deno. By the way, the author of Deno hopes that Deno will replace node.js at some point.
Alternative package with esm support: printj and same discussion about alternative way if esm will not be supported =). But I don't found both on cdnjs.
The approach used in printj is to build the ESM script with a .mjs extension and use the module field in package.json to point to the .mjs script. The main field points to the CJS version and we ship the minified dist scripts for standalone use in the browser. This approach does not break normal node require statements. Webpack will accept the extension. Node ESM is sated. Browser ESM (script type="module") accepts it. Older browsers can theoretically use the dist version without fear.
If you're comfortable with the idea of supporting ESM but don't want to be burdened with having to maintain two separate scripts, it's sensible to build the ESM script from the base script using gulp-replace. Strip the IIFE and replace the exports/window blocks with a single export statement:
- add the module line to package.json as well as the gulp-replace dev dep:
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"description": "JavaScript sprintf implementation",
"author": "Alexandru Mărășteanu <[email protected]>",
"main": "src/sprintf.js",
+ "module": "dist/sprintf.mjs",
"scripts": {
"test": "mocha test/*.js",
"pretest": "npm run lint",
@@ -25,6 +26,7 @@
"gulp-header": "^2.0.5",
"gulp-mocha": "^6.0.0",
"gulp-rename": "^1.4.0",
+ "gulp-replace": "^1.1.3",
"gulp-sourcemaps": "^2.6.4",
"gulp-uglify": "^3.0.1",
"mocha": "^5.2.0"
- create a gulp task to create that file from your base file:
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -8,6 +8,7 @@ var pkg = require('./package.json'),
header = require('gulp-header'),
eslint = require('gulp-eslint'),
mocha = require('gulp-mocha'),
+ replace = require('gulp-replace'),
benchmark = require('gulp-benchmark'),
banner = '/*! <%= pkg.name %> v<%= pkg.version %> | Copyright (c) 2007-present, <%= pkg.author %> | <%= pkg.license %> */\n'
@@ -42,4 +43,15 @@ gulp.task('dist', ['test'], function() {
.pipe(gulp.dest('dist'))
})
-gulp.task('default', ['dist'])
+gulp.task('dist-esm', ['test'], function() {
+ return gulp.src([
+ 'src/sprintf.js'
+ ])
+ .pipe(replace(/^[^]*?{/, ""))
+ .pipe(replace(/if \(typeof exports[^]*$/, "export { sprintf, vsprintf };"))
+ .pipe(rename({ extname: '.mjs' }))
+ .pipe(header(banner, {pkg: pkg}))
+ .pipe(gulp.dest('dist'))
+})
+
+gulp.task('default', ['dist', 'dist-esm'])
(you may also want to update dist/.gitattributes)
This approach works in a simple webpack import, in node 16 ESM, and in raw browser ESM.
@viT-1 unpkg and jsdelivr pull from the npm modules e.g. https://unpkg.com/[email protected]/dist/sprintf.min.js . The live demo linked in that thread imports from unpkg directly and it would roughly work the same way if the same approach is used here:
import { sprintf } from 'https://unpkg.com/[email protected]/printj.mjs';
+1 On this issue! I'm happy to help if need be. With newer build tools, it shouldn't be hard to produce this library in multiple formats.
I managed to convert NPM package for sprinft.js to an ESM using esh.sh
From the deno docs: "esm.sh is a CDN that was specifically designed for Deno... uses esbuild to take an arbitrary npm package and ensure that it is consumable as an ES Module"
This worked in the browser with the bundle I create with esbuild_deno_loader, but VSCode (the Deno extension) complained with: "This expression is not callable... has no call signatures.deno-ts(2349)" wherever I used sprintf in my TypeScript source code. Maybe I didn't configure the IDE properly? 🤷
Anyway... I then saved the ESM that was generated by esm.sh to a file, and did a relative import
import { sprintf } from "./sprintf/sprintf.esm.js"
This works, both the browser and the IDE is happy