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
ESM module
export differs from main
export
#240
Comments
Using named exports would solve all problems. |
There is objection, https://www.bignerdranch.com/blog/default-exports-or-named-exports-why-not-both/ maybe webpack better to provide a optionMap to config each node module are default export or named export. |
Convice me doesn't solve the problem, need convnce everyone and that's not possible. |
In this particular case technically these are named exports. There is no "primary" thing here and combining into single object does not solve any problem. If you will need single object use special syntax |
These are right, but the generated mjs code are default export |
Look at the dist file index.mjs, it's ends with default export, that's truely annoy.
I using Adjust webpack mainFields: to ['main', 'module'] for supporting newest |
In this diff I added new entry point to compile es modules with named exports to solve this problem (json5#240). It's a breaking change so we can drop legacy node support (newer versions of rollup and many other tools requires this) and add native node es modules support.
Check this #241 |
@lygstate Can you please explain what your issue is rather than just adding a link to an issue in another repo. |
The issue is using the library in commonjs code which is bundled by webpack
Though this does not work in node which does not have "default" field. |
module
export differs from main
export
Would it work to add an |
It won't work with webpack 4 which supports only "module" field. Do you have any objections to use named exports instead? I can migrate whole source to esm in the next PR if you want. |
I'm trying to avoid breaking changes. |
What about just assigning values to It produces the following code for var parse_1 = parse;
var stringify_1 = stringify;
var lib = {
parse: parse_1,
stringify: stringify_1
};
export default lib;
export { parse_1 as parse, stringify_1 as stringify }; |
Well, yeah, we can keep both until next major. |
Hi there, I get:
import json5 from "json5";
// import { parse } from "json5";
let json = `{
// comment
a: 1,
b: 1,
c: 1
}`;
console.log("json5.parse:", JSON.stringify(json5.parse(json)));
// console.log("parse:", JSON.stringify(parse(json))); // 'json5' is a CommonJS module?? |
Hi @jordanbtucker, please checkout this sample repo: https://github.com/ilanc/esm-json5 and let me know what you think. There's a clear problem with trying to use ESM json5 in node: i.e. node will use the CJS version of json5 even when included inside .mjs code. I've tested this with the following node versions:
The fix is to add and "exports" section to package.json. NB I know CJS/ESM transition is a pain and it's not easy to avoid breaking changes. will this "exports" break other js environments? NB the current "browser" looks wrong anyway = points to the bundled CJS code. "exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
}, |
The current correct way is to In April, when Node.js v12 is no longer supported, I plan on releasing json5@3, which will include your proposed fix and a few other breaking changes (moving the CLI to its own package, removing or deprecating |
Makes sense, thanks for the reply |
@jordanbtucker do you have a workaround for typescript? see error below // esm.ts
import json5 from "json5/dist/index.mjs";
let json = `{
// comment
a: 1,
b: 1,
c: 1
}`;
console.log("json5.parse:", JSON.stringify(json5.parse(json))); gives this error (I have no tsconfig.json in the directory atm):
|
I was using tsc |
@ilanc I wonder if copying |
@jordanbtucker possibly, and it may need types - but I wouldn't bother it'll change again with the next typescript / node / bundler / linter / ... sigh |
@jordanbtucker btw - not sure whether you've read these - but I've found these to be very useful articles on building dual cjs/esm packages: |
I checked. It's not that simple. The following declaration placed at import parse = require('../lib/parse')
import stringify = require('../lib/stringify')
interface JSON5 {
parse: typeof parse
stringify: typeof stringify
}
declare const JSON5: JSON5
export default JSON5 Is there a specific reason you need the ESM version in TypeScript?
Both <!-- Import json5 as a UMD global -->
<script src="https://unpkg.com/json5@2/dist/index.js"></script>
<script>
// JSON5 is a global
console.log(JSON5.parse(`{hello: 'world'}`))
</script> or <!-- Import json5 as a module -->
<script type="module">
import JSON5 from 'https://unpkg.com/json5@2/dist/index.mjs'
console.log(JSON5.parse(`{hello: 'world'}`))
</script> |
I don't want to keep wasting your time with this stuff. Thanks for all the responses.
Nope. I'm going through a painful exercise of porting my codebase from cjs to esm. One of the changes is to resolve how the 3rd party packages that I'm using have implemented esm. Of the 50+ packages I'm using I picked json5 to single step into and realised that the code tranformation suggested by node (i.e. I'm totally happy with the |
Webpack v4+ prefers the
module
field frompackage.json
over themain
field even when the webpacktarget
isnode
.Since the
main
module exports{parse, stringify}
and themodule
module exports{default: {parse, stringify}}
, this creates an issue when bundling with webpack.The text was updated successfully, but these errors were encountered: