Webstorm ES6 named import getting cannot resolve symbol error - javascript

I have an error in Webstorm when using ES6 named import declaration:
import { nodes } from 'utils/dom';
I get "cannot resolve symbol" error on "nodes"
Also when I try to export as named export like this:
export {
write: document.write.bind(document),
node: document.querySelector.bind(document),
nodes: document.querySelectorAll.bind(document)
};
I get errors too.
I use eslint with babel-eslint parser.
The thing is that this works in Sublime Text 3 as a charm, but for some reason fails error checking in Webstorm.
I assume that this is because except Eslint webstorm is doing other code checking.
Any Idea how I can suppress that and use only eslint with babel-eslint parser?
Any advice will be appreciated

I get "cannot resolve symbol" error on "nodes"
is because utils/dom in standard Node code means "find dom.js inside a module called 'utils'. You have overridden this behavior by using webpack's moduleDirectories property, but WebStorm doesn't know what that is. For WebStorm to properly resolve utils/dom, you'll need to add the utils folder as a library in your webstorm project configuration.
Your export syntax is incorrect. ES6 import/export syntax is 100% unrelated to objects, and in your example export, you are using object syntax. import { nodes } is asking for an export named nodes. There are multiple ways that you could write the exports that you have:
export const write = document.write.bind(document);
export const node = document.querySelector.bind(document);
export const nodes = document.querySelectorAll.bind(document);
or alternatively you could collapse them if you like multiline var/let/const
export const write = document.write.bind(document),
node = document.querySelector.bind(document),
nodes = document.querySelectorAll.bind(document);
or even
const write = document.write.bind(document);
const node = document.querySelector.bind(document);
const nodes = document.querySelectorAll.bind(document);
export {write, node, nodes};

Hard to say if this is directly related, but for Webstorm to know how to resolve your imports, you can also go to Preferences > Directories and set folders as Resource Root (or right/context-click on a folder and set it that way)
This might need to be done, for example, when you've configured Webpack to resolve certain sub-directories, where your project structure might be:
/
/docs
/src
/containers
/app
App.js
/components
/header
Header.js
In which case Webstorm would expect an import in App.js to look like the following:
import Header from '../../../components/header/Header'
Whereas with Webpack, if you've added src as a module to resolve, you can do the following, which Webstorm doesn't currently understand, hence adding it as a Resource Root resolves the issue
import Header from 'components/header/Header'
Reference: Path aliases for imports in Webstorm

Related

Resolving compiled default exports with ES6 syntax

I have a module, say as follows:
const awesomeFn = () => ...
export default awesomeFn;
It is built into ES5 using babel, and when I created another ES6 module, I want the following syntax:
npm i awesomeFn
// ./index.js
import awesomeFn from 'awesomeFn';
awesomeFn();
But this throws. Logging awesomeFn gives me { default: _default [Function()] } (or something like that), hinting that I'd need to do something like
import awesomeFnPackage from 'awesomeFn';
const { default: awesomeFn } = awesomeFnPackage;
How can I form my exports so that I don't have to do the default destructuring? Should I avoid default exports altogether for this reason?
Somewhat strangely, this works if:
I use esm, like so node -r esm index.js but not if I use mjs as the file extension (with "type": "module" set), only js
It doesn't work with --experimental-modules, --experimental-specifier-resolution=node nor "type": "module" in package.json,
In every non-working case, the import value is { default: [Function: awesomeFn] }, only with esm is the value [Function: awesomeFn]
So I guess that's the solution right now; rely on an external package for expected behaviour, or use named exports, which do work as expected. What is going on with this?
Solution provided here, which is to destructure the default property as stated in the question, or add yet another dependency to intuitively use es6 imports.
I'll leave out the reasoning for why this choice was made by Babel to the reader to research for brevity. My conclusion is to use ES5 or not to use default exports. ES6 syntax is a mess in the context of import/exports as of writing, not only in the context of this question, but in the context of npm packaging, file extensions, flags, package.json properties, etc.
Hei, it looks like a problem with your setup. Default functions are named "default" when exported (ES5).
You can probably destructure directly in the import statement like this:
import { default as awesomeFn } from 'awesomeFn';
awesomeFn()

Rollupjs Leave imports unchanged

My input file looks like this:
import * as chalk from 'chalk'
const chalkInstance = new chalk.Instance({
level: 1
})
My output file looks like this:
import { Instance } from 'chalk';
const chalkInstance = new Instance({
level: 1
});
The problem is that chalk is a commonjs module and I want to my output to be an es module so when I execute the file I get the following error: The requested module 'chalk' is expected to be of type CommonJS, which does not support named exports etc. Is there a way to prevent Rollup from changing the import * as something imports? The problem doesn't go away even if I disable treeshaking.
Thank you in advance!
Preserving the import as typed won't help you — you need to do import chalk from 'chalk' instead, since CommonJS modules only have a default export. If you do preserve the import you'll still get an error, it'll just be a different error:
const chalkInstance = new chalk.Instance({
^
TypeError: chalk.Instance is not a constructor

How to publish a library to npm that can be used both with import and require?

tealium-tracker is written in es6 and transpiled using Babel before published to npm.
When consumers do:
import initTealiumTracker from "tealium-tracker";
everything works as expected.
However, some consumers want to use a require instead of an import, and have to append .default:
const initTealiumTracker = require("tealium-tracker).default;
How could I publish the library to avoid appending .default?
I want consumers to be able to do either:
import initTealiumTracker from "tealium-tracker";
or
const initTealiumTracker = require("tealium-tracker);
Source code
In your source code, If you are ok with using commonJS syntax for import and export...
One option would be to replace all import and export with require and module.exports. Looks like webpack doesn't allow mixing the syntaxes (ES6 and commonJS modules).
So your index.js file can require the functions from dependent module as
const { callUtag, flushUtagQueue } = require("./utagCaller");
and export the default function as
module.exports = initTealiumTracker;
module.exports.default = initTealiumTracker;
Likewise your dependent module can export the functions as
module.exports = { callUtag, flushUtagQueue };
This way, consumers should be able to use either
import initTealiumTracker2 from "tealium-tracker";
OR
const initTealiumTracker1 = require("tealium-tracker");

Import JS web assembly into TypeScript

I'm trying to use wasm-clingo in my TypeScript React project. I tried to write my own d.ts file for the project:
// wasm-clingo.d.ts
declare module 'wasm-clingo' {
export const Module: any;
}
and import like this:
import { Module } from 'wasm-clingo';
but when I console.log(Module) it says undefined. What did I do wrong?
Notes:
clingo.js is the main js file.
index.html and index_amd.html are two example pages
Solution:
I solved the problem like this:
// wasm-clingo.d.ts
declare module 'wasm-clingo' {
const Clingo: (Module: any) => Promise<any>;
namespace Clingo {}
export = Clingo;
}
and
import * as Clingo from 'wasm-clingo';
Here's the source for this solution
I know you found a solution acceptable to you; however, you don't really have any types here, you just have Module declared as any, which gives you no typescript benefits at all. In a similar situation I used #types/emscripten, which provides full type definitions for web assembly modules compiled using emscripten. You simply need to do:
npm install --save-dev #types/emscripten
then change your tsconfig.json types array to add an entry for emscripten.
After that you can just write Module.ccall(...) etc. If you like you could of course write const Clingo = Module and then make calls against that if you want a more descriptive name than Module (which is a terrible name!).
You're welcome ;)
I think the issue is that wasm-clingo exports the module itself but import { Module } from 'wasm-clingo' expects a property.
Try
import Clingo_ from 'wasm-clingo';
const Clingo: typeof Clingo_ = (Clingo_ as any).default || Clingo_;

TypeScript: Can I mix using "import * from" and "require(*)"

Is it ok in TypeScript to mix these too 'include' types?
import { SomeType, someFunc } from "./MyThings";
And:
import events = require('events');
The first would be a TypeScript module with an export or two... and the second is just a node module called events (I guess this could be anything pulled in from NPM too).
Am I ok to mix these two conventions in a single TypeScript file?
Yes, this is acceptable in TypeScript.
When using the import foo = require('foo');, you must have a module 'foo' declared with declare module 'foo', typically in a .d.ts file.
This is typically covered in node.d.ts.

Categories

Resources