How to troubleshoot es6 module dependencies? - ecmascript-6

I am developing a React & Reflux app, which is bundled by webpack with babel-loader (v6), and I am experiencing es6 modules dependencies issues
For example, I have a component that use the reflux .connect() mixin :
import MyStore from '../stores/my-store';
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
When I import all modules individually in each file like this, everything's fine.
I then tried to improve my code by using deconstructed import statements :
...in a component :
//import One from '../js/one';
//import Two from '../js/two';
//import Three from '../js/three';
import { One, Two, Three } from '../js'; // Instead
...and in js/index.js :
import One from './one';
import Two from './two';
import Three from './three';
export { One, Two, Three };
App source code files are more concise using the above technique, because I can import all components in one import line.
But when I use this, some dependencies end up beeing undefined when I use them
If I use the same updated example...
//import MyStore from '../stores/my-store';
import { MyStore } from '../stores'; // Instead
const Component = React.createClass({
mixins: [Reflux.connect(MyStore)]
});
...MyStore parameter ends up undefined in Reflux.connect method.
I tried to troubleshoot in the debugger, but I'm not really aware of what's going on with the __webpack_require__(xxx) statements in the generated bundle. There must be a circular dependency that babel-loader or webpack require could not figure out when there are the index.js files re-exporting individual modules.
Do you know any tool that can help me figure this out? I tried madge but it does not work with es6 modules, and I could not find anything that would tell me where anything is wrong

In order to get extended info about build, run:
webpack --profile --display-modules --display-reasons
It will give you bunch of information for optimisation/profiling.

import statement is used to import functions, objects or primitives that have been exported from an external module.
As per MDN doc, you can import the Modules not the directory.
import name from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as alias from "module-name";
import defaultMember from "module-name";
import "module-name";
Reference URL:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
http://es6-features.org/#ValueExportImport
https://github.com/lukehoban/es6features#modules
http://www.2ality.com/2014/09/es6-modules-final.html
As a workaround keep one file as base.js and include all your 3 files.

Related

ES6 Destructuring imports and apply an "as"

I would like to know if something like:
import { faPause,
faLevelUpAlt,
faExchangeAlt,
faCircle,
} as SolidIcons from '#fortawesome/free-solid-svg-icons';
=> SolidIcons.faPause
I know there is:
import * as everything from '#fortawesome/free-solid-svg-icons';
=> everything.faPause
But that is not what I want because it imports everything from the library..
I don't think that what you've listed is possible under the syntax, but you should be able to bundle your imports into an object after the fact to simulate it. Something like
import { faPause,
faLevelUpAlt,
faExchangeAlt,
faCircle,
} from '#fortawesome/free-solid-svg-icons';
const SolidIcons = { faPause,
faLevelUpAlt,
faExchangeAlt,
faCircle,
};

Create an "Import Menu" in TypeScript

I'm trying to work on a project with a numerous amount of files, and I thought an import object would be helpful. For example, here would be menu.ts on the top-level, which every program will reference to:
import router from "./router/index";
import controllers from "./controllers/index";
import config from "./config";
export default {
router: router,
controllers: controllers
config: config
}
This would be a sample controllers/index.ts:
import database from "./database";
import accounts from "./accounts";
import a_controller from "./a_controller";
export default {
database: database,
accounts: accounts,
a_controller: a_controller
}
Obviously, this would raise some circular dependency issues with controllers referencing to menu. This is asserted with a TypeError: cannot read property controllers of undefined error message. Is there a way to do this?
Thank you for your time.
in your case it is better to use named import, in controllers/index.ts: you can do like:
export { database } from "./database";
export { accounts } from "./accounts";
export { a_controller } from "./a_controller";
and in your menu.ts you can import them like:
import { database, accounts, a_controller } from './controller'

How to import external JavaScript into Polymer 3.0

Let's say I have a traditional javascript library such as google-charts and I wanted to incorporate that into my Polymer 3.0 project. How would I actually do the import?
This is how I would traditionally do it: https://developers.google.com/chart/interactive/docs/quick_start
ES Modules on NPM
Normally, one would prefer an ES module version of such a library if available (e.g., on NPM), since ES modules allow tree shaking (by Polymer CLI in this case) to reduce the size of the production build output.
Modules are loaded in JavaScript with the import keyword. If available on NPM, the library could be installed in your Polymer project with the npm-install command. For instance, you'd install google-charts like this:
npm install --save google-charts
Then, import that package in your element code:
import { GoogleCharts } from 'google-charts';
Example:
import { PolymerElement } from '#polymer/polymer';
import { GoogleCharts } from 'google-charts';
class MyElement extends PolymerElement {
// ...
ready() {
super.ready();
GoogleCharts.load(/* ... */);
}
}
demo
Non-ES Modules (not on NPM)
On the other hand if ESM is unavailable, the script is likely an AMD/UMD module, which adds symbols to the global scope. In that case, you'd still import the file, and access the global as you normally would had you used the <script> tag.
If the script is not on NPM, you'd have to copy the file locally into your project (and include the library file in your release), and then import the file by path. For example, if you copied the library to <root>/src/libs/google-charts.js, the element code at <root>/src/components/Chart.html would import it like this:
import '../libs/google-charts'
Example:
import { PolymerElement } from '#polymer/polymer';
import '../libs/google-charts' // adds GoogleCharts to global
class MyElement extends PolymerElement {
// ...
ready() {
super.ready();
GoogleCharts.load(/* ... */);
}
}

How is path interpreted when using SIRD in Play framework

The following example is from Play's documentation
To use the routing DSL in conjunction with a regular Play project that uses a routes file and controllers, extend the SimpleRouter:
package api
import javax.inject.Inject
import play.api.mvc._
import play.api.routing.Router.Routes
import play.api.routing.SimpleRouter
import play.api.routing.sird._
class ApiRouter #Inject()(controller: ApiController)
extends SimpleRouter
{
override def routes: Routes = {
case GET(p"/") => controller.index
}
}
Add the following line to conf/routes:
-> /api api.ApiRouter
Question - In the above example As /api already maps to ApiRouter, does GET(p"/") resolve to somedomain.com/api/ or somedomain.com/
It will resolve to somedomain.com/api/, that is the main idea of the SIRD - it allows you to modularize routers.

es6 import 'destructuring' not working

Hey there I have this uiTypes.js file like this:
export default {
SELECT_ITEM: 'SELECT_ITEM',
DESELECT_ITEM: 'DESELECT_ITEM',
TOGGLE_ITEM: 'TOGGLE_ITEM',
}
And when I try importing its content like so, it works:
import uiTypes from './uiTypes';
console.log(uiTypes.SELECT_ITEM) // 'SELECT_ITEM'
But not like this:
import { SELECT_ITEM, DESELECT_ITEM, TOGGLE_ITEM } from './uiTypes';
console.log(SELECT_ITEM) // undefined,
Am I missing something?
There is no destructuring for imports (notice also that exports and imports use the keyword as instead of a colon to avoid confusion with objects). You can either import the default export, individual named exports, or the module namespace object.
Your attempt is trying to import three named exports, while there is only a default export; that's why it's failing.
You should use named exports:
export const SELECT_ITEM = 'SELECT_ITEM';
export const DESELECT_ITEM = 'DESELECT_ITEM';
export const TOGGLE_ITEM = 'TOGGLE_ITEM';
or use "real" destructuring after importing the object:
import uiTypes from './uiTypes';
const {SELECT_ITEM, DESELECT_ITEM, TOGGLE_ITEM} = uiTypes;