difference between importing a component vs importing react - reactjs

Hello every one i just want to know the mechanism behind how importing react from 'react' works in my cra-app but for my component i have to import it by defining the path of the component file in a nutshell why is there a difference between thee two statements
import React, { Component } from 'react';
import Button from './Button';
Thanks in advance

This is because React is using Webpack internally to resolve modules. In the first import import React, { Component } from 'react'; webpack will look for the library in the node_modules folder as it has a resolver configured to do so.
In the second case you need to mention the path or alias the path ./Button with a shorter name like 'button' to tell Webpack where to search/resolve in that directory inside the webpack.config.js.
For an app created using create-react-app, the webpack.config.js will be located in node_modules/react-scripts/config/webpack.config.js.
There you would notice this resolver is defined which tells Webpack where to look for the core libs:
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
modules: ['node_modules'].concat(
// It is guaranteed to exist because we tweak it in `env.js`
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
),
...
}
To alias your own path you can define a new alias in that file located in the config/webpack.config.js after you eject the app with npm run eject (you cannot undo this):
resolve: {
alias: {
'components' : path.resolve(__dirname, '../src/Components')
}
}
};
In you component you can import like:
import Button from 'components/Button';

react is a package installed via npm into node_mudules and can be imported by the package name.
Button is your custom component, and thus has to be imported by its path. If you made Button into a package, then you could install it via npm as well.

Related

CSS missing for some components on Vite bundle

The title really says it all, some components have their CSS included correctly and others are missing the CSS altogether. There is no difference between the working and non-working components that I can find, but each time I run the build script, the same components are missing the CSS. The CSS files are being imported normally -
import "./WeeklyTrend.css"
I'm using Vite as my bundler, I have not made any changes to the config beyond what comes with the react template, which I will include below.
import { defineConfig } from 'vite'
import react from '#vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
base: "https://www.--fakeserverurl--.com/"
})
The css in question is missing altogether from the bundled CSS file. I'm probably missing something simple, but I really have looked all over the place with no success. Thanks in advance.

Use two different React/React-Dom versions in project

I'm in an extremely weird situation where the project structure looks like:
Project
MiniProject1
MiniProject2
node_modules
package.json
The mini projects themselves are react apps that get shown within a ruby container. So when a user goes to /route1 it loads the miniProject1 react page. when they go to /route2 it goes to the miniProject2 page.
I've been tasked to update the react version of MiniProject2 but not interfere with MiniProject1 or make any changes that could interfere with MiniProject1.
I went the route of installing react and react-dom as follows:
"react-latest": "npm:react#^16.13.1",
"react-dom-latest": "npm:react-dom#^16.13.1",
so I can then import the latest versions specifically in MiniProject2
The problem that I'm facing is the react-dom has the "React" a peer dependency and it's trying to pull the project react instead of my aliased "react-latest" which makes sense but now I'm stuck trying to figure out how I can force react-dom to require my react-latest alias instead of the default react peer dependency.
I'm also open to potential Webpack config solutions.
Any thoughts?
After some digging I was able to force react-dom to use react-latest by doing the following:
package.json
"react": "^16.3.2",
"react-dom": "16.3.3",
"react-dom-latest": "npm:react-dom#^16.13.1",
"react-latest": "npm:react#^16.13.1",
webpack.config.js
module: {
rules: [
{
test: /\/node_modules\/react-dom-latest\/.*.js/,
resolve: {
alias: {
react: path.resolve('./node_modules/react-latest')
}
}
}]},
Then on the top of the files I need to use the latest react version for, I import react like so:
import React from 'react-latest'
//or
import ReactDOM from 'react-dom-latest' //for your index
On the files I need to use the old react for, I import react like so:
import React from 'react'
//or
import ReactDOM from 'react-dom' //for your index
That's all that needed to be done!
Disclaimer: Don't do this unless you have to and have no choice like I did. It'll increase the size of your bundle since you are bringing in two different versions of react and reactDom

Directly import typescript module with React

I created react by create-react-app my-app --typescript.
And then I installed typescript module in local.
../typescript-module/A.ts
export default class A {
}
App.ts
import A from 'typescript-module/A';
console.log(A);
I try to import typescript module to my react app.
But it show error like under.
./node_modules/typescript-module/A.ts
Module parse failed: Unexpected token
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
How can I set installing local typescript module ?
If I am understanding correctly, you are trying to import a local custom made React component. If you use an absolute path for your import, it will try to find it in the node_modules. You should use relative paths for local modules/components.
import 'typescript-module/A' -> import './typescript-module/A'
Note: The relative path depends on where you are importing it from

Using own React npm component - appropriate loader issues

I have made a component in my React app that I would like to publish to NPM. It's consists of just one file index.js
import React from 'react'
import PropTypes from 'prop-types';
export default class Test extends React.Component {
//I seem to be getting a specific issue with the lines below
//Do I need a special loader for these?
static displayName = 'Test'
static defaultProps = {
live: true,
}
}
Originally the component was in a components directory of my main app and I include it using:
import Test from './components/Test'
Since then I have created a new folder (not part of my main app) and added a package.json file and the index.js file. I have also published it to NPM which worked fine but when I try to use it after installing...
npm i -S package-name
import Test from 'package-name'
I get an error: You may need an appropriate loader to handle this file type...
My package.json file doesn't have any dependencies or devDependencies at the moment. Do I need to do something with Webpack and Babel?
Do I need to do something with Webpack and Babel?
Most likely. If you are using ES6 syntax in package-name then babel needs to transcode that library as well. When I have encountered that error this has always been the case. I suggest updating your Webpack / Babel configuration to include that library.

stateless functional components and `react` import

I face the same issue as described here
https://github.com/babel/babel/issues/2504
So, any file which has only stateless components needs to have react imported like import React from 'react';, which is bit annoying (eslint gives error as unused variable; which I understand can be suppressed, still..). Is there a way to avoid having this import in a webpack based setup.
thanks.
I had the same issue. Then, I found this:
babel-plugin-react-require
This will automatically add the required require or import calls to get 'react' imported to your stateless component modules.
P.S. If you use webpack and babel6, ensure that you are not using the jsx-loader for your JSX files. I was getting errors with this and then I realized the jsx-loader is not required anymore. Just use:
babel-preset-react
You can use Webpack's ProvidePlugin (https://github.com/webpack/docs/wiki/shimming-modules#plugin-provideplugin):
new webpack.ProvidePlugin({
React: "react"
})
Now you'll have React available in every module without having to explicitly write import React from 'react'

Resources