I've this code, it's a react typescript project:
import { Trans, translate, InjectedTranslateProps } from 'react-i18next';
and then:
export const Home: React.SFC<InjectedTranslateProps> = props => (
When i click on webstorm on InjectedTranslateProps, it's take me to /node_modules/#types/react-i18next/src/props.d.ts
why is taking me to #types and not to 'react-i18next' package ?
i mean all the links take me to #types and not the right folder for react-i18next in node_modules
so, everything pass by #types, and i's that library to connect it with the real package?
i don't need to see javascript code, just need to see if imports go first to the typescript file, and it's that file that do the work to import.
At runtime, your module loader will resolve the import directly to the real implementation. When the TypeScript language service sees an import, it only cares about the type information and not the implementation, so if the implementation file is a .js file and doesn't have a .ts or .d.ts alongside it, the language service will look for a .d.ts in a #types package. When you click on the import, the language service takes you to the .d.ts. As I understand it, the reasons for this behavior are:
It was easier to implement since the language service is already finding the .d.ts and not the .js.
Assuming you are writing code based on an API (which is more orthodox from a software engineering point of view than looking at the implementation, although I know that in the real world, developers often have questions that won't be answered by the API documentation), then the .d.ts is more likely to describe the API in human-readable format than the .js, which for real-world modules (especially those that have gone through some transpilation process) may be organized using any number of tricky code patterns as long as all the right elements end up defined when it is done loading.
Related
I got a job back in August, and most importantly through this pandemic, I've actually kept it too!!
As a side project I wanted to learn to create a react component library for my own use (far from complete) with Rollup for it's tree-shaking + plugins for cjs, udm, etc. for compatability.
When I compile with TSC it's almost perfect now that I've tweaked a couple of things regarding organization and a separate build TSConfig.
My TSConfig
My Build TSConfig
My Rollup Config
I'm not sure if there's any glaring issues that anyone can see at first glance or not, I've tweaked a bit here and there trying to get rollup to even work in teh first place, but it's obviously not resolving correctly otherwise I wouldn't be here! :D
Side note: Despite setting up a custom.d.ts in the root for declaring svg imports with svgr, TS still isn't understanding the declaration and throws a type error:
declare module '*.svg' {
import React = require('react')
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>
const src: string
export default src
}
I say TSC Config is almost perfect, but there's a few things I'm aware of:
I'm not sure that TSC compiling is good for Tree-shaking. Correctly me if I'm wrong here, but that's why Rollup is a thing, right?
TSC doesn't seem to transforming my path aliases within the config, where I have '#app' for 'src' to beat the '../../../../' resolving.
When I try to use Rollup I come into two different issues entirely:
Despite having the types in a folder ./src/types/*.ts I don't have a root level declaration file within my 'dist' folder, they're scattered amongst the individual component folders for their props.
Not all props and types that are for sure utilized in exported components etc. are being exported, there are several components that are having (_a: any) are their props which is obviously a very back experience to work with.
I'm not sure if it's resolving / transforming my path aliases either, so that's something I have to double check.
If anyone can aid in this issue I'd be eternally grateful! I've already searched through Google/Reddit/SO for anyone with similar issues as I can I haven't come across any solutions that have worked successfully.
I've created a few apps that follow the same pattern as the react-microfrontend projects listed on the Single-spa examples page. However, these examples are not using TypeScript.
I am receiving a TS error when App2 tries to import a function that exists in App1, because App2 is unable to find the typings for the App1 object. And this makes sense to me, since the importmap.json that is referenced in the index.html file of the root-config project only has a URL listed for the .js file of each microfrontend. I really don't want to add #ts-ignore statements everywhere, and I also don't want to do cross-app communication without being type safe.
An example of what I'm referring to:
This file in the Planets app references the Button component from the Styleguide app. I am unable to build this unless I place a #ts-ignore on the line before the import statement, because my Planets app cannot find the type declarations for Styleguide.
I am very new to import maps and SystemJS in general, so if anyone could point me in the right direction, I'd appreciate it. I've actually gone through the trouble of building my Styleguide as a regular npm library and just including it as a dependency in the Planets package.json file... which kind of defeats the whole purpose of using Single-spa in the first place.
importmap.json
{
"imports": {
"#react-mf/planets": "//localhost:9000/react-mf-planets.js",
"#react-mf/styleguide": "//localhost:9001/react-mf-styleguide.js"
}
}
page.component.ts
// #ts-ignore
import { Button } from "#react-mf/styleguide";
...
render() {
return (
// Unable to view the available props
<Button label="Hello World" />
);
}
Unfortunately no, they cannot be shared via the import map because that operates in the browser, and browsers do not understand TypeScript syntax.
Your alternatives are:
Publish your module's types to an npm registry and npm install it into each dependent microfrontend
One caveat here: you will need to update this with every new publish of the shared module, but that can be automated with various tools such as renovate
Mock the utility module's types
More info can be found at this Github issue: https://github.com/single-spa/single-spa/issues/609#issuecomment-665132965
In the case of react native web we have a possibility to use files with .web and .android extensions.
Eg.
myFile.web.js
myFile.android.js
then we can include them via
import myFile from './myFile';
and React native web automatically provides proper file content depends on the platform.
It works so far but after I added Typescript the ts compiler started to complain about the missing module 'myFile' and it's logically okay because we don't have this file and TS compiler doesn't know that the RNWeb will automatically pick a proper file later.
When I disabling Typescript, everything works fine so the system is working.
The question is how to solve it in the case of Typescript?
Thanks for any help.
The only way I found how to avoid this issue is using CommonJS module system - require instead of ES6 - import standard
Example: const MyFile = require('./myFile')
In this case, the TS compiler will ignore it. Unfortunately, it isn't a perfect/right solution as I'd like to see but it works so I just use it as is.
P.S. If someone finds another way, please, provide your solution, I'll be appreciated.
I have a sort of a "monorepo", one big project consisting of a few smaller projects that use React.
I'm trying to break these up into three separate repositories, lets call them Core, Application1, and Application2
The Core is a dependency of both applications, and the Core depends on React, because it defines some React component classes. The applications both also use React.
When I tried to build this all together (using Parcel bundler), I am getting a final bundle which at runtime gives the Invalid Hook Call warning in one (but not both) of the applications.
On that page (or in the error message), it says that the error could be caused by one o these:
You might have mismatching versions of React and React DOM.
You might be breaking the Rules of Hooks.
You might have more than one copy of React in the same app.
I have checked that #1 is not true, and I'm not even using hooks in any way that I am aware of, so the problem is seems to be multiple versions of React.
I gathered from reading about this that it was a mistake for my Core library to declare React as a dependency, and that it should instead declare it in peerDependencies. That made the Application stop giving the error, but it also made my Core library start having a bunch of Typescript errors and failing to be able to run the unit tests (which rely on React, using Jest/Enzyme to render and validate DOM).
Since specifying React in peerDependencies caused it not to be installed in the node_modules of Core, I decided that I should probably include React in both the peerDependencies and the devDependencies of Core. That fixes the Core library again but breaks the Application.
I'm not really sure of the following:
Why one of my applications fail due to duplicate React copies and the other doesn't, since they seem pretty symmetrical to each other.
Why, even though I only specify React in peerDependencies and devDepenencies in Core I still would get a duplicate copy of React in the dependent application
Whether the method used to bring Core in to the application has any bearing on this. (one method I'm trying is package.json I specify core as a "file:../" style of URL. Another alternative is to use "yarn link", or possibly to do both of these, and I'm not sure whether this has any effect on what ends up in node_modules underneath the application folder or on what gets bundled)
What is the right way to include React in both an Application and a library, in such a way that both of those projects have React available but there does not end up being duplicates in the Application causing this hook error (or, just taking up extra space).
Answering my own question.
I found the following issue helpful: https://github.com/facebook/react/issues/14257
Various different suggestions were made in the comments of ways to solve this problem, either by npm link or yarn linking the react library from the library to the application, or vice versa. Those all seemed promising, since the idea is to make sure that all of the different references to React are actually pointing to the same place. Unfortunately none of those worked for me. (e.g. the answers by JerryGreen and Kas in that issue)
Another user, dcecile, suggested using webpack's alias feature, but I'm not using webpack.
resolve: {
alias: { react: require.resolve("react") }
},
Parcel has a similar alias feature but can't be used in quite the same way because it's used in the package.json file so things like require.resolve can't be called like they are in webpack's js config file.
I ended up finding a way to use Parcel's alias feature to do what I wanted, based on another example from https://github.com/jaredpalmer/tsdx/issues/64 from user jaredpalmer. In my situation, I'm adding this to the application's package.json, and it appears to get rid of the duplication problem and the "Invalid Hook Call" error:
"alias": {
"react": "../my-core-library/node_modules/react",
},
I tried to utilize reactAdmin but i have some questions in file hierarchy why .ts , tsx and .js files are there in one use of single screen , May i know the usage of that and how to handle the API's integration within interlinking the data.
And also is there any solutions of handling .tsx functions or components in .js file as im very much familiar with .js than ts or tsx.
React AdminA Web Framework for B2B applicationsmarmelab.com
They typescript files which gonna be eventually compiled to javascript. So you can just use javascript code as reference, there is no need to look at those .ts or/and .tsx file, you should look at them when you want to learn typescript.
It checks variable types at compile time in 'your code'.
If you are new to javascript, first learn it, and not necessary to learn typescript, but you "may may" need it in future.