Dynamic import images from folders - reactjs

Using webpack I can import images from a folder
let i = 0;
const imgs =[];
let img;
for(i=0;i<3;i++){
img = require( '../Resources/OtherProjects/'+props.type+'/'+i+'.jpg' );
imgs.push(img);
}
where props.type gives me a different folder to create an array for each folder in my dynamic component
my question is : there is a better way?
also , there is a way to get how many images are in my folder?
require.context only works for an specific folder , but not for each folder

You can use alias to provide aliases for your srcor any directory in your root folder.
Sample tsconfig.json file
const {alias, configPaths} = require('react-app-rewire-alias')
module.exports = function override(config) {
alias({
...configPaths('tsconfig.paths.json')
})(config)
return config
}
tsconfig.paths.json
/* tsconfig.paths.json */
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"example/*": ["example/src/*"],
"#library/*": ["library/src/*"]
}
}
}
and modify your package.json to this:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
}
You may also refer to this for more information.

Related

Can't resolve 'crypto' in react-oauth2-pkce

I have a React.js application which is part of an oAuth2 architecture and in order to get a token it uses Authorization Code + PKCE flow as explained here.
The issue is that when I try to run the app npm start I get the following error:
I tried with the suggested approach at many places to add the following in my package.json after devDependencies:
"browser": {
"crypto": false
}
but I still have the same issue. I am using Node.js 14.0.0
This is a big issue, and I will not elaborate on the various moving parts that causes the issue.
What you need to do:
run yarn add crypto-browserify stream-browserify buffer
run yarn add -D react-app-rewired
create a new file in the root of your directory: config-overrides.js with the contents:
const webpack = require('webpack');
module.exports = function override(config, env) {
config.resolve = config.resolve || {};
config.resolve.fallback = config.resolve.fallback || {};
config.resolve.fallback.crypto = require.resolve('crypto-browserify');
config.resolve.fallback.stream = require.resolve('stream-browserify');
config.resolve.fallback.buffer = require.resolve("buffer")
config.resolve.alias.buffer = 'buffer'
config.plugins = config.plugins || [];
config.plugins.push(new webpack.ProvidePlugin({Buffer: ['buffer', 'Buffer'],}));
return config;
}
Edit your package.json and make sure it looks like this:
...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
...
run rm -fr node_modules/.cache
Read more:
The actual issue that caused all this - "BREAKING CHANGE: webpack < 5 used to include polyfills..." - issue 11756 at CRA
related react-oauth2-pkce issue 33
How to re-wire CRA

how to set base path for all imports in react

In a create-react-app cli project, using configs below to set all import paths to src as base url
jsconfig.json
{
"compilerOptions": {
"jsx": "react",
"baseUrl": "src/",
"paths": {
"~/*": ["./*"]
}
}
}
package.json
..
"scripts": {
"start": "react-scripts start",
"build": "react-scripts --max_old_space_size=4096 build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
all I want to use import statments like this:
import { PanelHeader } from '#/components/panel';
instead of this:
import { PanelHeader } from '../../../components/panel';
By checking Absolute Imports on CRA you can see two things:
(1) Setting baseUrl to src
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
(2) Using components/.. when importing a component from folder called components (subfolder of src folder)
Example — import Button from 'components/Button';
So, get rid of #/ part.
You will need to add it to your webpack config and jsconfig files.
Install the following packages,
npm install customize-cra react-app-rewired
Then create a config-overrides.js in root project and add the following,
const { override, addWebpackAlias } = require('customize-cra');
const path = require('path');
module.exports = override(
addWebpackAlias({
'#': path.resolve(__dirname, 'src')
})
);
Add the following to your jsconfig.json,
{
"compilerOptions": {
"jsx": "react",
"baseUrl": "src",
"paths": {
"#/*": ["*"]
}
}
}
You will have to use react-app-rewired to start your project or add it to your package.json scripts,
npx react-app-rewired start
or
...
"scripts": {
"start": "react-app-rewired start",
...

Can't import react component library into CRA

I created a react component library for a project to create a shareable component library across
multiple projects using the same theme and similar components.
I am importing it by npm link and importing as import { Button } from 'ph-shared'
It throws error
Here's the link to lib code if that can help
https://github.com/usmantahirr/react-lib
Found the fix. You have to install react-app-rewired and react-app-rewired-alias
here's the code snippit
const path = require('path');
const {alias} = require('react-app-rewire-alias')
Add a file config-overrides.js in root and put this.
// config-overrides.js
module.exports = function override(config) {
alias({
react: path.resolve('./node_modules/react'),
})(config)
return config;
};
Modify scripts your package.json as follows
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},

Coverage report for jest unit tests not displaying with --coverage option

My Project is based on Create-react-app setup and my package.json script for testing unit tests is as below
"scripts": {
"test": "react-scripts test --coverage",
}
or
"test": "react-scripts test --coverage --collectCoverageFrom=src/**/*.{js,jsx}
It executes tests in Test folder but doesn't display coverage report.Can you help to solve this issue.
My file structure is as below
src
|
--- Test
---components> moduleA > package1 > package2> transaction.js, abcd.js... etc
ProcessEvent.test.js
describe('ProcessEvent Component', () => {
const expectedProps = {
"event": {iconStatus:'active', desc:'abc'}
}
it('should render without error', () => {
const component = <ProcessEvent {...expectedProps}/>
const wrapper = component.find('.eventclass');
expect(wrapper.length).toBe(1);
});
it('should receive valid props', () => {
const component = shallow(<ProcessEvent {...expectedProps}/>);
const wrapper = component.find('.eventclass');
expect(component.props).toBeDefined();
});
});
Using --watchAll=false parameter makes it list down all the files.
Example package.json
{
...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"coverage": "react-app-rewired test -- --coverage --watchAll=false",
"eject": "react-scripts eject",
"serve": "node server.js"
},
...
}
Also your coverage report is physically located at /coverage/lcov-report. Opening an index.html located there, would show you the coverage report in your browser.

How do I change `src` folder to something else in create-react-app

I'd like to know if it's possible using react-script to rename src to something else like app folder
You can use react-app-rewired to override react paths configuration.
In my case, I can change the paths in config-overrides.js file
const path = require('path');
module.exports = {
paths: function (paths, env) {
paths.appIndexJs = path.resolve(__dirname, 'mysrc/client.js');
paths.appSrc = path.resolve(__dirname, 'mysrc');
return paths;
},
}
Not sure if this answers your question but I'll give it a shot. My directory structure looks like this:
/root
--/app
----/build
----/public
------index.html
----/src
------index.js
app.js
package.js
My /root/package.json has this in it:
"scripts": {
"build": "cd app && npm run build",
"start": "node app.js",
"serve": "cd app && npm run start"
},
"dependencies": {
"express": "^4.8.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-scripts": "^1.0.17"
},
and my /root/app/package.json looks like this:
"scripts": {
"build": "react-scripts build",
"start": "set PORT=3000 && react-scripts start"
},
"dependencies": {
"react-scripts": "^1.0.17"
}
To run the development version of Reactjs, in the /root I can just npm run serve to serve up the dev version.
I am using node and express, so to run the production version of Reactjs,
in the /root I can just npm run build to create the /root/app/build directory. I have a router that looks like this:
var options = {root : config.siteRoot + '/app/build'};
mainRte.all('/', function(req, res) {
console.log('In mainRte.all Root');
res.sendFile('index.html', options);
});
so when I run /root/app.js in node and surf to "/" it opens up /root/app/public/index.html and then /root/app/index.js.
Hopefully that helps.
react-app-rewired allows for this exact customization.
1
Install react-app-rewired as a dev dependency:
npm install --save-dev react-app-rewired
2
In package.json, change these lines
"scripts": {
"react-start": "react-scripts start",
"react-build": "react-scripts build",
"react-test": "react-scripts test",
...
}
to
"scripts": {
"react-start": "react-app-rewired start",
"react-build": "react-app-rewired build",
"react-test": "react-app-rewired test",
...
}
3
Create a config-overrides.json file in your project directory root with the following contents:
const paths = require('react-scripts/config/paths')
const path = require('path')
// Make the "app" folder be treated as the "src" folder
paths.appSrc = path.resolve(__dirname, 'app')
// Tell the app that "src/index.js" has moved to "app/index.js"
paths.appIndexJs = path.resolve(__dirname, 'app/index.js')
Now your app folder is the new src!
You can also customize many other things, such as the name of the "public" folder:
paths.appPublic = path.resolve(__dirname, 'subfolder/public')
paths.appHtml = path.resolve(__dirname, 'subfolder/public/index.html')
And you can also change the location of package.json and node_modules. See here for the full list.
I know this is an old question but I'm still gonna post my solution since it might help someone.
I got it working by doing the following:
Run npm run eject. This exposes some internal configuration stuff from create-react-app
Open your package.json and edit the respective regexes under jest.collectCoverageFrom and jest.testMatch to match your test path
Alter the paths for appSrc, appIndexJs and testsSetup in the config/paths.js file
T0astBread's answer is nearly perfect, but there's an additional reference to "src" that he missed inside modules.js.
Specifically:
return {
src: paths.appSrc,
};
needs to be changed to
return {
newSrcName: paths.appSrc,
};
This is a great question and a valid scenario for changing this folder name is when migrating old react projects to CRA.
Here's another approach I found that breaks less things:
Create a symlink with:
ls -s ./app src
Then add this in config-overrides.js, to allow webpack to process the symlink:
module.exports = (config, ...rest) => {
return { ...config, resolve: { ...config.resolve, symlinks: false } };
};
Then install react-app-rewired and add this to your package.json:
"start": "react-app-rewired start",
While Cong Dan Luong's answer is correct as far as renaming the folder goes, it will break testing with jest. You need to expand the config-overrides.js module.exports part with the following:
module.exports = {
jest: function(config) {
config.collectCoverageFrom = ['client/**/*.{js,jsx,ts,tsx}', '!client/**/*.d.ts'];
config.testMatch = [
'<rootDir>/client/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/client/**/*.{spec,test}.{js,jsx,ts,tsx}',
];
config.roots = ['<rootDir>/client'];
return config;
},
// The paths config
paths: function(paths, env) {
paths.appIndexJs = path.resolve(__dirname, 'client/index.js');
paths.appSrc = path.resolve(__dirname, 'client');
return paths;
},
};
In my above example I am using 'client' instead of 'src'. npm test now works.
Perhaps a symbolic link might address your reasons for wanting to do this:
ln -s ./src/ ./app
The src folder will remain but you can work with it as if it was the app folder.
If, like me you're using vscode you can also do:
Cmd-shift-p search workspace settings, and add the following:
{
"files.exclude": {
"src/": true
}
}
You could do similarly with other editors
Create file in root of your project, insert this code and run.
const fs = require('fs');
const path = './node_modules/react-scripts/config/paths.js';
const folder = 'app';
fs.readFile(path, 'utf8', (err, data) => {
if (err) throw err;
data = data.replace(/src/g, folder);
fs.writeFile(path, data, 'utf8');
});

Resources