EcmaScript 6 module requiring, how does it work? - javascript

So I know how to require and export modules in ES6. But for frameworks like Aurelia, the docs say that you require aurelia like so:
import {LogManager} from 'aurelia-framework';
Do I have to place a JS file named aurelia-framework in the folder where the JS file I'm executing it from resides, or does the import function work similiar to the require function in NodeJS/CommonJS?

According to this article ES6 modules spec only deals with loading modules that are present in the file path. Downloading these files (via NPM or by other means) is outside of scope of ECMAScript 6 modules spec. Nothing is said in the spec about supporting npm package includes (traversing the directory structure down to the /, one directory at a time, looking for a package.json file and then searching within the node_modules directory where package.json file is found). So while the import syntax is similar to commonJS style, the whole magic of looking for modules in the node_modules directory is not included.
So for your example to work, aurelia-framework must be a javascript file somewhere in your file system and it should contain an exports statement.
import {LogManager} from 'aurelia-framework'; // ./aurelia-framework.js
import {LogManager} from '../libs/aurelia-framework'; // ../libs/aurelia-framework.js

with Aurelia, you can install dependent libraries using jspm. you can see an example of that here. jspm will get the packages for you and bring them into subfolders in your project. jspm uses an index (stored in config.js) to know where to locate the files (similar to how requirejs, but works for amd, commonjs, and es6 modules).
there is also an example of using the aurelia libraries with requirejs amd loader. this example uses a bundle of aurelia libraries generated by r.js as shown here

Related

How to add compiled javascript library to typescript project?

I have an Typescript project (ProjectA) that uses few nodes packages. Aside I have babel project (ProjectB) which build configuration supports output for multiple module definition standards: amd, common.js, esm.
Is it possible to incorporate compiled ProjectB into ProjectA?
So far inside ProjectA i have created folder for ProjectB-dist, and placed there all of the outputs of ProjectB.
Inside one of the .ts files I have tried to import ProjectB as:
import ProjectB form './ProjectB-dist/output.common.js'
I have placed types for this project inside my #types folder. But compiler complains:
Could not find a declaration file for module './ProjectB-dist/output.common.js'.
Maybe I'm missing something with module concept?
If you want to import a library, just use the path to it (without the .js extension): import "./ProjectB-dist/output.common". If after doing this the compiler still complains about a declaration file, then create that file named output.common.d.ts in a directory and put the following into it:
declare module "./ProjectB-dist/output.common";

Publishing both es6 and commonjs with subfolders

I want to be able to import module from subfolder like this, without any lib folder, https://davidwells.io/blog/publishing-flat-npm-packages-for-easier-import-paths-smaller-consumer-bundle-sizes/
I want to publish both CommonJS and ES6 modules
I can specify the main file for commonjs with "main": "./index.js" and for es6 with "module": "./index.es.js" in package.json.
But how does it works when I import my-package/myfile ? Is myfile.js used or myfile.es.js
And why it isn't possible to specify a subfolder instead of a single main file ?
There's not a lot of magic going on in that blog post you mentioned, he's just asking for node_modules/his-module/P.js
The bundlers need a single entry because (in theory) that is where you have your
module.exports = {}
code which is what lets the bundlers access your functions.
If you are using an esmodule compatible bundler like webpack or rollup, they will read the module key
import someFunction from 'your-module';
Would import the es module unless you are using something like browserify which would take the commonjs version.
You can also ask explicitly for a different file
import someFunction from 'your-module/lib/index.min.js';
Whatever file you ask for here, it'll import that. If you add a / after your-module you are now breaking out of the main or module path conventions and asking for whatever file you want.

import requirejs amd module with webpack

I'm using Converse.js and it's prebuilt into the RequireJS/AMD syntax. Including the file from a CDN you could use it like require(['converse'], function (converse) { /* .. */ }). How is it possible to use this with webpack? I would like to bundle converse.js with my webpack output.
I have the file on disk, and want to import it like
import converse from './converse.js';
converse.initialize({ .. });
Webpack picks up the file and bundles it correctly, although it's not useable yet as it throws 'initialize is not a function'. What am I missing?
I suspect the way their bundle is built will not work correctly with how Webpack evaluates modules in a limited context.
From their builds, taking the built AMD module via NPM without dependencies should be parsable by Webpack and it will enable you to provide the dependencies to avoid dupes in the final output.
If all else fails, using the script-loader will evaluate the script in the global context and you'd get the same experience as if you'd have followed their usage guidelines to reference it from a CDN, just don't forget to configure the globals for your linter.

Using node modules with Rollup to build web client

I'm trying to build a react application using rollup instead of browserify and babel. I realize I need to use the rollup-plugin-babel to transpile jsx, but when I tell rollup the format is iife, the final page loads with an error:
Uncaught ReferenceError: React is not defined
What do I need to add to the rollup.config.js to include the node modules I've installed in package.json in my final build?
Two options:
Include React as a separate <script> tag before your app bundle
Include rollup-plugin-node-resolve in your config file, to pull in dependencies from your node_modules folder.
If you take the second route you'll also need rollup-plugin-commonjs (to convert the CommonJS module into an ES module). I think you would also need to add import * as React from 'react' to each module that contained JSX, otherwise you'll continue to get the ReferenceError.
Note: you might be able to use rollup-plugin-buble to transpile JSX. It's similar to the Babel plugin but much faster (though it doesn't transpile every ES2015 feature)

ES6 module import and dependency management

With the use of transpilers it is already possible to use ES6 modules. One of the easiest ways is using Browserify and Babelify.
The problem I'm having is how to handle dependency management.
In the old days you'd just have some Bower dependencies. The build would bundle non-CDN to vendor.js and project specific files to foobar.js (or whatever).
So then you'd be able to use the resulting code in a different project by simply bower install foobar --save.
If both foobar and your new project had a common dependency it would be easily resolved with Bowers flat dependency.
Now in come ES6 modules:
Say I have a project foo using lodash. The directory structure is as follows:
src/js/foo.js
src/vendor/lodash/dist/lodash.min.js
And foo.js starts by declaring:
import * as _ from '../../vendor/lodash/dist/lodash.min.js';
or (as Browserify wants since Babelify transpiles to CommonJS):
import * as _ from './../../vendor/lodash/dist/lodash.min.js';
If I now round up and publish my foo project and start a new project bar that uses foo this will be my directory structure.
src/js/bar.js
src/vendor/foo/dist/foo.js
src/vendor/lodash/dist/lodash.min.js
But that would not work since the path from foo to lodash is now broken (if I understand Browserify correctly the dot-slash in './blaat/file.js' is relative to the file it's being called from).
Is some way to import without making any file path assumptions?
Isn't there some way to indicate multiple source roots? (ie in the above case src/js and src/vendor ... well, ideally you'd just want to state import * as _ from 'lodash';)
I've only used Browserify with Babelify on cli. Should I be using some other transpiler?
I think that jspm is the solution your looking for. It will help you out without making file path assumptions when importing modules. It uses the SystemJS dynamic ES6 loader. Watch the video that is posted on their site for a very good explanation on how it all works, Guy Bedford: Package Management for ES6 Modules [JSConf2014].

Categories

Resources