cannot find sass module when it already works (TS2307) - reactjs

I've started using Electron alongside React and one issue I'm facing right now - which may actually be unrelated to Electron - is that Node cannot seem to "find" a Sass module that I am importing despite the fact the styles I'm importing are actually working.
Here is my file structure:
src
|__Render
|__Styles
| |__Page
| |__Home.module.scss
|__App.tsx
Inside of App.tsx, I'm importing the Sass module like so:
import styles from "./Styles/Page/Home.module.scss";
export default function App(){
return <div className={styles.test}>Test</div>
}
and receiving the error:
TS2307: Cannot find module './Styles/Page/Home.module.scss' or its corresponding type declarations.
Despite this, if I inspect the element I'm targeting, the styling is being applied.
<div class="Home_test__QTxtE">Test</div>
I have followed every single answer in this thread to no avail.
Is this an issue with Electron? Is there some sort of extra configuration I'm missing?
Also, it might be worth mentioning, that if I just import "Test.css";, this works fine.

Related

All imports are undefined for one module during Jest test run

Strange bug with Jest, create-react-app, and typescript.
Tonight Jest started failing to import my "./ProcessStore" module correctly. This module is a transitive dependency of something that my tests import.
The error I see is that the thing I import is undefined.
When I do import * as what from "./ProcessStore" and log(what), it prints all of the exports, but the values are undefined. Like {default: undefined, ResourceChange: undefined} two classes that are exported. It should be {default: <a class>, ResourceChange: <a class>}.
It's just that one file. Every other file works.
When I use npm start, it works --- this is a Jest only problem.
Also if I rename the broken file to say ./ProcessStore2, it also works.
I tried ./node_modules/jest --clearCache, which didn't help.
In case it's relevant, I'm using craco normally. Switching back to react-scripts temporarily didn't help.
I'm using react-scripts 4.0.3 (latest version).
What is going on? How do I fix this silly problem?
This was caused by a circular dependency in my project.
The circular dependency was causing Jest to return an empty module. I believe the 2nd time a module is entered, it will have undefined contents.
In my case the chain was ProcessStore.ts -> stores.ts -> ProcessStore.ts. So by the time stores.ts loads ProcessStore.ts, the process store has already been loaded, so everything is undefined.
I ran into this when I was importing in one file like this
import { myHook } from 'services/hooks/myHook'
and in another file
import { myHook } from 'services/hooks'
There was an index file
// src/services/hooks/index.ts
export * from './myHook.ts'
Converting them all to use the index path fixed it. I don't think I had a circular dependency anywhere, I never was able to truly understand what was wrong.
I also ran into this issue, due to a circular dependency.
In order to confirm the nature of the bug, I console.log the missing import and executed my test. I could see that the import was in fact undefined when it shouldn't have been.
I ran this command to find circular dependencies at package/project level:
npx madge --circular --extensions ts,tsx .
This only gave me a clue as to what was going on, however.
I then used the debugger at the point where my circular dependency was occurring. Using Chrome DevTools, I inspected the call stack, and found how each import was being imported. This revealed the circular dependency very clearly. For me, this was the most important part of untangling the circular dependency.

Import a file as a string (or source asset) in Gatsby / React

I want to import .ts, .tsx, .js, and .jsx files into a react component and render them within a PrismJS highlighting block. For example, let's say I have a TypeScript file with functionA in it that I want to highlight in my actual website:
functionA.ts:
export function functionA() {
console.log("I am function A!");
}
I want to include this in a different component. The problem is, when I import it, I am obviously importing the webpack module version of it. My weak attempt at trying to get my function render in a react component looks like this:
MyComponent.tsx:
import * as React from "react"
import { functionA } from "./functionA"
export function MyComponent() {
return (
<>
<h1>Here is your code block:</h1>
<pre>
<code>
{functionA.toString()}
</code>
</pre>
</>
)
}
and what will actually render on the page where the code block is will look something like this:
Here is your code block:
WEBPACK__IMPORT.functionA() {
console.log("I am function A!")
}
I can't exactly remember what the .toString() function output looked like, but the point is it is NOT just the contents of the file how it appears in a code edit for example - it has been modulized by WebPack.
So, in a Gatsby project, how can i get these various code snippets to be imported directly as a string, purely as they are written, without WebPack enacting its import stuff on it? Is there a plugin or some way to tell Webpack to use the imported file as its asset/source module type? I know for MD or MDX files there is the gatsby-remark-embed-snippet, but I am building a component based HTML page and can't use MD or MDX files!
It's very late, and perhaps I just can't see the forest from the trees, I know there must be a way to do this...
You need to require the file using webpack's raw-loader, i.e:
const functionA = require("!!raw-loader!./functionA");
This works for create-react-app, as in the solution discussed here, and this works for Gatsby as well!
After using require on such a file, the file contents can be rendered in the component as:
<pre>{functionA.default.toString()}</pre>
It's then up to you to add syntax highlighting using a tool like prism or similar.
Note this solution will only work as long as Gatsby V3 continues to use WebPack v4, as raw-loader is deprecated in WebPack v5 and will be phased out for asset/source type modules.

Why do I have to use "require" instead of "import from" for an image in React?

I see that this answer suggests the syntax for importing images as shown below (commented out). In my case, it didn't work out (complaining there's no modules to find in that file) and I had to switch to the syntax that's currently active.
// import Author from "../assets/author.png";
var Author = require("../assets/author.png");
The difference I can imagine is that I'm using TypeScript (transpiling my TSX by awesome-typescript-loader and loading my PNG file-loader) and they seem to use JSX. But as far my understanding goes, it all transpiles to plain JS and require in the end.
Being a noob on React, I'm not sure what the reason of this discrepancy is but also I'm not sure what to google for to investigate myself.
This is more of a problem with typescript than webpack itself, you might need to declare modules on a declaration file.
Create a declarations.d.ts
Update your tsconfig.json
"include": [
"./declarations.d.ts",
],
Put this on that file:
declare module '*.png';
Error might be gone.
You can declare a module for your images like this:
declare module "*.png" {
const value: any;
export default value;
}
Then, you will be able to import your image like this:
import AuthorSrc from "../assets/author.png";
This is happening because webpack doesn't support image import out of the box. So you need to add a rule for that in the webpack config file. When you add a new rule, TypeScript doesn't automatically know that, so you need to declare a new module to resolve this. Without the module, you will be able to import images, but TypeScript will throw an error because you didn't tell to it is possible.
This issue has nothing to do with webpack or any bundler and is not quite a problem with typescript.
Typescript has stated that `require("path") is a way to include modules to the scope of your current module, whilst it can be also used to read some random files (such as json files, for example).
As Vincent and Playma256 specified, you can declare a module wildcard to match certain file types, so you can import it as an import statement. But you don't really need to do this. Typescript won't give you an error if you are trying to import a png or a json file (tslint might, but that depends on your configuration).
By the way, if your declaration is within the source folder of your project as defined in tsconfig.json, you don't need to include it as specified by Playma256.
I've created a sample project in node for you to test:
https://github.com/rodrigoelp/typescript-declare-files
I think you can solve this problem with Webpack&&typescript.The official webpage of webpack has introduced something about this in
https://webpack.js.org/guides/typescript/
And I have try this myself in
https://github.com/reactpersopnal/webpack-root/tree/feature/typescript
The reason is that you would like to use non-code assets with TypeScript, so we need to defer the type for these imports for webpack.
Your could simply add custom.d.ts.
declare module "*.jpg" {
const content: any;
export default content;
}

React css transition throwing invalid component error

Been struggling with this one for a few hours now. I'm trying to use react-css-transition-group to animate elements in an array. I have:
render: function(){
var dataSections = this.props.sections.map(this.buildDataSection);
return (
<div>
<ReactCSSTransitionGroup transitionName="example" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{dataSections}
</ReactCSSTransitionGroup>
</div>
);
}
It compiles fine, but when I run it I get Uncaught Error: Invariant Violation: ReactCSSTransitionGroup.render(): A valid ReactComponent must be returned. in my console. I have no idea why. I've tried rolling back my version of both react and react-css-transition-group to no avail. I'm at a loss for ideas at this point.
dataSections is a valid array of elements and renders fine when I take the animation out.
Any thoughts?
Update
I've since moved on to several other things in this project, and I've realized that it isn't just this package, it's any react package that exports a component. All of them throw this same error: A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
I've updated all my packages including Browserify, and React is already a peer dependency. Not sure what to do :(
Okay, I've figured it out, and I'm a fool.
Before I started using NPM, I was using the react-rails gem, and when I ported everything over to Browserify, I never took out the old gem. Because of that, I didn't notice the several different places that I forgot to require('react') at the top of a component file, because the old gem provided React in the global namespace and it therefor didn't throw an error.
Long story short, I had two conflicting versions of React running at the same time. Removed the gem, fixed the missing includes, and problems went away!

React FixedDataTable Webpack bundle - Uncaught TypeError: Cannot read property 'requestAnimationFrame' of undefined

I've created a simple component called MyDataTable, as a wrapper over React FixedDataTable component and bundled it with Webpack. The file resulted from this bundle is called my-components.js. Nothing really complicated until here. You can try the source code to see how it works: https://github.com/cosminnicula/fdtwebpack
Now, the second step would be to consume this my-components.js library in a separate project. Here https://github.com/cosminnicula/fdtwebpackclient you can see how I imported the library and tried to use the <MyDataTable /> component:
'use strict';
//fdtwebpackclient/src/main.jsx
import React from 'react';
import MyDataTable from './../lib/my-components.js';
React.render(
<div>
Hello MyDataTable!
<MyDataTable></MyDataTable>
</div>
, document.body
)
However, if i try to browse index.html, I get a nasty error, which I don't find a logical explanation for: "Uncaught TypeError: Cannot read property 'requestAnimationFrame' of undefined".
BTW, the wrapper component was copy-pasted from here http://jsbin.com/temufa/18/edit?html,js,output, so it should suppose to work.
Any idea on this error?
I've identified the problem and the solution is very simple. Inside fdtwebpackclient change:
import MyDataTable from './../lib/my-components.js';
...
<MyDataTable></MyDataTable>
with:
import MyComponents from './../lib/my-components.js';
...
<MyComponents.MyDataTable></MyComponents.MyDataTable>
I think the problem is that you have a bundle within a bundle kind of situation. FixedDataTable seems to do some trickery to find global context (ie. window). This breaks here.
Instead of bundling a bundle within a bundle at your wrapper you could push FixedDataTable as an external there like this:
externals: {
'fixed-data-table': 'fixed-data-table',
},
The wrapper should probably consume FixedDataTable as a peer dependency then. Your main project would depend on FixedDataTable directly then. Webpack can deal with mapping the dependency to your wrapper.

Resources