-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Description
Bug…
This issue arises when attempting to create a package that:
- Transpiles both ESM (
.mjs) for recent versions of Node.js run with--experimental-modulesenabled, and CJS (.js) as a fallback. - Imports a CJS package that contains
exports.__esModule.
When imported CJS in .mjs, Node.js provides a single default export representing the value of module.exports, so the syntax to use in source is:
import graphql from 'graphql'
console.log(graphql.GraphQLScalarType) // ClassThis syntax survives transpilation when using preset-env with modules: false for the .mjs target and works ok when running --experimental-modules. When transpiled with modules: 'commonjs' for the .js target, it creates syntax like this:
'use strict'
var _graphql = _interopRequireDefault(require('graphql'))
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj }
}
console.log(_graphql.default.GraphQLScalarType) // Undefined_graphql.default.GraphQLScalarType becomes causes an error as _graphql.default is undefined, because _interopRequireDefault found __esModule in the imported module and didn't wrap the exports under default.
Trying either of these approaches syntax in the source results in a functional .js target:
import { GraphQLScalarType } from 'graphql'
console.log(GraphQLScalarType)import * as graphql from 'graphql'
console.log(graphql.GraphQLScalarType)But breaks the .mjs target, because with --experimental-modules CJS can only be imported using default syntax.
The only workaround that seems to work in the source for both CJS and ESM targets:
import graphqlDefault, * as graphqlExports from 'graphql'
const graphql = graphqlDefault || graphqlExports
console.log(graphql.GraphQLScalarType)Babel/Babylon Configuration (.babelrc, package.json, cli command)
.babelrc.js:
module.exports = {
presets: [
[
'@babel/env',
{
targets: { node: '6.10' },
shippedProposals: true,
modules: process.env.MODULE ? false : 'commonjs',
useBuiltIns: 'usage'
}
]
]
}package.json scripts:
{
"scripts": {
"build": "npm run build:js && npm run build:mjs",
"build:js": "babel src --out-dir lib",
"build:mjs": "MODULE=true babel src --out-dir lib --keep-file-extension"
}
}Context
I have been struggling to find an elegent solution to solve jaydenseric/graphql-upload#40. apollo-upload-server is run by users in both traditional CJS environments and with native ESM using --experimental-modules.
Your Environment
| software | version(s) |
|---|---|
| Babel | 7.0.0-beta.38 |
| node | 8.9.3 |
| npm | 5.6.0 |
| Operating System | macOS |