Location of static application settings - reactjs

I'm developing a Redux/ReactJS application and I have a list of application settings.
I'm trying to decide if I should have them in the store or if I should create a file which contains the settings and import it where I need it.

It depends on the nature of the 'application settings'.
For the secure things
Like API keys, etc. Use environment variables. You can use something like dotenv to make simulating other environments easier.
For constants
Like strings and colors and external URLs, I use a constants file with multiple exports. Then in each module I import whatever I need, like so:
import {
ANIMATION_DURATION,
COLORS,
MODALS,
TEXT_PADDING,
} from '../../constants.js';
For environment-specific things (e.g. dev, prod ...)
For example API URLs or log levels, etc. use a set of config files. So you might have a config-dev.js and config-prod.js and then a config.js that returns the correct file's contents based on process.env.NODE_ENV

Application settings should be just a const in some file. In this way, for different configurations, the settings can be toggled.
An example of settings file could be:
let apiUrl = 'http://prodUrl';
// __DEV__ defaults to true in simulator.
if (__DEV__) {
apiUrl = 'http://devUrl';
}
export const settings = {
apiUrl,
registerUrl: `${apiUrl}/api/register`,
educationUrl: `${apiUrl}/api/education`,
};

Related

Authentication to serve static files on Next.js?

So, I looked for a few authentication options for Next.js that wouldn't require any work on the server side of things. My goal was to block users from entering the website without a password.
I've set up a few tests with NextAuth (after a few other tries) and apparently I can block pages with sessions and cookies, but after a few hours of research I still can't find how I would go about blocking assets (e.g. /image.png from the /public folder) from non-authenticated requests.
Is that even possible without a custom server? Am I missing some core understanding here?
Thanks in advance.
I did stumble upon this problem too. It took my dumbass a while but i figured it out in the end.
As you said - for auth you can just use whatever. Such as NextAuth.
And for file serving: I setup new api endpoint and used NodeJS magic of getting the file and serving it in pipe. It's pretty similar to what you would do in Express. Don't forget to setup proper head info in your response.
Here is little snippet to demonstrate (typescript version):
import { NextApiRequest, NextApiResponse } from 'next'
import {stat} from "fs/promises"
import {createReadStream, existsSync} from "fs"
import path from "path"
import mime from "mime"
//basic nextjs api
export default async function getFile (req: NextApiRequest, res: NextApiResponse) {
// Dont forget to auth first!1!!!
// for this i created folder in root folder (at same level as normal nextjs "public" folder) and the "somefile.png" is in it
const someFilePath = path.resolve('./private/somefile.png');
// if file is not located in specified folder then stop and end with 404
if (! existsSync(someFilePath)) return res.status(404);
// Create read stream from path and now its ready to serve to client
const file = createReadStream(path.resolve('./private/somefile.png'))
// set cache so its proper cached. not necessary
// 'private' part means that it should be cached by an invidual(= is intended for single user) and not by single cache. More about in https://stackoverflow.com/questions/12908766/what-is-cache-control-private#answer-49637255
res.setHeader('Cache-Control', `private, max-age=5000`);
// set size header so browser knows how large the file really is
// im using native fs/promise#stat here since theres nothing special about it. no need to be using external pckages
const stats = await stat(someFilePath);
res.setHeader('Content-Length', stats.size);
// set mime type. in case a browser cant really determine what file its gettin
// you can get mime type by lot if varieties of methods but this working so yay
const mimetype = mime.getType(someFilePath);
res.setHeader('Content-type', mimetype);
// Pipe it to the client - with "res" that has been given
file.pipe(res);
}
Cheers

React : webpack.config.js modification to import json variables in a sass file?

I am trying to import variables from .json file in a .scss file with node-sass-json-importer package.
I am facing a problem because this package is not automatically integrated in react-scripts/config/webpack.config.js. So, I would like to modify this file as follows below :
Add const jsonImporter = require ('node-sass-json-importer');
Add an optional preProcessorOptions object parameter to getStyleLoaders function. Indeed, this function has no preprocessor options const getStyleLoaders = (cssOptions, preProcessor) and the only option added by default is sourceMap: true. Of course, this function will take in account this new parameter.
Add a third parameter in the getStyleLoaders call for scss file.
{
implementation: require("sass"),
sassOptions: {
importer: jsonImporter(),
}
}
It works on a minimal webpack implementation (without react). But, I suppose it is not so easy to apply changes to react-scripts/config/webpack.config.js and I suspect I will have many problems. Perhaps, there is an another way to do it.
Thanks for answer.

Why webpack imports all files in subdirectory instead of the right

I have React app which render 300 pages. They are divided into 4 groups. There are common settings, custom settings for each group and settings for each page in .json files. I don't want to load all the settings for all pages, but only those needed for a particular page. I try use require to import necessary file:
const getThemeConfig = (theme) => {
const filePath = `./themes/${theme}/config.json`;
return require(`${filePath}`)
};
const themeConfig = getThemeConfig(currentTheme);
this file is imported, but at the same time the application tries to upload absolutely all .json files in ./themes directory. IDK how to fix it.

test database for react-native app development

I'm in the early stages of developing an app with react-native, and I need a DB implementation for for testing and development. I thought that the obvious choice would be to use simple JSON files included with the source, but the only way I see to load JSON files requires that you know the file name ahead of time. This means that the following does not work:
getTable = (tableName) => require('./table-' + tableName + '.json') // ERROR!
I cannot find a simple way to load files at runtime.
What is the proper way to add test data to a react-native app?
I cannot find a simple way to load files at runtime.
In node you can use import() though I'm not sure if this is available in react-native. The syntax would be something like:
async function getTable(tableName){
const fileName = `./table-${tableName}.json`
try {
const file = await import(fileName)
} catch(err){
console.log(err
}
}
though like I said I do not know if this is available in react-natives javascript environment so ymmv
Unfortunately dynamic import not supported by react-native but there is a way so to do this
import tableName1 from './table/tableName1.json';
import tableName2 from './table/tableName2.json';
then create own object like
const tables = {
tableName1,
tableName2,
};
after that, you can access the table through bracket notation like
getTable = (tableName) => tables[tableName];

How do I implement environment-specific configuration settings in AngularJS and Typescript

I'm putting together a AngularJS+Typescript+VisualStudio project. I want to have a configuration file with constants in it that control different settings (e.g., REST API URLs and environment names). How is this typically done in this kind of project?
I might have a dev config file called app.dev.config.ts like this:
module app.config {
export class ConfigSettings {
static environment(): string { return "dev"; }
static dataApiBaseUrl(): string { return "DevDataService"; }
}
}
and an app.prod.config.ts like this:
module app.config {
export class ConfigSettings {
static environment(): string { return "prd"; }
static dataApiBaseUrl(): string { return "PrdDataService"; }
}
}
Of course this doesn't actually work because these two classes have the same name.
I need to set this up in a way so that I build this only once in my build server, and then can deploy this to a fixed (3) number of environments. Maybe this means that when I go to deploy this to some environment, I have an additional step where I rename a config file. This is what I do for C# projects and their config files.
I've searched around online for this, but all I can find is references to tsconfig.json files.
I found a solution for this.
1) I put together separate config files like env.dev.ts and env.prd.ts in my project. Their contents look like this:
angular.module('compdb') //module name matches my main module
.constant('env', 'prd')
.constant('key1', 'prd value 1')
.constant('key2', 'prd value 2');
2) Visual Studio transpiles these to env.dev.js, etc.
3) In my gulp file, I copy the env.*.js files to my output directory.
4) In my Index.cshtml file, I include env.js. I include this after my scripts that create the compdb angular module
5) When I deploy my code to any environment, I rename the appropriate config file (e.g., env.prd.js) to env.js

Resources