I'm working on a node project in VS Code with a package.json file that has the "type": "module" set. when I type in an export name from another file the autoImport functionality automatically writes the import statement for me; although I would like it to write the import statement using ES modules syntax. currently, it imports it using require which doesn't make much sense since I wrote the export using ES syntax. how do I get VS Code to behave this way?
// example.js
export default function reader() {}
this is how the import works currently
I use this plugin for auto import. Maybe this plugin will help you too.
Related
I simply can't seem to import classes in Javascript anymore.
My App.js:
My User.js (None of the classes import, but the statement to import this class comes first as you will see in the error) :
The error message:
I know that:
- the paths to the classes are right
- the names of the classes are right and that the IDE recognizes them (the IDE suggests what values need
to be in the constructor)
- This way of importing / exporting the class should be right
It seems that you have a code that was intended for the browser however you're running it with Node.js which 1. doesn't support import and export keywords in .js files; 2. doesn't have document.* APIs.
To make this code work in the browser, it's still recommended to compile it to ES5 code using Babel or webpack first.
I've noticed that React can be imported like this:
import * as React from 'react';
...or like this:
import React from 'react';
The first imports everything in the react module (see: Import an entire module's contents)
The second imports only the default module export (see: Importing defaults)
It seems like the two approaches are different and fundamentally incompatible.
Why do they both work?
Please reference the source code and explain the mechanism...I'm interested in understanding how this works.
Update
This is not a duplicate of What is the difference between import * as react from 'react' vs import react from 'react'
That question was answered with general ES6 module information.
I am asking about the mechanism that makes the react module work like this. It seems to be related to "hacky" export mechanism in the source here but it's not clear how that enables both importing the entire module and just the default export into React and having both of those approaches work with transpiling JSX, etc.
TL;DR
Indeed ES import statements import default and import * are not the same thing, the fact that they behave the same in this case is a combination of how React authors chose to publish the library and compatibility layers in TypeScript (using esModuleInterop) or Babel and your bundler to make them "just work". It probably shouldn't work according to ES6 spec, but today we are still working in an era where JS modules are a mess, so tools like Babel, TypeScript, Webpack, etc try to normalize behavior.
More details:
React is not an ES6 library. If you look at the source code you see this in index.js:
const React = require('./src/React');
// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest.
module.exports = React.default || React;
(Note the comment, even in React source code they struggle with ES6 default export compatibility.)
The module.exports = syntax is CommonJS (NodeJS). A browser would not understand this. This is why we use bundlers like Webpack, Rollup, or Parcel. They understand all kinds of module syntax and produce bundles that should work in the browser.
But even though React is not an ES library, both TypeScript and Babel let you import it as if it is (using import syntax, rather than require(), etc), but there are differences between CJS and ES that have to be resolved. One of them is the fact that export = can give you things that ES has no spec-compliant way to import, like a function or a class as the module. To work around these incompatibilities Babel has for awhile allowed you to import CJS modules as if they were exporting something by default, or import as a namespace. TypeScript for awhile didn't do this, but more recently added that as an option under esModuleInterop. So now both Babel and TypeScript can pretty consistently allow a CJS module to be imported using default or namespace ES imports.
With TypeScript it also depends on how the type-definitions for the library are actually defined. I won't get into that, but you can imagine situations where thanks to transpilers and bundlers a particular import works at runtime, but TypeScript doesn't compile without errors.
Another thing worth mentioning is that if you look at the built code for React there is a UMD module version as well as the CJS version. The UMD version includes some gnarly runtime code to try to make it work in any module environment, including the browser. It's mainly for use if you want to just include React at runtime (ie you don't use a bundler). Example.
Confusing? Yeah, I think so. :)
You most likely have "allowSyntheticDefaultImports": true, set in your tsconfig.json, which essentially shuts the compiler up about default imports it thinks are invalid. Typescript added esModuleInterop which does essentially what babel does for module loading.
This allows you to use ES6 default imports even when the source code you're importing doesn't export anything as default
Typescript is strict (follows the rules) when it comes to this, which is why they require you to import * as React from 'react'. Or requires you to tell it to allow synthetic default imports in its base config.
More On That Here
I use ES6 for a while and have no experience with npm or node.js.
I want to use some npm modules in my project using ES6.
I tried following and got an error
import {axios} from './axios.js';
The requested module './axios.min.js' does not provide an export named 'axios'
I am trying to use https://github.com/axios/axios/blob/master/dist/axios.js
I do not want to use <script src="..."></script> tag implementation. I want to to load it on demand with ES6 modules.
Is there any helper script to adapt npm modules to ES6 or any solution?
import {axios} from './axios.js';
would require Axios to have a named export like
export function axios(...params) { ... }
Axios does have a default export though, which you import without the curly braces:
import axios from './axios.js';
For imports to work in a browser, you need to declare the importing script with type="module":
<script type="module" src="./js/main.js"></script>
Edit:
Checking that URL you gave it seems Axios does not provide an ECMAScript module at all. Importing the way I described will work as long as you're using something like webpack to bundle your scripts.
Edit 2:
I have just filed an issue on the Axios repository regarding the topic: https://github.com/axios/axios/issues/1879
Edit 3 (April 2021):
Three years forward, even Node.js supports ES Modules, but Axios seems stuck on an old code base that looks unlikely to ever get updated, which causes problems when you want to use Axios along with Vue.js 3/Vite build stack, or Svelte.
A 20% the size but not all the features (e.g. interceptors are missing) rewrite in ES6 including proper exports is available with redaxios.
import { default as axios } from 'axios';
I'd like to load/import and use the Bootstrap-table extensions but no luck yet...
The basic module load is fine:
I've added with yarn to the package.json and it sits there like this:
"bootstrap-table": "^1.11.2",
In the javascript file I import it:
import BootstrapTable from "bootstrap-table";
And the usage is fine as well:
$.extend($.fn.bootstrapTable.defaults, {
filterControl: true,
showMultiSort: true
});
$('.element').bootstrapTable();
But (obviously) it doesn't pick the custom options up. How should I load the extensions from the node_modules/bootstrap-table/src/extensions directory?
in ES5 I've had to load those js files one by one, after the bootstrap-table.js. But how does it work in ES6?
Thank you!
To use named imports the package would need to use named exports, I've just taken a look at that package and it doesn't, so you can't import a single module member with the ES6 syntax:
import {Module} from 'my-package';
so you will have to reference the file directly in your node_modules folder:
import FilterControl from '/node_modules/bootstrap-table/dist/extensions/filter-control/bootstrap-table-filter-control.min.js';
It might be worth raising an issue asking the package publisher to add the named exports, which is essentially one file entry point that exports everything for you.
I have gone through 2ality article on Modules, however, I am confused, how does the system know to treat a module as a module?
import React from "react";
import { hello } from "./hello.js";
var Ctrl = React.createClass ({
render : function () {
return (
<div .... random data
></div>
);
}
});
export default Ctrl;
To me, a module is just a file with global code written in it. We reference the module via its filename.
However, I wonder how does this all gel together when we build the production build.
How does the system know that this is a module & not just global varaibles being declared?
Is it the import / export commands that actually make it say: 'aha, this is a module!'
Excuse the newbie question.
Is it the import / export commands that actually make it say: 'aha, this is a module!'
Yes!
More precisely, the import keyword instructs the JavaScript engine (or transpiler) to load an external file as a module.
if by system you mean the browser, it doesn't know, you normally use another tool that implements the idea of modules for you, and it transforms (puts in code) that act as a module system for you that the browser understands.
some tools like do this is require in node, browserify, webpack
that*, not like