cannot import image with create-react-app - reactjs

I'm using create-react-app, and I am struggling to load images. I am following the instructions as specified here, but I keep seeing the following error:
Failed to compile.
Error in ./src/components/Home/imageIndex.ts
(1,24): error TS2307: Cannot find module './party.png'
Does anyone know why when I run yarn start my app continues to fail to compile?
I have a Home component and this is how I am importing the file:
import photo from './party.png';
The component is located in src/components/Home/index.tsx and the png file is located in src/components/Home/party.png.
here is my package.json:
{
"name": "eai-reactjs-typescript-redux-starter",
"description": "A ReactJS/TypeScript + Redux starter template with a detailed README describing how to use these technologies together and constructive code comments.",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.5",
"redux": "^3.7.0",
"redux-logger": "^3.0.6"
},
"devDependencies": {
"#types/enzyme": "^2.8.0",
"#types/jest": "^19.2.3",
"#types/node": "^7.0.18",
"#types/react": "^15.0.24",
"#types/react-dom": "^15.5.0",
"#types/react-redux": "^4.4.40",
"#types/redux-logger": "^3.0.0",
"enzyme": "^2.8.2",
"react-addons-test-utils": "^15.5.1",
"react-scripts-ts": "1.4.0",
"redux-devtools-extension": "^2.13.2"
},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
}
}

Are you sure you've got the correct path? Also when you import an image via css (as is done in the example you mentioned) you need to give a path relative to the public folder and not the src folder. I have run into this problem several times.
An example using import:
import Image from './img.png'
...
// react example
...
render() {
return (
<img src={Image}/> // notice the curly
...
and not
<img src="Image"/>

I had the same problem and was able to solve with a require statement.
const photo = require('./party.png');
and then in your component use that like:
render() {
return (
<img src={photo}/>
also see this post Displaying a static image using React, Typescript and Webpack

As #archae0pteryx proposed it is much better to separate pictures from the code, so the project public folder should be used instead of src.
Here is how it works with css:
copy 'img.bmp' into /public
inside .css file/class: background-image: url('/img.bmp');

You can simply use something like this:
render() {
// Note: this is an escape hatch and should be used sparingly!
// Normally we recommend using `import` for getting asset URLs
// as described in “Adding Images and Fonts” above this section.
return <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;
}
Quoted directly from CRA docs

By default, Create-React-App uses url-loader for files with size 10000 bytes
that works fine in the development environment, but in production reduce error.
For a production environment, you should change the value for the limit of bytes in order to enforce webpack use file-loader instead.
If you have to eject your app modify webpack.config.prod.js file and change the limit of url-loader to 10 and will work as well
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10,
name: 'static/media/[name].[hash:8].[ext]',
},

Related

Error: EISDIR: illegal operation on a directory, readlink 'D:\study\noobinjs\pages\_app.tsx' when trying to run 'npm run build' for next js app

Im getting the above mentioned error when trying to run the npm run build for next js app. The next.js app is in typescript.
Here is the error screenshot with the folder structure
Error. Unable to understand why _app.tsx is being considered as directory here instead of a file. Any help is much appreciated. Thanks in advance!
Edit: It's just a basic next.js app created with typescript by default containing the folder structure shown in the left side in the Error screenshot above.
Below is the code inside _app.tsx:
import 'tailwindcss/tailwind.css'
import React from 'react'
import { Layout } from '../components'
import '../styles/globals.scss'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
Below is my package.json
{
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"graphql": "^16.3.0",
"graphql-request": "^4.1.0",
"html-react-parser": "^1.4.8",
"moment": "^2.29.1",
"next": "latest",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-multi-carousel": "^2.8.0",
"sass": "^1.49.9"
},
"devDependencies": {
"#types/node": "17.0.4",
"#types/react": "17.0.38",
"autoprefixer": "^10.4.0",
"postcss": "^8.4.5",
"prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.1",
"tailwindcss": "^3.0.7",
"typescript": "4.5.4"
}
}
I receive error when I ran npm run build as Error: EISDIR: illegal operation on a directory, readlink 'D:\study\noobinjs\pages_app.tsx'.
Just started learning next.js and this happens in the initial encounter.
Try to put the file of project in C drive not in the D.
Example => C:\Users\Mahmoud\Desktop\next-damo
Then try to run npm run build.
This problem may be related to whether the symbolic link can be created or not.
I also encountered the same problem, but solved it by changing the filesystem from exFAT to NTFS.
As you know exFAT can't create symlink.

Hot module reload is not working on my nextjs app

I have a project based on nextjs. Oddly enough, the HMR is not working properly for my project. Every time I make changes I have to re run the process. I have attached details of my next config and package.json:
next.config:
const withSass = require("#zeit/next-sass");
const withCSS = require("#zeit/next-css");
module.exports = withCSS(
withSass({
webpack(config, options) {
config.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: "url-loader",
options: {
limit: 100000,
},
},
});
return config;
}
})
);
package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next export"
},
"dependencies": {
"#zeit/next-css": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^3.26.8",
"chartjs": "^0.3.24",
"classnames": "^2.2.6",
"draft-js": "^0.11.4",
"isomorphic-unfetch": "^3.0.0",
"moment": "^2.24.0",
"next": "^9.2.1",
"node-sass": "^4.13.1",
"react": "16.12.0",
"react-dom": "16.12.0",
"react-helmet": "^5.2.1",
"react-markdown": "^4.3.1",
"react-mde": "^8.1.0",
"react-redux": "^7.2.0",
"react-select": "^3.0.8",
"react-slick": "^0.25.2",
"react-toastify": "^5.5.0",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"showdown": "^1.9.1",
"slick-carousel": "^1.8.1"
},
"devDependencies": {
"eslint": "^6.8.0",
"eslint-loader": "^3.0.3",
"eslint-plugin-react": "^7.18.3",
"url-loader": "^3.0.0"
}
I have tried removing node_modules and reinstalling again as well, doesnt seem to fix the issue.
Following is my project structure
Got help from #felixmosh. There was issue because of my folders were case was not matching route case. Fixed the issues by changing folder name to route names.
I just solved this problem by deleting folder ".next" and then closing terminal, and run npm run dev again.
Sometimes, when you accidentally name a component starting with a lowercase and then later changes to capital letter, next cache will still consider the older name and won't count it as a normal component.
The easiest solution is to copy the contents of the components, delete the file, and create one with a proper component name.
in my case hot reload didn't work because there was assetsPrefix in my next.config.js. You can remove or change them to "/" in the development mode and everything will be as expected.
For people NOT using modules and using Typescript paths.
For my setup, I just like having general .scss files
So, in my _app.tsx
I add Styles/index.scss
Then, in my index.scss
I add my #import '~Styles/flex.scss'
take note of the ~
this was required for it to work with hot reloading.
Wrt to Next js version 10+ and in addition to Pranay's answer, make sure your routes case matches the case of the folder.
Also, I noticed the component name has to start with the upper case. If your file name is dashboard.jsx, the component name should be Dashboard.
// home/dashboard.js
const Dashboard = () => {
....
}
export default Dashboard
I had to go to package.json remove react and react-dom and re add them with yarn add.
In my case, it wasn't working on Chrome. But it was working on Edge browser. And funny enough... even on a guest chrome window.
So all I had to do was...
Clear the cookies and hard refresh.
Force audit fix worked for me. Don't know the exact reason, might be some conflicts between dependencies.
Steps
1)Run this command in your next project directory.
npm audit fix --force
you need to run npm run dev instead npm run start

How to serve a React component library dependent on Styled Components to another library that also has a Styled Comopnents dependency?

I've recently converted an internal component library I'm working on to Styled Components. That component library has Styled Components listed as a peerDep and a devDep in the package.json. From there I'm importing Styled Comopnents into every component that needs styling. All works great up to that point.
I have a Create React App (CRA) application that also imports Styled Comopnents as a regular dependency. I need this to be able to build one-off components for this specific project. BUT I also need the ability to import my component library to build out core components for this new CRA-based app.
Now this is my problem: I'm testing my recently converted Styled Components-based component library in this CRA app by linking directly to the component library in package.json (file:../component-lib). I've installed all my deps, imported components from the component library, built a new project specific Styled Component within the CRA project, and ran it locally only to see this same error: "It looks like there are several instances of 'styled-components' initialized in this application. This may cause dynamic styles not rendering properly, errors happening during rehydration process and makes your application bigger without a good reason." I've read that section of docs and learned not to use npm link and to serve SC as a peerDep and a devDep in my component library.
I believe this issue is not allowing me to access theme props I'm passing into a custom ThemeProvider from the component library since I'm running multiple instances in the CRA project?
This problem is definitely due to my lack of knowledge in dependency management. I'm just wondering if anyone else has encountered a similar issue or what I should be doing to avoid duplicate instances of Styled Comopnents?
Component library index
export { default as Button } from "./components/Button";
export {
default as CustomThemeProvider
} from "./components/utils/CustomThemeProvider";
Component library package.json
"scripts": {
"build": "nwb build-react-component --copy-files",
"clean": "nwb clean-module && npm clean-demo",
"start": "nwb serve-react-demo",
"lint": "eslint src/**",
"test": "nwb test-react",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build",
"test:coverage": "nwb test-react --coverage",
"test:watch": "nwb test-react --server",
"publish": "npm run build && npm publish"
},
"dependencies": {
"#rebass/grid": "^6.0.0-4",
"prop-types": "^15.6.0",
"react-portal": "^4.1.2"
},
"peerDependencies": {
"react": "16.x",
"styled-components": "^4.0.3"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"eslint": "^4.18.2",
"eslint-plugin-react": "^7.7.0"
"prettier": "1.14.3",
"nwb": "0.22.x",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-styleguidist": "^7.2.0",
"styled-components": "^4.0.3"
},
Component library NWB config
module.exports = {
type: "react-component",
npm: {
esModules: false,
umd: false,
},
babel: {
stage: 1
}
};
CRA Project package.json
"dependencies": {
"component-library": "0.16.6",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react-scripts": "2.1.0",
"styled-components": "^4.0.3"
},
This is only a partial answer that I'm hoping will enable you or someone else to figure out the rest. I'm far from an expert on managing these kind of dependencies and am helping with this to further my own knowledge since I may want to do a similar setup soon.
Though it seems this should be doable with nwb, I switched to using webpack directly in order to have more control. Even using webpack directly I have only made it part of the way there. Everything works correctly when I do a build, but in dev mode (npm start) for the CRA app, the styled-components package is still getting pulled in twice and the styling doesn't work correctly. This seems like a potential webpack issue since the dev and production modes behave so differently, but it could be something with the CRA webpack dev configuration or (more likely) some aspect of this that I don't yet understand.
This is a good example to reference for the component library configuration: https://github.com/kalcifer/webpack-library-example
Here's my package.json for my test component lib (component-lib3 just because of trying several other approaches):
{
"name": "component-lib3",
"version": "1.0.7",
"description": "component-lib3 React component",
"main": "dist/component-lib3.js",
"peerDependencies": {
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3"
},
"devDependencies": {
"react": "^16.6.0",
"react-dom": "^16.6.0",
"styled-components": "^4.0.3",
"#babel/core": "^7.1.2",
"#babel/preset-env": "^7.1.0",
"#babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.4",
"webpack": "^4.24.0",
"webpack-cli": "^3.1.2"
},
"scripts": {
"build": "webpack"
}
}
Here's the webpack.config.js:
var path = require('path');
module.exports = {
entry: './src/index.js',
mode: 'production',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'component-lib3.js',
libraryTarget: 'umd',
library: 'component-lib3'
},
externals: {
"styled-components": {
commonjs: 'styled-components',
commonjs2: 'styled-components',
amd: 'styled-components'
},
"react": {
commonjs: 'react',
commonjs2: 'react',
amd: 'react'
},
"react-dom": {
commonjs: 'react-dom',
commonjs2: 'react-dom',
amd: 'react-dom'
}
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
And then also .babelrc:
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
I tried a number of variations, and I don't understand why this won't work right for dev mode.
I am facing the same issue at this moment and I'm still not sure. I could fix it properly or not, so please don't take this answer as a guaranteed solution.
There are two things you can try.
The first one is something that appears in the styled-components FAQs section. They suggest configuring Webpack (I assume you are using Webpack too) with an alias so that it always looks for the styled-components dependency wherever you specify. This should avoid having several instances of styled-components, but so far I couldn't make this work for me.
The second option is to use an alternative no npm link. Apparently when you have a symlinked dependency (this is what npm linkdoes actually). The bundler's resolver tries to look for the dependency in the same project. This is also mentioned in the linked styled components FAQs section.
What you should do if you follow this approach is to avoid creating a symlink that points to your component library from the CRA app and copy the folder instead.
There is a tool called wml that can copy the contents of your component library into the node_modules folder of your CRA app. wml is also able to watch for changes in your component library folder and it re-copies the changes to your CRA app's node_modules. So, we could say wml is kind of alternative to npm link. In my initial attempts it worked fine for me so maybe this is something you can try.
Be careful: There is an issue in wml that causes the files on your project to be removed on the first time you set it up. It didn't happen to me but I saw others suffering the problem so if you are going to try wml, please ensure you have all the changes pushed to your source code version control system.
These are the steps you would need to follow to setup wml for your projects using the command line:
wml add <component-library-folder> <CRA-app-folder>/node_modules/<name-of-component-library>
wml start
Ideally I would prefer to solve this without having to use any external tool but if what styled-components maintainers suggest on their site is not valid, it could serve as a workaround.

How to find .babelrc?

I want to create React app with Ant Design
In the docs, it says I need to change .babelrc to modularly load the files, also from https://medium.com/#GeoffMiller/how-to-customize-ant-design-with-react-webpack-the-missing-guide-c6430f2db10f..
But, I can't find any.. I'm very new to Webpack/Babel/other things...
I used create-react-app to make React app
Please help..
This is my package.json:
{
"name": "ant",
"version": "0.1.0",
"private": true,
"dependencies": {
"antd": "^3.0.3",
"jquery": "^3.2.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.0.17"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"babel-plugin-import": "^1.6.3",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"less-vars-to-js": "^1.2.1",
"style-loader": "^0.19.1"
}
}
for anyone that ends up here in the future, some clarification: when you create your project with CRA, the babel configuration exists as part of the react-scripts setup (react-scripts is the package responsible for all the tooling magic of CRA). this means all babel related controls are nested somewhere inside of your project's node_modules directory. for all intents and purposes, they are not editable, and ejecting is required.
If you have created React app using create-react-app, first you need to eject from the app so that you can use custom configuration. Check this official doc about custom setup : link
Note: this is a one-way operation. Once you eject, you can’t go back!
Once you run "npm run eject" when you are in a react app, you can then use custom babel presets. After ejecting from project, go to package.json and you will find babel presets.
There are two ways to edit your Babel configuration in your react app
1) Edit directly using package.json :
{
"babel": { // nest config under "babel"
"presets": [
"es2015",
],
"plugins": ["transform-class-properties"]
}
}
2) Create new .babelrc file and edit the configuration :
//.babelrc
{
"presets": [
"es2015",
],
"plugins": ["transform-class-properties"]
}

Size of bundled ReactJS app

I am trying to reduce the size of my reactjs application bundle.js file. For a relatively simple app i have its browserified js file size - 452Kb.
To build it, i use NPM with respective package.json file:
{
"name": "MyApp-React",
"version": "0.0.1",
"description": "My App Description",
"main": "app.js",
"scripts": {
"watch": "watchify app.js -o public/js/bundle.js -v",
"browserify": "browserify app.js | uglifyjs > public/js/bundle.js",
"build": "npm run browserify",
"start": "npm install"
},
"author": "",
"dependencies": {
"axios": "^0.14.0",
"body-parser": "^1.15.2",
"clipboard": "^1.5.12",
"express": "~4.9.7",
"express-handlebars": "~1.1.0",
"express-session": "^1.14.1",
"highlight.js": "^9.7.0",
"node-jsx": "~0.12.4",
"react": "~15.3.1",
"react-dom": "^15.3.1",
"react-maskedinput": "^3.2.4",
"react-modal": "^1.4.0",
"react-router": "^2.8.1"
},
"devDependencies": {
"browserify": "~6.0.3",
"nodemon": "^1.2.1",
"reactify": "~1.1.1",
"uglify-js": "~2.4.15",
"watchify": "^3.1.1"
},
"browserify": {
"debug": false,
"transform": [
"reactify"
]
}
}
Not being an expert in Node JS/ ReactJS development i hope i do somethin wrong, but i cant find what.
For the time being i tried few things: app.js file has a line of code setting NODE_ENV variable to 'production'
process.env.NODE_ENV = 'production';
A second thing i have tried is to use npm prune command with --production parameter. Having this run, i see it removes a lot from node_modules folder, but then npm run build is failing to run as it misses devDependencies. What can i do?
One thing that you could do to lighten the download burden for your users is get react and react-dom from a CDN instead of putting them in your bundle.
Move them from the dependencies section of your package.json to a new section peerDependencies (see npm docs).
Then add tags to your HTML code for loading React and ReactDOM like so:
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js"></script>
→ See React on cdnjs.com
Then you need to change your Browserify config to recognize react and react-dom as external modules.
→ See related question on StackOverflow

Resources