I'm using jspm and SystemJS to import ES2015 modules.
Is it possible to get a list of all of the imported modules in a project through the System object, or anywhere else? I can access my project-specific modules through System._loader.moduleRecords, but the modules that I've installed through jspm (e.g., d3, jquery) do not appear in this list.
System._loader.modules contains a list of all modules, but unfortunately also includes a list of modules required to transpile my code and modules-loading packages.
System._loader.moduleRecords (project modules)
System._loader.modules (project modules, libraries, transpile packages)
I want only a list of declared imports, specifically, those that I've imported using import x from 'x'. This should include both project modules and libraries, but not babel/module-loading related modules. I'd like the solution to not involve filtering using regular expressions.
SystemJS Debugger is probably what you are looking for.
Related
I am new to npmjs package publishing and recently published my 1st package successfully. But since it's written in ES5 style. It is accessed only via "require"
const smiley = require('smiley-id');
What should be done to make it accessible via import statement also? like this
import smiley from 'smiley-id';
or/and
import { smileyId } from 'smiley-id';
require is part of the CommonJS module system (also known as cjs modules) whereas import and export are used in es2015 module system (also known as JavaScript modules, es6 modules or esm modules).
You can use import for both cjs and esm modules, but you cannot use require for esm modules. This means that in an esm module (or source file which you will compile with Typescript tsc or Babel or bundle with Webpack) you can already import your package, as it is, with import. However, you cannot use named imports. Instead you have to destructure the imported item afterwards.
If you want to distribute it as an esm package, this is also possible and it comes with some advantages, out of which the most important is related to tree-shaking. To distribute it as an esm module, you tell your build tool to output esm modules. This is different for different tools. Fortsc for example you specify --module es6 (there are multiple targets that output esm modules). For Webpack, Babel and Rollup, the procedure is different.
In the documentation for Node's native support of ECMAScript modules, they state
There are three types of specifiers:
...
Bare specifiers like 'some-package' or 'some-package/shuffle'. They can refer to the main entry point of a package by the package name, or a specific feature module within a package prefixed by the package name as per the examples respectively. Including the file extension is only necessary for packages without an "exports" field.
...
The definition of bare specifiers indicate you can import ECMAScript Modules from "packages".
What's considered a "package" in Node.js? Does node just search the entire node_modules folder for any folder with a package.json file and consider that a package? Or is it more complicated than that? Is it the same for CommonJS modules and ESMAScript modules?
What's considered a "package" in Node.js?
In the sense of "bare" named packages for ESM, any name that matches a node builtin package, or is in node_modules/{{ bare name }} in the current directory or subsequently any parent directory, that has a package.json that loads and also has the correct name field.
Does node just search the entire node_modules folder for any folder with a package.json file and consider that a package? Or is it more complicated than that?
Basically, node doesn't care about anything you haven't named as an import though. It's always more complicated, the algorithm is documented further down on the ESM modules page.
Is it the same for CommonJS modules and ESMAScript modules?
No, although the part that resolves the package exports is shared once a "package" is located and vetted by the ESM or CommonJS rules). Big differences are
Global node_modules are not considered in ESM (i.e. traversing $NODE_PATH, $HOME and the node $PREFIX).
Outside of the process for loading this subset or "bare names" there are more differences.
ESM modules or mjs files will not load via require.
No native or JSON imports
Generally the ESM loader is a much more strict subset of CommonJS as anything Node specific doesn't apply.
I've been playing around with using es6 modules directly, without using Webpack, rollup, etc. After reading this article, I settled on the following:
import { MyObject } from './node_modules/module_name/index.mjs'
This works fairly well (in both browsers, and node using the esm module and running with node -r esm), but falls apart if you have nested dependencies. For example, if you have two modules that both depend on the same version of a third module, npm will only install a single copy of the third module at the top level, so when the first two modules go looking for it in ./node_modules it doesn't exist.
As far as I know there's not currently away around this other than bundling. Is there any plan for a unified syntax?
A dependency package that I'm using only has module and main as entry points. By default, the webpack version I'm using resolves to module entry point first. If I set resolve.mainFields to main in webpack configuration, I might affect other dependencies that were being resolved by 'browser' entry point by default.
So, the question is, how can I transpile a dependency like that and have it bundled in my bundle in ES5?
Some package writers distributes their ES6 sources, some other don't.
If you can figure out what "modern JavaScript syntax" the dependency is using, In general, the standard format for distributing a module is called CJS or Common JS.
If the author of the package you are trying to use did not export CJS from it's bundle (in 99% they do), then you don't need to transpile anything.
What do you mean by "the other ones"?
Be sure to import the right sources.
I first tested using the commonjs module that I installed like this:
npm install the-module;
I then created main.js which looked something like this:
var module = require('the-module');
module.doStuff();
Then compiled main.js with webpack into bundle.js, loaded it in the browser, and it did stuff.
Now I want to use the-module inside an angular 4 service. How should I import it?
I also found this article on how to create an angular 2 component library. Curious whether this set of steps is required for all commonjs modules that will be imported by Angular or whether there is a more direct approach?
Related Concepts
Ended up writing this article:
using-vanilla-npm-javascript-modules-with-typescript