Import different file depending on environment - reactjs

I'm using Create-React-App. I have 2 static JSON files with data which is different depending on the environment they run in.
What is the best approach to importing the files based on the environment the application runs in?
I have this but it doesn't look right, any other advice?
if (process.env.NODE_ENV !== 'production') {
import data from './data/devData';
}
if (process.env.NODE_ENV === 'production') {
import data from './data/prodData';
}

Another idea - add to your wabpack alias
resolve: {
alias: {
'config/data': path.resolve(__dirname, `./data/${process.env.NODE_ENV}`)
}
}
and call it from component this way:
import { data } from 'config/data';

You can create one file config with keys for example "default" and "production". Once import with file, check process.env and return actual config object.
const config = require('./data/config.json');
function getConfig() {
let customConfig = config['default'];
if (process.env.NODE_ENV === 'production') {
customConfig = config['production'];
}
return customConfig;
}

Related

How do add process.env when using vite?

I got a react project I'm building with vite.
This project uses #mui and inside it, they have -
if (typeof process !== 'undefined' && process.env.GRID_EXPERIMENTAL_ENABLED !== undefined && localStorageAvailable() && window.localStorage.getItem('GRID_EXPERIMENTAL_ENABLED')) {
experimentalEnabled = window.localStorage.getItem('GRID_EXPERIMENTAL_ENABLED') === 'true';
} else if (typeof process !== 'undefined') {
experimentalEnabled = process.env.GRID_EXPERIMENTAL_ENABLED === 'true';
}
When they try and access process.env.GRID_EXPERIMENTAL_ENABLED, it fails, saying it can't get GRID_EXPERIMENTAL_ENABLED of undefined.
I logged process, and it's an empty object.
I tried different ways of generating a process env through the vite.config.ts file, but nothing worked.
Expected result - 3rd party libs should be able to access process.env
Insite the Vite environment
Vite exposes env variables on the special import.meta.env object.
So instead of
process.env.GRID_EXPERIMENTAL_ENABLED
Do
import.meta.env.GRID_EXPERIMENTAL_ENABLED
If the variables still don't show up, its because vite only exposes variables starting with the VITE_ keyword.
So try
import.meta.env.VITE_GRID_EXPERIMENTAL_ENABLED
And in you .env file
VITE_GRID_EXPERIMENTAL_ENABLED=true
Outside the Vite environment
If you are trying to access .env variables outside Vite then you have to expose them first.
// vite.config.(ts/js)
import { defineConfig, loadEnv } from 'vite';
export default ({ mode }) => {
// Load app-level env vars to node-level env vars.
process.env = {...process.env, ...loadEnv(mode, process.cwd())};
return defineConfig({
// You can now use process.env.GRID_EXPERIMENTAL_ENABLED
});
}

Webpack obfuscator not working with craco, maps disabled

today I have a very large problem using react & craco, I can't seem to get my webpack-obfuscator to do anything. I have disabled source maps, but to no avail.
This is my craco config:
const path = require("path");
const WebpackObfuscator = require('webpack-obfuscator');
module.exports = {
webpack: {
configure: (webpackConfig) => {
// Because CEF has issues with loading source maps properly atm,
// lets use the best we can get in line with `eval-source-map`
if (webpackConfig.mode === 'development' && process.env.IN_GAME_DEV) {
webpackConfig.devtool = 'eval-source-map'
webpackConfig.output.path = path.join(__dirname, 'build')
}
return webpackConfig
},
plugins: {
add: [
new WebpackObfuscator ({
rotateStringArray: true
}),
],
},
},
devServer: (devServerConfig) => {
if (process.env.IN_GAME_DEV) {
// Used for in-game dev mode
devServerConfig.writeToDisk = true
}
return devServerConfig
}
}
I get no visible maps files when building, and I've put "GENERATE_SOURCEMAP=false" in my .env file that's located where the package.json is.
Hopefully someone has the answer as to why this is happening.
Kind regards, and thanks for reading.
To upgrade a short config, you can use a construct that, if the condition is met, updates the configuration without using WebpackObfuscator:
module.exports = {
webpack: {
configure: {
...(process.env.IN_GAME_DEV && process.env.NODE_ENV === 'development' && {devtool: 'eval-source-map'})
}
}
}
Also, if you need additional properties for the configuration, in addition to the dvttool, you can add them

React/Next.js recommended way to set constants such as backend API URLs

I am looking through next.js documentation and trying to understand what the suggested approach is for setting URLs that change in different environments. Mostly, I want to ensure that I'm pointing backend URLs correctly in development versus production.
I suppose you can create a constants configuration file, but is there a supported, best practice for this?
Open next.config.js and add publicRuntimeConfig config with your constants:
module.exports = {
publicRuntimeConfig: {
// Will be available on both server and client
yourKey: 'your-value'
},
}
you can call it from another .js file like this
import getConfig from 'next/config'
const { publicRuntimeConfig } = getConfig()
console.log(publicRuntimeConfig.yourKey)
or even call it from view like this
${publicRuntimeConfig.yourKey}
You can configure your next app using next-runtime-dotenv, it allows you to specify serverOnly / clientOnly values using next's runtime config.
Then in some component
import getConfig from 'next/config'
const {
publicRuntimeConfig: {MY_API_URL}, // Available both client and server side
serverRuntimeConfig: {GITHUB_TOKEN} // Only available server side
} = getConfig()
function HomePage() {
// Will display the variable on the server’s console
// Will display undefined into the browser’s console
console.log(GITHUB_TOKEN)
return (
<div>
My API URL is {MY_API_URL}
</div>
)
}
export default HomePage
If you don't need this separation, you can use dotenv lib to load your .env file, and configure Next's env property with it.
// next.config.js
require('dotenv').config()
module.exports = {
env: {
// Reference a variable that was defined in the .env file and make it available at Build Time
TEST_VAR: process.env.TEST_VAR,
},
}
Check this with-dotenv example.

How to import minified js file on react create app

So I have this Create react app (I don't really understand webpack), and I wanted to use EaselJS on this one, However the NPM counterpart of EselJS is their version 2 (BETA) and is quite unstable and undocumented - That's why I wanted to use the minified version.
I have a easeljs.min.js on my project but I don't know how to "import it".
doing `import './easeljs.min.js' seems to also generate a lot of linting issues and seems to nor work.
EDIT:
I tried using react-helmet and append it as a script tag, but it seems that react is doing something with the minified version and causes it to error. (unexpected token <)
So I was able to fix it:
I installed react-app-rewired created config-overrides.js and added this code:
module.exports = function override(config, env) {
if (!config.resolve || Object.keys(config.resolve).length === 0) {
config.resolve = {};
}
if (!config.module || Object.keys(config.module).length === 0) {
config.module = {};
}
if (!config.module.rules || config.module.rules.length === 0) {
config.module.rules = [];
}
const resolve = {
alias: {
createjs: "createjs/builds/1.0.0/createjs.js"
}
};
config.resolve = {
...config.resolve,
...resolve
};
config.module.rules.push({
test: /node_modules[/\\]createjs/,
loaders: ["imports-loader?this=>window", "exports-loader?window.createjs"]
});
return config;
};
It seems that it is an issue with createjs itself https://github.com/CreateJS/Combined/issues/12
I also ended up using this repo for createjs.

Webpack2 keep adding dev dependancy file

I have this kind of configuration like below. However, it seems to load development script even though the if statement go into only "production"
if (process.env.NODE_ENV === 'production') {
module.exports = require('./configureStoreProd')
} else {
module.exports = require('./configureStoreDev')
}
If I delete the "import logger from 'redux-logoer", it does not show on analyzer.
I am guessing when webpack building vendor file, NODE_ENV is undefine or null. How do i set it properly ?
Workaround I used:
Your config file (that you will import in the js files you wish to use it in) that determines what file you will use depending on the environment you are in.
config.js
var config = null;
if (process.env.NODE_ENV !== 'production') {
config = require('./config.development');
}else {
config = require('./config.production');
}
export default config;
Your config production .json file that will be selected if you are in the production environment. Same goes for development.
config.production.json
{
"graphQlEndpoint": {
"uri": "YourUriHere"
},
}
In the store, you can import the config.js file and then choose what variable you want. Example: config -> graphQlEndpoint -> uri
store.js
import config from '../../configs/config';
networkInterface = createNetworkInterface({
uri: config.graphQlEndpoint.uri
});
const store = createStore(rootReducer, defaultState, networkInterface);
I found it easier to use require() and to have my config files in son. You can then use your config file with the correct environment everywhere you import it.
I suggest you test this with npm run build.
Hope this helps

Resources