Skip to content
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

New 'export default' issue in 0.16 #4784

Closed
pietropizzi opened this issue Dec 15, 2015 · 6 comments
Closed

New 'export default' issue in 0.16 #4784

pietropizzi opened this issue Dec 15, 2015 · 6 comments
Labels
JavaScript Resolution: Locked This issue was locked by the bot.

Comments

@pietropizzi
Copy link

I can reproduce an issue with using export default since upgrading to 0.16.

The following scenario:

// constants.js 
const constants = {
  fetchStates: {
    LOADING: 'loading'
  }
};
export default constants;

// -------------------------------------------

// In another module
import { fetchStates } from './constants';
console.log(fetchStates.LOADING);

Once this code is transformed and run the error message is undefined is not an object (evaluating '_constants.fetchStates.LOADING')

What does not seem to work is the following line:

// Does NOT work
import { fetchStates } from './constants';

It also does not work with require:

// Does NOT work
const { fetchStates } = require('./constants');

This works though:

// Does work
import constants from './constants';
const { fetchStates } = constants;

Alternatively using module.exports = instead of export default works too.

These are both not great workarounds, there seems to be something wrong with export default in general. I ran into another set of issues when requiring the files from jest tests. The exported object would be nested inside another default key.

I tried all I can digging into this and trying to find the root cause but boiling it down to this scenario is as far as I came.

@facebook-github-bot
Copy link
Contributor

Hey pietropizzi, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don't know how to do something or not sure whether some behavior is expected or a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you're using. Thank you for your contributions!

@pietropizzi pietropizzi changed the title New export default issue in 0.16 New 'export default' issue in 0.16 Dec 15, 2015
@gre
Copy link
Contributor

gre commented Dec 15, 2015

noticed this too.

workaround is either to require("./foo").default or to not use export default

@satya164
Copy link
Contributor

@pietropizzi

About the first issue, React Native 0.16 uses Babel 6 to transpile, which changed lots of things. Can you try it by just using Babel 6, and if the issue persists, report this issue on Babel's bug tracker?

About the second issue with require('./module'), it's how it's supposed work. default exports are just named exports with a special name default. So you need to do require('./module').default instead.

@pietropizzi
Copy link
Author

An update on this issue:

My aforementioned code:

// constants.js 
const constants = {
  fetchStates: {
    LOADING: 'loading'
  }
};
export default constants;

// -------------------------------------------

// In another module
import { fetchStates } from './constants';
console.log(fetchStates.LOADING);

should not actually work according to spec and apparently Babel 5 made it work but Babel 6 is stricter. The right way to do the export is:

// constants.js 
export const fetchStates = {
  LOADING: 'loading'
};

// or

const fetchStates = {
  LOADING: 'loading'
};

export { fetchStates };

I changed that and now I can live without module.exports = BUT

Inside of jest tests it still does not work. There the only way to make it work now is to change all the named imports to this:

import * as constants from './constants';
const { fetchStates } = constants;

Inside of tests I unfortunately need to use require (which I fixed up the way you described) since imports are being hoisted to the top of the file. But that is the only difference. Any ideas here?

@pietropizzi
Copy link
Author

Closing this, since it is only about the tests. Narrowed it down, find more info here #3999 (comment)

@ide
Copy link
Contributor

ide commented Dec 16, 2015

In summary, Babel 6 implements a stricter but correct behavior. It's sort of a pain to migrate but from personal experience if you move entirely to import/export one thing that's nice is that cycles are less of an issue because there is no more clobbering of module.exports; with JS's import/export everything is assigned to exports.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 20, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 20, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
JavaScript Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

6 participants