Reputation: 29109
If I have a lib, say utils.js
which looks like this
exports.foo = function () {
return 'foo';
};
exports.bar = function () {
return 'bar';
};
Which can be used as follows
import {foo} from './libs/utils';
console.log(foo());
Not very spectacular, but I get the feeling that this problem is the origin of the issue described in this post. Anyway I cannot get this to work in combination with SystemJS. I have to change the code to fix it
import utils from './libs/utils';
console.log(utils.foo());
Here is my systemjs-config file:
SystemJS.config({
map: {
'plugin-babel': 'node_modules/systemjs-plugin-babel/plugin-babel.js',
'systemjs-babel-build': 'node_modules/systemjs-plugin-babel/systemjs-babel-browser.js',
},
packages: {
'.': {
defaultJSExtensions: 'js'
}
},
transpiler: 'plugin-babel'
});
So, it seems only the exports
object can be loaded and not the named export. Can this somehow be fixed?
UPDATE I get the impression it could be fixed with formats
meta: {
'./libs/utils.js': {
format: 'cjs'
}
}
But so far it gives the same problems
Upvotes: 4
Views: 1836
Reputation: 1409
This behavior is not SystemJS specific. SystemJS behaves like this since version 0.20 because this is what ES6 module interoperability is being standardized to.
When, as in your question, you are importing CommonJS modules (exported via module.exports
) using ES6 import
, you will only get the entire export, and you cannot immediately destructure the exported names.
However, when you are import
ing modules which are exported via ES6 export
, you will be able to destructure the exported names.
So, it's all by design. Guy Bedford wrote about this on his blog and referenced the module standardization that is going on for NodeJS:
... named exports will no longer be permitted when importing a CommonJS module from an ES module, and is discussed at https://github.com/nodejs/CTC/pull/60/files#diff-2b572743d67d8a47685ae4bcb9bec651R217.
That is,
import { name } from 'cjs.js'
, wherecjs.js
is a CommonJS module will no longer be supported, and instead will requireimport cjs from 'cjs.js'; cjs.name
.
An interop workaround by using __esModule
:
We will continue to support the
__esModule
flag in interop though, allowing lifting of named exports for these cases.So if the
cjs.js
module was written:exports.__esModule = true; exports.name = function () { ... }
then it would be possible to have
import { name } from 'cjs.js';
, even thoughcjs.js
is a CommonJS module, although this__esModule
will eventually in the longer term be deprecated as well.
Upvotes: 4