why can't I use import/export code in JSX files visual studio - javascript

I have a React app with dozens of files and I don't use any import / export statements. I have a _references.js file that helps intellisense reference components to each other.
I'm looking for a WYSIWYG component to use in my app but all examples show import statements like this:
import { Editor } from 'react-draft-wysiwyg';
When I type this in my JSX file I get:
JSX illegal import declaration
Do I have to configure Visual Studio (2015) differently in order to use this? What is the deal with this syntax and what are the rules around using it?
I am using react for .net so I assume this is what prevents imports from working... but if that is true, then what is the workaround?

Related

Svelte Import Files other than JavaScript

In the svelte example app there are imports like this:
import './app.css'
import svelteLogo from './assets/svelte.svg'
I could not find an explanation on the official documentation.
I am guessing that this is a svelte and not a js feature?
Which files can you import? And how do they get imported, e.g. import './app.css' applies the stylesheet and import svelteLogo from './assets/svelte.svg' appears to save the path in svelteLogo.
I searched "Svelte Import Files other than JavaScript", "js import files" and searched on https://svelte.dev/docs.
It has nothing to do with Svelte or JS, it's something build tools provide.
Common types may be supported out of the box while others require plugins/loaders.
SvelteKit e.g. uses Vite but there are others like Webpack or Parcel.

import * as React from 'react'; vs import React from 'react';

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

How to import a function from a .js file when using Typescript and Vue

I have a Vue.js project that is using Typescript and it is working well but I have an old piece of javascript with a lot of logic in it that I need to use and I would like to import it but I seem to have tried every combination of Import syntax to the .vue file and am unable to load the javascript.
I've tried
import * as revpubeditor from '../modules/revpubeditor'
import revpubeditor from '../modules/revpubeditor'
import { revpubeditor } from '../modules/revpubeditor'
and have also altered the .js file and added a .d.ts file so that it will compile and not give any errors but at runtime in the browser the revpubeditor that I have imported is not found by webpack.
How should this be setup and consumed? I am not worried about it being strongly typed I just want the webpack loader to find the module.

React + TypeScript: 'React' refers to a UMD global but the current file is a module. Consider adding an import instead. (Justification)

We are using React and TypeScript in our current project and I come across below behavior.
import React, { Component } from 'react';
I replace the above line with the one below since it seems to be using Component import only.
import { Component } from 'react';
And I was thrown below error
Error: 'React' refers to a UMD global but the current file is a module. Consider adding an import instead.
I tried looking it up on Stack and GitHub, found few articles and discussion but still unclear about why it's happening.
Would be more interested in whether React or Typescript is throwing it and WHY ? Not the ways to fix it.
Also some light around UMD, why it's used here ?
Are you rendering any jsx in the file? If so, you do need to import React, since those jsx tags compile into calls to React.createElement(). Without the import, the references to React are trying to reference a global variable, which then results in that error.
If you're using eslint, i'd recommend using eslint-plugin-react and turning on the rule react-in-jsx-scope, which will catch this case.
The way JSX syntax is transpiled depends on compiler options, jsxFactory option defaults to React.createComponent. This means that <p/> is transpiled to React.createComponent('p'), and React is expected to exist in the scope of a module.
If there's no React import, it's expected that React global should exist.

How can I use no-typescript React component in TypeScript?

I am beginner in React and Typescript. I have a problem with using react component e.g. https://www.npmjs.com/package/react-toggle-button in typescript.
I generated types by Visual Studio.
Btw import ToggleButton from 'react-toggle-button'; error :/ClientApp/types/react-toggle-button"' has no default export.
So, I imported this way:
import * as ToggleButton from 'react-toggle-button';
<ToggleButton
value={this.state.influencer.billingVATPayer || false}
onChange={(e: any) => { console.log(e) }}
/>
My error:
(TS) JSX element type 'index' is not a constructor function for JSX elements.
Property 'context' is missing in type 'index'.
Can no-typescript modules be imported in some way?
My Typescript version: 3.2.4
My React version: 16.7.0
Thank you advance
Sometimes, packages have an "#types/" version you can install instead of the normal one which includes the types for the items you need/want to import (e.g https://www.npmjs.com/package/#types/react). In cases where this is not an option, you can either:
A) Create your own .d.ts file and create your own types for the package your trying to import as #hazardous mentioned.
Or you can
B) Edit your tsconfig.json file and add the property "allowJs" and set it to true which allows JS files to be imported into Typescript files without the linter or compiler complaining. This is particularly useful in large codebases (or even small) that are transitioning to Typescript and can't immediately convert all of there files/components to Typescript. Shout out to #Juraj Kocan for mentioning this as well.

Categories

Resources