webpack-contrib / imports-loader

Imports Loader
MIT License
520 stars 63 forks source link

Dealing with ES6 export #20

Closed chongkong closed 7 years ago

chongkong commented 8 years ago
/* foobar.js */

// ES6 export
const foobar = {
  foo: 'bar'
}
export default foobar;

// is equivalent to
module.exports = {
  default: foobar
}
/* foobar-log.js */

console.log(foobar);

So if I import foobar-log.js with imports-loader

import 'imports?foobar=./foobar!./foobar-log'

It gives object with default. It seems there're no way toget just { foo: bar }.

lijunle commented 8 years ago

+1 here.

saulshanabrook commented 8 years ago

I was able to get around this by importing the module and then settings the variable to the <modeule name>.default for getting the default export. Like this:

require("imports?WebViewBridgeModule=../test/mockWebViewBridge,WebViewBridge=>WebViewBridgeModule.default!../dist/inject.js");
methodbox commented 8 years ago

Not really a fix, @saulshanabrook as this uses ES5 require() instead of import/export.

saulshanabrook commented 8 years ago

@methodbox Do you know if this would work with import instead of require?

methodbox commented 8 years ago

@saulshanabrook Assuming you're using Babel or similar in your build setup, import should work the same.

However, webpack seems to favor require() (and ES5 syntax in general) so I'm not sure it is possible.

None of the webpack.conf.js examples I've seen use ES6 at all; and I thing this is mostly due to webpack being focused on bundling before transpiling to ES6, which is still necessary for supporting a lot of modules, but isn't an excuse for not moving to ES6 syntax for webpack config itself.

Part of this is a node limitation, too. Node supports ES6, but I am unsure how webpack handles modules in terms of reliance on node. Node has fallbacks for ES5 as many modules have yet to be updated.

Webpack is kind of a weird middleware in that sense. We will probably need to wait for ES6 in webpack for quite a while.

methodbox commented 8 years ago

Also note that ES6 eslint will not flag module.exports but will flag other common ES5 items like var.

Module.exports is more semantic IMO as it encompasses the export in a clearly defined object using brackets.

methodbox commented 8 years ago

Also, OP you don't need {foo: bar}, you only need foobar.foo.

SpaceK33z commented 7 years ago

As of #35, it is possible to import nested properties, so foobar.default should work. I'll try to release a new version very soon. Let me know if it doesn't work.

getsnoopy commented 7 years ago

@SpaceK33z , #35 allows something like imports?foobar.default=foobar which would result in foobar.default = require('foobar'), but what we want in this case is something like imports?foobar=foobar.default to result in var foobar = require('foobar').default, since the ES6 transpilation will end up nesting the default export of the module under the default property of foobar's exported object.

I tried to do something like that with v0.7.0 without luck. That makes sense though, considering . is an allowed character in file names, so there's no way to know whether it's part of the filename or property notation.

Having an easy way to import default exports and/or named exports would be nice.

wildcard commented 7 years ago

@getsnoopy try this e.g. imports-loader?{default:Auth0Lock}=auth0-lock!angular-lock using a ES2015 destructor will solve the problem