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.
Related
I have just started with Typescript for a front-end web project. My goal is to use a OOP approach. So my convention is one class by file (named from the class it contains).
Consider this example:
//Car.ts
export default class Car {
public startEngine (): void {
console.log('vroom!');
}
}
//RaceCar.ts
import Car from './Car';
export default class RaceCar extends Car {
public startEngine (): void {
console.log('!!VROOOOOMM!!');
}
}
//index.ts
import RaceCar from './RaceCar';
import Car from './RaceCar';
const car:Car = new RaceCar();
car.startEngine();
This code works fine but I have 2 questions:
When I use the convention "one class per file" (with default export) it is really annoying to write import Car from './Car';. Is there a short way to do this? Like a macro or something? I have tried import './Car'; but of course this does not import Car symbol...
Another annoying thing is to import Car and RaceCar in index.ts. Is there a way to import only RaceCar that already knows the Race class?
In other words I am looking for a way to do something like a C++ include.
When I use the convention "one class per file" (with default export) it is really annoying to write import Car from './Car';. Is there a short way to do this? Like a macro or something? I have tried import './Car'; but of course this does not import Car symbol...
To use the Car, the code will have to say import Car from './Car'. This syntax basically means "run the code in ./Car, and assign its default export to Car". import './Car' is legal, but it means "run the code in ./Car, but i don't need to use what it exports".
That said, various IDEs can help you fill the import in automatically. For example, i use Visual Studio Code, and if i use Car somewhere in my code without importing or defining it, i get the red underline and can then press ctrl-space to automatically import it in most cases.
Another annoying thing is to import Car and RaceCar in index.ts. Is there a way to import only RaceCar that already knows the Race class?
If you need to directly reference any of the things exported by the Car file, then you'll need to import it. In your example, you're using Car as a type. If you need that, then you need to import it. That said, in your situation i'd probably just use RaceCar as the type, since that's what you're newing up anyway.
import RaceCar from './RaceCar';
const car: RaceCar = new RaceCar();
car.startEngine();
TypeScript uses +ES6 syntax:
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Import an entire module for side effects only, without importing
anything. This runs the module's global code, but doesn't actually
import any values.
import '/modules/my-module.js';
You need to import the symbol you want to use:
import myDefault from '/modules/my-module.js'; // myDefault is the default exported symbol in the module.
Therefore, no. You always need to import the symbol you want to use explicitly and only from these code places where you need to use them.
I'm learning Javascript ES6 on codecademy and there´s a lesson about named exports and export as statement. For example:
export { specialty as chefsSpecial, isVegetarian as isVeg};
My question is about what are the benefits of using export as rather than named exports like:
export let specialty = '';
or
export { specialty, isVegetarian };
So far my thought is that export as could be used for variable names standarization in projects, but haven´t come up with further advantages on makeing use of it.
also, do developers make use of this export as functionality? I´ve tried to get answers on the web but everything that's about exports and imports doesn't mention anything about export as .
Using as just allows you to define the symbol name of the export if you want it to be different than the name is locally.
So your publicly exported symbol name can be something different than you use locally.
My question is about what are the benefits of using export as rather than named exports like:
There's no particular benefit if you're happy with the internal name being the same as the exported name. If you want a different exported name, you can either rename everything locally to the new name or use export as to change just the name of the exported symbol.
So far my thought is that export as could be used for variable names standarization in projects, but haven´t come up with further advantages on makeing use of it.
I could imagine it being convenient to centralize the definition of the exported symbols in one place without forcing the definition of the functions themselves to be all in one place. If you were designing the code originally to be exported and publicly reusable, then you'd probably just name things from the beginning with an appropriate exported name and not use export as. But, if you had a body of existing code that you were now trying to put a wrapper around and for various reasons you didn't want to rename a lot of things internally, I could see some convenience to using export as.
Keep in mind that it's just a syntactical convenience. These two scenarios are functionally equivalent:
function sayGreeting() {
console.log("hi");
}
const greet = sayGreeting;
export greet;
And this:
function sayGreeting() {
console.log("hi");
}
export {sayGreeting as greet};
Or, of course you could have just written it like this in the first place:
export function greet() {
console.log("hi");
}
Personally, I agree with Geuis that import as is more useful than export as and the canonical use for import as is when you're importing two modules that both define the same symbol name (a name collision which can happen in the real world), then you can use import as to change the local symbol name to something that does not conflict with the other module you are importing.
This is the best reference article I've found on import and export syntax:
ECMAScript 6 modules: the final syntax
I am trying to make my Meteor code ES6 compatible. I had a file called /both/global.js containing functions and constants that I wanted to be accessible globally. For ES6 purposes, I moved it to /both/imports/global.js and prefaced all the functions and constants with export const.
I haven't changed the whole directory structure yet. The template javascript files are still in /client/controller/. I have added to them import statements for the exported functions and constants. When I write the import statements in the form:
import { fn1, fn2, ... } from '../../both/imports/global.js';
they work fine.
I would rather import all the functions and constants with a single:
import from '../../both/imports/global.js';
but that doesn't seem to do anything.
What am I doing wrong?
It's to do with the way imports and exports work.
What you need is
import * from '/both/imports/global.js'
Alternatively...
import something from '/both/imports/global.js'
Will look for the default export, and assign it to the variable called something.
import { fn1, fn2, ... } ...
Will import the named variables into your namespace
Another way is to do this:
import globalFunctions from '/both/imports/global.js'
Then your functions are callable like this:
globalFunctions.fn1()
globalFunctions.fn2()
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- )