I would like to access some imports like Rx.Observable or Rx.Subject. Look at the following:
import {Observable, Subject} from 'rxjs'
This is valid but they will be imported into the current scope instead of a namespace.
import {Observable, Subject} as Rx from 'rxjs'
This is not valid.
import * as Rx from 'rxjs'
This is valid but it imports everything and can make file size larger.
Is there a solution?
If you're okay with having an extra JavaScript file to fulfill this purpose, I would suggest adding a new file with the line
export { Observable, Subject } from 'rxjs';
If that was in ./namespaces/rx.js, then in your existing file you could write
import * as Rx from './namespaces/rx.js';
which allows you to have a namespace with only the exports you wanted to target.
Related
I want something like this:
import {get, set} as moduleName from 'module-name'
moduleName.get()
The reason is because sometimes methods of different modules can have the same name, and I don't want to import the whole module because of it
There is no such thing as:
import {get, set} as moduleName from 'module-name'
You can either do it like this:
import * as moduleName from 'module-name';
moduleName.get(); //all the exported items will be accessible.
Or this:
import {get as moduleNameGet, set as moduleNameSet} from 'module-name';
moduleNameGet();
Please check this out
You can use below syntax
import * as module from "module-name";
I was browsing through this repo on Github and was trying to comprehend the working of the code
Here, the author (or programmer) have mentioned import * at multiple places so I am trying to comprehend and understand how import * work?
First in Game.js file of his repo he have mentioned/written like this
import * as actions from '../actions';
In VS Code, when if I click on '../actions using command It is redirecting me to this file -> index.js
then in Index.js they have something like this
import * as ActionTypes from './action-types';
when I click on ./action-types it redirects me to here action-types.js
I went through firefox docs but I wasn't able to clearly make sense for the first example like for one, the action folder contains multiple files and how does import * as actions from '../actions'; mean index.js file
While i get he have called/referenced the functions using actions.functionName() or ActionType.TypeName
My Prime question remains
how does import * as actions from '../actions'; mean index.js file ?
The import * as name syntax imports all exported content of a javascript file.
For example, if you want to import an entire module's contents, then access the doAllTheAmazingThings() function
import * as myModule from '/modules/my-module.js';
myModule.doAllTheAmazingThings();
From the docs
Import in js is new syntax of ES6 to import a module it has the same work of require but its easier to filter what do you want in a module
In your example you import * as actions from '../actions'; you import all function from ../actions file
its same to do const actions = require('../actions')
but its easier to manage what you want
this syntax is not work on all browser so be sure to use transpiler with babel or other
you can see this syntax in python too
When you reference a directory in an import statement, it looks and loads the index.js file in that directory. What I usually do there is export classes and functions under that directory in a grouped object, so they can be easily accessed:
For instance in index.js I export sth like:
{
Class1,
method1
}
where each is imported as such:
import Class1 from './Class1';
So they just group the classes/methods/... that are in files in the directory.
Then you can easily access it as such:
import { Class1, method1 } from './mymodule';
vs
import Class1 from './mymodule/Class1';
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Observable } from '#rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/observable/throw';
#Component({});
export shellModule{}
This is a piece of code form my Angular app that I copied from somewhere (I have removed the definitions in the exported module. I am using it to make a service to call APIs.
In the imports in this particular file, why is it that Observable is imported separately even though the entire rxjshas been imported. If a particular module is being imported in its entirety, why is a particular object from it imported separately? I tried asking this question at the forum from where I took it, but there was no answer. I want to understand if this somehow helps with optimization of code.
In general:
In Typescript, the way modules are handled would require you to either load in the entire library with the import * as rx from 'rxjs/Rx', or a specific exported module within the library to use it, so the the compiler loads in the types.
Reducing your imports to only the specific modules you need sets up your app to use tree shaking from Angular's AOT compilation. This is not done by the typescript compiler, but by a tool called rollup. So, it can help with optimizing code later, but it doesn't automatically do so.
As far as compilation overhead, bringing in the whole library might slow down the compiler a bit... but this isn't a very strong point except for massively complex libraries.
I, personally, prefer importing in specific modules because it makes the calling code a little cleaner since I don't need to use that global name to get to the specific name. rx.Observable vs Observable. A good example of this is the lodash library (rxjs is a bit more complex...)
Honestly, importing entire libraries like the line you have there: import 'rxjs/Rx' doesn't make sense to me. You should only import specific exported modules. Try removing it, seeing what errors you get, and then using the * as rx syntax instead.
As far as rxjs goes - it is a little wonky when you want to import specific operators like this question does - so the way to get specific operators is with: import 'rxjs/add/observable/from' - but that also requires a tinkering with your webpack set up as outlined in the referenced question's answer.
Let's see what the rxjs/Rx module exports:
export { Subject, AnonymousSubject } from './Subject';
export { Observable } from './Observable';
export { Operator } from './Operator';
export { Observer } from './Observer';
export { Subscription } from './Subscription';
export { Subscriber } from './Subscriber';
export { AsyncSubject } from './AsyncSubject';
export { ReplaySubject } from './ReplaySubject';
export { BehaviorSubject } from './BehaviorSubject';
...
import './add/observable/bindCallback';
import './add/observable/bindNodeCallback';
import './add/observable/combineLatest';
...
So it exports RxJs classes and also imports operators from the add folder. So as you can see it loads everything in the library. It doesn't export any global object though. So you need to use named export like this:
import * as Rx from 'rxjs/Rx'
to be able to use an exported class:
Rx.Observable.of(12, 3);
This emulates what you would have if you loaded the library using the bundle - a global Rx object:
<script src="rxjs/bundles/Rx.js">
If you want to use Observable without Rx global object, you need to import it separately:
import { Observable } from '#rxjs/Observable';
Observable.of(1);
Importing both
import { Observable } from '#rxjs/Observable';
import 'rxjs/Rx';
is not a good practice, but may be used if you don't want to import every operator separately.
Also see How to correctly import operators from the rxjs package.
import utilityRemove from 'lodash/array/remove';
import utilityAssign from 'lodash/object/assign';
import utilityRandom from 'lodash/number/random';
import utilityFind from 'lodash/collection/find';
import utilityWhere from 'lodash/collection/where';
let util;
util = {};
util.remove = utilityRemove;
util.assign = utilityAssign;
util.random = utilityRandom;
util.find = utilityFind;
util.where = utilityWhere;
Is there a better way to do the above using ES6 module system?
If these are the only symbols in your module, I would shorten the names and use the new object shorthand to do:
import remove from 'lodash/array/remove';
import assign from 'lodash/object/assign';
import random from 'lodash/number/random';
import find from 'lodash/collection/find';
import where from 'lodash/collection/where';
let util = {
remove,
assign,
random,
find,
where
};
If that could cause conflicts, you might consider moving this section to its own module. Being able to replace the lodash methods while testing could potentially be useful.
Since each symbol comes from a different module, you can't combine the imports, unless lodash provides a combined import module for that purpose.
If you're simply exporting a symbol without using it, you can also consider this syntax:
export remove from 'lodash/array/remove';
export assign from 'lodash/object/assign';
Which, to anyone importing and using your module, will appear as:
import {remove, assign} from 'your-module';
You can do this in a utils module:
//utils.js
export remove from 'lodash/array/remove';
export assign from 'lodash/object/assign';
export random from 'lodash/number/random';
export find from 'lodash/collection/find';
export where from 'lodash/collection/where';
and use it like this:
import * as util from './utils';
...
util.random();
import utilityRemove from 'lodash/array/remove';
import utilityAssign from 'lodash/object/assign';
import utilityRandom from 'lodash/number/random';
import utilityFind from 'lodash/collection/find';
import utilityWhere from 'lodash/collection/where';
let util;
util = {};
util.remove = utilityRemove;
util.assign = utilityAssign;
util.random = utilityRandom;
util.find = utilityFind;
util.where = utilityWhere;
Is there a better way to do the above using ES6 module system?
If these are the only symbols in your module, I would shorten the names and use the new object shorthand to do:
import remove from 'lodash/array/remove';
import assign from 'lodash/object/assign';
import random from 'lodash/number/random';
import find from 'lodash/collection/find';
import where from 'lodash/collection/where';
let util = {
remove,
assign,
random,
find,
where
};
If that could cause conflicts, you might consider moving this section to its own module. Being able to replace the lodash methods while testing could potentially be useful.
Since each symbol comes from a different module, you can't combine the imports, unless lodash provides a combined import module for that purpose.
If you're simply exporting a symbol without using it, you can also consider this syntax:
export remove from 'lodash/array/remove';
export assign from 'lodash/object/assign';
Which, to anyone importing and using your module, will appear as:
import {remove, assign} from 'your-module';
You can do this in a utils module:
//utils.js
export remove from 'lodash/array/remove';
export assign from 'lodash/object/assign';
export random from 'lodash/number/random';
export find from 'lodash/collection/find';
export where from 'lodash/collection/where';
and use it like this:
import * as util from './utils';
...
util.random();