In version 5.6.4 of BabelJS, I seemingly cannot "import ... as." Here are examples of what I am trying to do:
In file 'test.js':
export default class Test {};
In file 'test2.js' (in the same directory):
import Test as Test2 from './test';
I have also tried to do:
import {Test as Test2} from './test';
Even though it says nothing about that here:
http://babeljs.io/docs/learn-es2015/#modules
And only uses brackets in the non-default syntax here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Has anyone done this successfully?
EDIT: It is absolutely because of the default keyword. So, in this case, the question becomes, does anyone have any links to documentation that states that I should not be able to alias a default import? ECMA or Babel.
You can import the default export by either
import Test2 from './test';
or
import {default as Test2} from './test';
The default export doesn't have Test as a name that you would need to alias - you just need to import the default under the name that you want.
The best docs I've found so far is the article ECMAScript 6 modules: the final syntax in Axel Rauschmayers blog.
Related
Problem
In React Native project in my company I came across such code, aggregating exports from multiple modules:
export Icon from "./Icon";
export Input from "./Input";
export Pills from "./Pills";
My editor highlights this as invalid syntax. I checked MDN docs on export and indeed they don't list such a syntax for aggregation. From what they list it seems the proper one would be:
export { default as Icon } from "./Icon";
export { default as Input } from "./Input";
export { default as Pills } from "./Pills";
But then the first code works in React Native project I'm in.
Question
Is this a valid syntax in JavaScript, or is it only available by some third party package we're using in the project?
You are right, but you are not really using ES6 module.
You are using babel, with the metro-react-native-babel-preset. Which make the above syntax valid.
As always, there's a proposal to make it part of the language, but it's currently on stage one.
From the proposal:
The proposed addition follows this same symmetric pattern:
Importing the "default" name (existing):
import v from "mod";
Exporting that name (existing):
import v from "mod"; export {v};
Symmetric "export from" (proposed):
export v from "mod";
In the context of ES6 and Javascript. Syntactically react native method would be not valid. However As the #federkun suggested, it is valid under the context of babel and on the same desk proposal is already made.
However, "default" is used to export default exports which can be exported again
export {default} from '.\example.js'
or you can use name export within curly braces to export only named export. Besides, to export all the named export you can use "*"
export * from '.\example.js'
export {test} from '.\example.js'
Or you can add babel dependency to use the same syntax.
For cases like this,
/ACollectionOfTinyComponent/index.js
import Container from './Container';
export {
Container,
};
So the index.js becomes a directory to include other small parts without having to write each Component Name out all the time.
So in this case, we can import a component in another component like following:
import {Container} from './ACollectionOfTinyComponent'
//then use Container in the code here
Is this a bad practice? Since if I have airbnb linter enable then I got error linting of
Prefer default export import/prefer-default-export
it asks me to add default but that will cause compile error
I found out that because I added only ONE import & export for the index.js. But if I add more than one its fine!
For example, if I do
import Container from './Container';
import Ezeewei from './Ezeewei';
export {
Container,
Ezeewei,
};
Note that I added one more import of Ezeewei.
Then the linting rule will pass!
it asks me to add default but that will cause compile error
You must be using the wrong syntax for exporting a default.
export { name1 as default, … };
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Syntax
import {Container} ... Is this a bad practice?
Yes. If you have a single entry point into a component (like a a class), you should export it as the default rather than a named export. The designers of the language gave default imports and exports a special syntax to promote it as the primary use case.
http://2ality.com/2014/09/es6-modules-final.html#default-exports-are-favored
Say I have these imports:
import clearLineReporter from '../modules/clear-line-reporter';
import karmaReporter from '../modules/karma-reporter';
import metaTestReporter from '../modules/meta-test-reporter';
import stdReporter from '../modules/std-reporter';
import tapJSONReporter from '../modules/tap-json-reporter';
import tapReporter from '../modules/tap-reporter';
import webSocketReporter from '../modules/websocket-reporter';
these must be referenced like I do above, in other words, I obviously can't do this:
const imports = {
stdReporter: import(...),
tapJSONReporter: import(...),
...
webSocketReporter: import(...)
}
Is there any way I can reference imported files through some form of reflection? Because it seems like I can't group them together to reference them somehow.
Instead of import syntax, I could use require(), but I am wondering if there is some way I can do some dynamic things with import statements, for example reference them all dynamically, such that if I add or remove an import, I don't have to change any other code.
There is a great answer to this question that I discovered by asking a different question, here:
exporting imports as a namespace with TypeScript
Create a file name grouped-modules.ts for example, where you want to simply list only the modules and export each one.
export {default as clearLineReporter} from '../modules/clear-line-reporter';
export {default as karmaReporter} from '../modules/karma-reporter';
export {default as metaTestReporter} from '../modules/meta-test-reporter';
...
export {default as stdReporter} from '../modules/std-reporter';
export {default as tapJSONReporter} from '../modules/tap-json-reporter';
Then in your module you can just do :
import * as mods from './grouped-modules'
export {mods}
It will export both types and values in a namespace called s. You can then import them using :
import {mods} from 'your-module'
const anObject: mods.clearLineReporter = ...;
This allows you to dynamically group your modules into one variable.
Is there any way I can reference imported files through some form of reflection?
Answer is dependent on environment, meant in questing, because import statement can be ES native modules implementation in browser, or babel-ed to require statements in node.js, or compile-time resolved bindings in webpack.
So, in each case there is solution to do something reflection. In node.js with babel-ed code import is just require wrapper, so any information is available there.
In browser with native ES modules, all requests to them can be served via ServiceWorker, so it can provide necessary information about fetched ES modules. Also in browser ES modules can be dynamically imported that way: https://matthewphillips.info/posts/loading-app-with-script-module
Most interesting part is webpack: compile-time resolve and semi-reflection can be achieved by externals resolver in functional style (https://webpack.js.org/configuration/externals/#function), and runtime by load module API (https://webpack.js.org/api/module-variables/#webpack_modules-webpack-specific- )
In learning more about ES6/2015 imports, I've come across a couple of cases where I'd like to change the namespace of the default member in the import scope.
Basically the equivalent of import {myMember as name} from 'my-module', but for the default member. I expected something like import defaultMember, {defaultMember as name} from 'my-module', but that seems not to work.
It seems like this should possible:
Mozilla Docs
It is also possible to use the default syntax with the ones seen above (namespace imports or named imports). In such cases, the default import will have to be declared first...
Perhaps not the actual answer, but a solution that I'm using.
For this example, I was using Node-Simple-Schema, and did not want to track imports of it as it is often used across the global scope on the project I'm working on.
The problem is that when import SimplSchema from "simpl-schema'; is used, then "SimpleSchema" as a convention is not available globally.
So I created a code file "SS2.js" and placed the following in it:
import SimpleSchema from 'simpl-schema';
var SS2 = SimpleSchema;
export {SS2};
Then in the working file, I do a subsequent "chained" import and with the following:
import {SS2} from './imports/SS2.js';
SimpleSchema = SS2;
This gives me the default module export convention "SimpleSchema" available globally once again.
This question already has answers here:
`export const` vs. `export default` in ES6
(6 answers)
Closed 6 years ago.
I found a strange situation in ES6. For example, I'm using npm packages react and react-router. I want to import them to the file:
import React from "react";
import { browserHistory } from "react-router";
The strange situation is that I need to wrap browserHistory in figure brackets, but I don't need to wrap React. What is the reason?
import { React } from "react"; // React is undefined
import browserHistory from "react-router"; // browserHistory is undefined
What's the reason that I need to customize my import?
ES6 modules differentiate between two kinds of exports: default exports and other exports.
Every module can have at most one default export. A default export is kind of like the “main attraction” of a module. It’s supposed to be the one thing that you probably meant the module to have. All other exports fit into the other category.
So a module can have any number of exports (even zero), of which at most one can be a default export.
On the export side of the syntax, a default export is simply marked by adding a default after the export keyword:
// this is a normal export
export var foo = 'foo';
// this is a default export
var bar = 'bar';
export default bar;
On the import side of the syntax, this gets a it more complicated: Default exports are imported outside of curly braces. All other exports are imported inside curly braces.
import bar, { foo } from 'some-module';
This would import the default exported member of the module as bar and also import the (named) other export foo. Note that default exports do not have a fixed name: The original name of the member at export time does not matter. Instead, you give it some name when importing it. So you could also write this instead:
import baz, { foo } from 'some-module';
This would still import the same default export from the module, but give it a different name. Other imports however are required to have the correct name, since that’s what’s used to identify them. You can however give them a different name by using the as keyword.
There are a few more things to know when using the export and import statements. You should check MDN for a full description of them.
If the module you are importing has a default export, then you do not have to use the { } syntax to access the given export. Named (non-default) exports must be accessed via the { } syntax. A module can have a default export as well as many named exports.
An example of that would be React which is a default export, but the module also has a named export of Component. To import both of these exports the syntax: import React, { Component } from 'react' would be used.