-
-
Notifications
You must be signed in to change notification settings - Fork 878
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 import requires using .default property #1381
Comments
It is not tested with .mjs... It works if you use it like that:
I thought that it would understand default exports, it probably needs some additional typescript setting to support import from .mjs |
possibly you need to recompile source to .mjs? |
.mjs makes nodejs treat the file as ECMAScript-Module, and makes me able to use import / export syntax instead of require(), no need to compile npm-packages to be compatible. import syntax works with non module-packages. Now that you write it, i checked the package and since in After checking other installed npm packages in my projects, i see only default exports using
The following code-change made it work for me with
|
I'm running into a similar issue using Rollup to bundle Ajv into a bundle for the browser. package.json {
"name": "avj-test",
"version": "1.0.0",
"dependencies": {
"ajv": "^7.0.3"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^11.0.1",
"rollup": "^2.36.1"
}
} rollup.config.js import { nodeResolve } from "@rollup/plugin-node-resolve";
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'iife',
},
plugins: [nodeResolve()],
}; src/index.js import Ajv from "ajv"
const ajv = new Ajv() Output
The issue is fixed with this change: node_modules/ajv/dist/ajv.js exports.default = Ajv;
+ export default Ajv
//# sourceMappingURL=ajv.js.map |
The problem with the below
is that you cannot export anything else from this module other than this thing. So I won't be able to do in typescript something like The problem with this:
is that I think it is not a valid JS outside of I didn't figure out a better way to compile typescript in such a way that I can both have default export compatible with typescript and with require, and also be able to export other things from the same file - hence this compromise that allows above import in typescript but requires There may be a better, more universal solution probably, in configuring typescript options in such way that at least a normal import (without .default) from Any ideas on how best to configure typescript (while still allowing the above imports and without using esModuleInterop setting) are welcome |
Unfortunately, TypeScript does not yet support Node.js native ESM. One hacky workaround to support native ESM is to add export default class Ajv extends AjvCore {
// ...
}
module.exports = Ajv;
module.exports.default = Ajv;
Object.defineProperty(exports, "__esModule", { value: true }); You will also need to move all exports to after the part where you added them. This technique is used in some packages, such as got. |
@epoberezkin If necessary, the other |
@teppeis thank you - maybe not such a terrible idea... So in this case all the extra bits will be added as properties of the constructor function, but probably no harm. Also requirement to add It does look like the linked example is compiled in esModuleInterop mode, but it should work without it as well. I am not sure whether |
I would not bother fixing it in core.ts, I don't think anybody would import it directly, but the user facing classes can be updated indeed - PR would be great! |
Another option would be to export the export class Ajv {}
export default Ajv Example usage: const Ajv = require('ajv').default
const {Ajv} = require('ajv')
import {Ajv} from 'ajv' But that would not enable the default use case: const Ajv = require('ajv') // wrong
import Ajv from 'ajv' // wrong |
Hi @epoberezkin , got into this issue as well which made our team switch to Joi for validation because it conflicts with the fact that Jest requires transpiling into commonjs, which creates issues, see: svsool/axios-better-stacktrace#3 for example. All the above solutions are nice but require editing the source code, when a nicer solution would be to compile for both ESM and CJS, then create a sub- cjs/package.json: {
"type": "commonjs"
} esm/package.json: {
"type": "module"
} and in the main package.json: "exports": {
".": {
"import": "./esm/index.js",
"require": "./cjs/index.js"
}
} I can make a PR for this if it's accepted. |
@Nowadays Node.js marks I'm going to add what @teppeis proposed: export default class Ajv extends AjvCore {
// ...
}
module.exports = Ajv
module.exports.default = Ajv |
So, What seems to work is class Ajv extends AjvCore {
// ...
}
module.exports = exports = Ajv
exports.__esModule = true // this is still needed because "exports" is overridden (and TS compiler does it in the beginning)
export default Ajv |
I am facing similar issue while importing Should we apply similar hack for |
I updated Node.js version with npm version to
and I am unable to
I tried lot of things like deleting node_modules, cache, solving it via resolutions of new / old versions of |
Not sure what's going on but I installed latest
I've tried enabling esModuleInterop to no avail. (Oh, and I already have the node types installed, not sure why I'd need them tho) edit: Oh, sorry. It was this line that caused the trouble, which I of course can live without:
|
The version of Ajv you are using:
v7.0.3
Operating system and node.js version
Win10, node 15.5.1
Package manager and its version
npm v6.14.10; yarn v1.22.5
Link to (or contents of) package.json
Error messages
The output of
npm ls
When i downgrade to v6.x.x everything works fine. I also tried yarn for package installation, deleted node_modules and setup a new project to avoid conflicts from other code.
The text was updated successfully, but these errors were encountered: