React Import Icons / Images in bulk - javascript

I have 100's of Icons and Images to be imported. Is there any way to eliminate writing so many import statements at the top of the page? I was thinking to write a import statements in a separate file and embed that at the top.
import basicAmenitiesIcon from '../../../../images/icons/wifi-sign.png';
import parkingIcon from '../../../../images/icons/parking.png';
...
Any other way of solving it? I'm using webpack and here is the config:
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file?hash=sha512&digest=hex&name=[hash].[ext]',
'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
}

Yes, it is posible, see my answer here: https://stackoverflow.com/a/41410938/646156
var context = require.context('../../../../images/icons', true, /\.(png)$/);
var files={};
context.keys().forEach((filename)=>{
files[filename] = context(filename);
});
console.log(files); //you have file contents in the 'files' object, with filenames as keys

Related

inject style into DOM using link tag in Gatsby

Is there any way to configure gatsby to inject a style file using a link tag?
currently, I have a global style (style.less) which I import it using a Layout Component. It's ok but It injects all CSS content into each page and bumps the page size.
I want to configure gatsby to load this style file using a link tag instead of injecting directly into DOM. webpack has an option for this purpose but I couldn't find anything similar for Gatsby.
Try:
exports.onCreateWebpackConfig = ({ actions, loaders, getConfig }) => {
const config = getConfig();
config.module.rules = [
...config.module.rules.filter(rule => String(rule.test) !== String(/\.jsx?$/)),
{
test: /\.link\.css$/i,
use: [
{ loader: `style-loader`, options: { injectType: `linkTag` } },
{ loader: `file-loader` },
],
},
];
actions.replaceWebpackConfig(config);
};
Gatsby allows you to customize the webpack's configuration by exposing some APIs (such as onCreateWebpackConfig or setWebpackConfig) functions.
The code is quite self-explanatory if you take into account the style-loader from webpack. Basically, you are setting some custom loaders for all files that match the regular expression, and finally, you override the default configuration with actions.replaceWebpackConfig(config).
For further details check Adding Custom webpack configuration docs.
In addition, regarding your original issue, you don't need to add your global styles in your Layout component since it will cause what you said, it will bump the page size. With Gatsby, you can use gatsby-browser.js API to add global styles like (in your gatsby-browser.js file):
import './src/your/path/to/global/style.less';
Check the link you've provided (Standard Styling with Global CSS file).

How can I create a loader for webpack which exposes all sources via a function?

I would like to have a loader that collects all css sources and allows me to get all contents in a function. Like this:
Webpack config
module: {
loaders: [
{test: /\.css$/, loader: 'my-loader'}
]
}
JS file A (foo.js)
import './foo.css';
JS file B (bar.js)
import './bar.css';
JS file C (app.js)
import './app.css';
import getAllCSSContents from 'my-loader';
const css = getAllCSSContents();
where getAllCSSContents would return all CSS contents from foo.css, bar.css and app.css
This is a bit tricky because the loader you want to make needs to know about all CSS modules before it can generate the code it needs to return, making it stateful (loaders are meant to be pure functions that transform one input module).
You can kind of achieve what you want using raw-loader and require.context like this:
// Load all CSS files in the current directory and descendants
const context = require.context('!raw-loader!./', true, /\.css$/);
const cssFiles = {};
for (let filename of context.keys()) {
cssFiles[filename] = context(filename);
}

React JS - Loading Image Issue

I'm stuck with the loading image, I've been searched all the sources, and i don't find any answer of this. The code below it doesn't works
import goldImage from './../../../public/img/gold.png';
but when i'm write like this, it works:
const gold = '../../../public/img/gold.png';
Or if I'm importing the JPG file, it works:
import test from './../../../public/img/kaslie.jpg';
I'm also using Webpack 2, here is my code:
test: /\.(png|jpe?g|gif|svg)$/,
use:[
{
loader: 'url-loader',
options:{limit:40000,name:'[path][name].[ext]?[hash]'}
},
'image-webpack-loader?bypassOnDebug&optimizationLevel=7&interlaced=false'
]
I don't have any idea for this, why its only work for jpg file, but PNG file not work.
For images you should use:
const goldImage = require('./../../../public/img/gold.png');
<image src{goldImage} alt="" />
The import statement is used to import functions, objects or primitives that have been exported from an external module, another script, etc.

Render Transpiled ES6 in CSHTML

I have
Tutorial.jsx
class ShoppingList extends React.Component {
render() {
return (<div>Milk</div>);
}
}
export default ShoppingList;
webpack.config.js
module.exports = {
...
output: './React/bundle.js',
...,
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel-loader",
query: {
presets: ['es2015', 'react'],
}
}
]
}
}
In my CMD prompt, when I run webpack -w everything is green and I see my bundle.js file appearing where it should, in the React folder. Opening it, I see
...
var ShoppingList = function (_React$Component) {
...
}
...
so it looks like that's all good.
Now I want to render ShoppingList in my _Layout.cshtml file.
Question: How do I do this? I've tried all methods below and get React errors all the time about invalid parameter type, or passing in the wrong element, or whatever. My CSHTML is below.
<div id="content1">render here</div>
....
<script src="~/React/bundle.js"></script>
<script>
ReactDOM.render("ShoppingList", document.getElementById("content1"));
ReactDOM.render(ShoppingList, document.getElementById("content1"));
ReactDOM.render(<ShoppingList />, document.getElementById("content1"));
</script>
Can someone please let me know if
It's possible to NOT have a ReactDOM.render() inside the JSX file and,
It's possible to do what I want to do which is render my ShoppingList in CSHTML
The best results I've got so far is to see ShoppingList in my DOM explorer but no HTML was actually rendered. It came out <shoppinglist ...></shoppinglist> which appears wrong to me.
Thanks.
You should have this inside your entry file:
import ShoppingList from 'path-to/ShoppingList';
ReactDOM.render(<ShoppingList />, document.getElementById("content1"));
In the CSHTML page the additional script tag is not required.
Your original example does not work because:
ShoppingList is not exposed globally (exporting as default does not make it global).
JSX syntax (<ShoppingList />) needs to be transpiled before it can be used in HTML page.
If you really need to use a component within a CSHTML page, you can make the component global:
window.ShoppingList = ShoppingList
inside the file that defines the component.
And use vanilla javascript instead of JSX syntax:
ReactDOM.render(React.createElement(ShoppingList), document.getElementById("content1"))

How can I use a config file in React?

Let's say I have 5 jsx files and each file uses some config parameter.
My index.js file imports all of these 5 jsx files.
Instead of having my config data spread accross 5 files, is there a way for my jsx files to get the data from a global JS object which has loaded the data from a config file?
I've seen some examples, but I've not been able to get them to work.
JS6 import function | Example using webpack
Assuming ES6:
config.js
export const myConfig = { importantData: '', apiUrl: '', ... };
Then:
jsxFileOne.js, jsxFileTwo.js, ...
import { myConfig } from 'config.js';
There are other ways to import & export things globally leveraging webpack, but this should get you started.
If your project is built using Webpack, consider using node-env-file.
Example config file snippets:
development.env
API_SERVER_URL=https://www.your-server.com
webpack.config.js
const envFile = require('node-env-file');
...
const appSettingsFile = isDevBuild ? '/settings/development.env' : '/settings/production.env';
try {
envFile(path.join(__dirname + appSettingsFile));
} catch (error) {
console.log("Failed to read env file!: " + __dirname + appSettingsFile);
}
...
plugins: [
new webpack.DefinePlugin({
"process.env": {
API_SERVER_URL: JSON.stringify(process.env.API_SERVER_URL)
}
})
...
]
Inside your js/jsx code, you can now access process.env.API_SERVER_URL variable which will contain the required value.
It seems dotenv package is more popular, you can try this out as well.
Very old problem, that nobody took the time to solve, until now. I leave this for future readers because this is a top search result for configuration in React.
I created wj-config to deal exactly with this. Be sure to pay close attention to the React notes as you will need to enable top-level awaits in webpack, either by ejecting or using the #craco/craco NPM package.
You may also read this blog post that explains its use.

Categories

Resources