Can we create Environment Variables for backbone applications? - backbone.js

We are building a backbone application that uses a set of REST APIs. What we want to do ideally is to have different config files for dev and live that are determined by environment variables. Is it possible.
Thanks in advance

I recommend you to have one file in a way like this:
var YourProject = {};
YourProject.Config = {
Local : {
db : 'mysql:dumy:dummy#localhost',
relativeUrl : 'blabla',
otherConfig : '123456'
},
Dev : {
db : 'mysql:dumy:dummy#localhost',
relativeUrl : 'blabla',
otherConfig : '123456'
},
Production : {
db : 'mysql:dumy:dummy#localhost',
relativeUrl : 'blabla',
otherConfig : '123456'
}
}
And then in your utilities to have something like this:
YourProject.ConfigHandler = {
getValue : function(key){
var env;
switch( window.location.hostname ){
case "localhost":
case "127.0.0.1":
env = 'Local';
break;
case "dev.yourdomain.com":
env = 'Dev';
break;
case "yourdomain.com":
env = 'Production';
break;
default:
throw('Unknown environment: ' + window.location.hostname );
}
return YourProject.Config[env][key];
}
};
So you will have just one file and for call differents API DB urls you will need to call just one line:
YourProject.ConfigHandler.getValue( 'db' );

Your question can be targeted to any javascript application, not just a backbone application, so the following answer is more general:
What I do is have a config.js file that is the first thing loaded in your HTML. The content is just a JSON object with configuration:
var CONFIG = {
debug : false,
server : 'http://production.foo.com'
};
Now every component of your app can access the configuration since CONFIG is a global object. So you can write this anywhere in your app:
if (CONFIG.debug) {
console.log('my debug stuff...');
}
The trick is to have 2 config.js files. One for development and one for production. When you want to publish your application, bundle your production config.js file and upload it to your server.
You can create a build script to build your application for production. As a first step, it could copy the correct config.js file to the right location. You can also add steps to minify your js files, bundle them into one file and more.

I adapted Daniel's nice answer to Coffeescript/CommonJS, so in my config.coffee I have:
env = switch window.location.hostname
when "localhost", "127.0.0.1"
"development"
when "www.example.com", "example.com"
"production"
config =
development:
urlRoot: "http://localhost:3000"
production:
urlRoot: "http://www.example.com"
module.exports = config[env]
And then client code looks like:
config = require("config")
config.urlRoot

Related

Vite serving shader file with wrong (none) MIME type

I'm developing a BabylonJS application. BabylonJS PostProcess class appends .fragment.fx to a given file name and requests that from the server. When my local Vite (version 4.0.4) dev server serves this file the content-type header is empty. This causes Firefox to intepret it as type xml and fail. Chrome fails through a different, but I think related, mechanism.
How do you configure Vite to serve the *.fragment.fx static files as text/plain? I assume I need to disable the default middleware and write some custom code instead, like this: https://vitejs.dev/config/server-options.html#server-middlewaremode but I wanted to first check there wasn't something else going on / a simpler way to configure / fix this.
The vite dev server is started using vite --host --port 3000 --force and the config in vite.config.js is:
import { defineConfig } from 'vite';
export default defineConfig(({ command, mode }) => {
// if (command === 'serve') {
// return {
// // dev specific config
// }
// } else {
// // command === 'build'
// return {
// // build specific config
// }
// }
return {
resolve: {
alias: {
"babylonjs": mode === "development" ? "babylonjs/babylon.max" : "babylonjs",
}
},
base: "",
// assetsInclude: ['**/*.fx'],
};
});
* edit 1 *
I have seen there's a parameter ?raw that can be added to the URL however I don't control how BabylonJS forms the URL so I can't see how to make this work in this situation.
I followed these instructions and set up a dev server using express. I added this block of code above the call to app.use(vite.middlewares):
app.use("**/*.*.fx", async (req, res, next) => {
const url = req.originalUrl
const file_path = path.resolve(__dirname, "." + url)
const file = fs.readFileSync(file_path, "utf-8")
res.status(200).set({ "Content-Type": "text/plain" }).end(file)
})
I now start the dev server using the following script line in the package.json of "dev": "node server",
I could not find a way to solve this by configuring the default vite dev server.

Why is my amplify environment variable appearing for just a moment then disappearing again [duplicate]

So i'm using the Contentful API to get some content from my account and display it in my Next.Js app (i'm using next 9.4.4). Very basic here. Now to protect my credentials, i'd like to use environment variables (i've never used it before and i'm new to all of this so i'm a little bit losted).
I'm using the following to create the Contentful Client in my index.js file :
const client = require('contentful').createClient({
space: 'MYSPACEID',
accessToken: 'MYACCESSTOKEN',
});
MYSPACEID and MYACCESSTOKEN are hardcoded, so i'd like to put them in an .env file to protect it and don't make it public when deploying on Vercel.
I've created a .env file and filled it like this :
CONTENTFUL_SPACE_ID=MYSPACEID
CONTENTFUL_ACCESS_TOKEN=MYACCESSTOKEN
Of course, MYACCESSTOKEN and MYSPACEID contains the right keys.
Then in my index.js file, i do the following :
const client = require('contentful').createClient({
space: `${process.env.CONTENTFUL_SPACE_ID}`,
accessToken: `${process.env.CONTENTFUL_ACCESS_TOKEN}`,
});
But it doesn't work when i use yarn dev, i get the following console error :
{
sys: { type: 'Error', id: 'NotFound' },
message: 'The resource could not be found.',
requestId: 'c7340a45-a1ef-4171-93de-c606672b65c3'
}
Here is my Homepage and how i retrieve the content from Contentful and pass them as props to my components :
const client = require('contentful').createClient({
space: 'MYSPACEID',
accessToken: 'MYACCESSTOKEN',
});
function Home(props) {
return (
<div>
<Head>
<title>My Page</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main id="page-home">
<Modal />
<NavTwo />
<Hero item={props.myEntries[0]} />
<Footer />
</main>
</div>
);
}
Home.getInitialProps = async () => {
const myEntries = await client.getEntries({
content_type: 'mycontenttype',
});
return {
myEntries: myEntries.items
};
};
export default Home;
Where do you think my error comes from?
Researching about my issue, i've also tried to understand how api works in next.js as i've read it could be better to create api requests in pages/api/ but i don't understand how to get the content and then pass the response into my pages components like i did here..
Any help would be much appreciated!
EDIT :
So i've fixed this by adding my env variables to my next.config.js like so :
const withSass = require('#zeit/next-sass');
module.exports = withSass({
webpack(config, options) {
const rules = [
{
test: /\.scss$/,
use: [{ loader: 'sass-loader' }],
},
];
return {
...config,
module: { ...config.module, rules: [...config.module.rules, ...rules] },
};
},
env: {
CONTENTFUL_SPACE_ID: process.env.CONTENTFUL_SPACE_ID,
CONTENTFUL_ACCESS_TOKEN: process.env.CONTENTFUL_ACCESS_TOKEN,
},
});
if you are using latest version of nextJs ( above 9 )
then follow these steps :
Create a .env.local file in the root of the project.
Add the prefix NEXT_PUBLIC_ to all of your environment variables.
eg: NEXT_PUBLIC_SOMETHING=12345
use them in any JS file like with prefix process.env
eg: process.env.NEXT_PUBLIC_SOMETHING
You can't make this kind of request from the client-side without exposing your API credentials. You have to have a backend.
You can use Next.js /pages/api to make a request to Contentful and then pass it to your front-end.
Just create a .env file, add variables and reference it in your API route as following:
process.env.CONTENTFUL_SPACE_ID
Since Next.js 9.4 you don't need next.config.js for that.
By adding the variables to next.config.js you've exposed the secrets to client-side. Anyone can see these secrets.
New Environment Variables Support
Create a Next.js App with Contentful and Deploy It with Vercel
Blog example using Next.js and Contentful
I recomended to update at nextjs 9.4 and up, use this example:
.env.local
NEXT_PUBLIC_SECRET_KEY=i7z7GeS38r10orTRr1i
and in any part of your code you could use:
.js
const SECRET_KEY = process.env.NEXT_PUBLIC_SECRET_KEY
note that it must be the same name of the key "NEXT_PUBLIC_ SECRET_KEY" and not only "SECRET_KEY"
and when you run it make sure that in the log says
$ next dev
Loaded env from E:\awesome-project\client\.env.local
ready - started server on http://localhost:3000
...
To read more about environment variables see this link
Don't put sensitive things in next.config.js however in my case I have some env variables that aren't sensitive at all and I need them Server Side as well as Client side and then you can do:
// .env file:
VARIABLE_X=XYZ
// next.config.js
module.exports = {
env: {
VARIABLE_X: process.env.VARIABLE_X,
},
}
You have to make a simple change in next.config.js
const nextConfig = {
reactStrictMode: true,
env:{
MYACCESSTOKEN : process.env.MYACCESSTOKEN,
MYSPACEID: process.env.MYSPACEID,
}
}
module.exports = nextConfig
change it like this
Refer docs
You need to add a next.config.js file in your project. Define env variables in that file and those will be available inside your app.
npm i --save dotenv-webpack#2.0.0 // version 3.0.0 has a bug
create .env.development.local file in the root. and add your environment variables here:
AUTH0_COOKIE_SECRET=eirhg32urrroeroro9344u9832789327432894###
NODE_ENV=development
AUTH0_NAMESPACE=https:ilmrerino.auth0.com
create next.config.js in the root of your app.
const Dotenv = require("dotenv-webpack");
module.exports = {
webpack: (config) => {
config.resolve.alias["#"] = path.resolve(__dirname);
config.plugins.push(new Dotenv({ silent: true }));
return config;
},
};
However those env variables are gonna be accessed by the server. if you want to use any of the env variables you have to add one more configuration.
module.exports = {
webpack: (config) => {
config.resolve.alias["#"] = path.resolve(__dirname);
config.plugins.push(new Dotenv({ silent: true }));
return config;
},
env: {
AUTH0_NAMESPACE: process.env.AUTH0_NAMESPACE,
},
};
For me, the solution was simply restarting the local server :)
Gave me a headache and then fixed it on accident.
It did not occur to me that env variables are loaded when the server is starting.

How to set different basepath for images in production and development in React

I'm retrieving my images on production as:
src="/dibble_back_end/images/icon.png"
Which then is proxied through my nginx:
location /dibble_back_end {
proxy_pass http://dibble_back_end:4000;
rewrite ^/dibble_back_end(.*)$ $1 break;
}
The issue is that on development react server is running in ExpressJS not on ngInx. I'd want to based on environment variable be able to switch between production and development.
e.g.
Dev:
src="localhost:4000/images/icon.png"
Production:
src="/dibble_back_end/images/icon.png"
You are not providing details about your setup but if you are using Create a React App than you can use the NODE_ENV environment variable, something like:
const src = process.env.NODE_ENV === 'production' ? "/dibble_back_end/images/icon.png" : "localhost:4000/images/icon.png"
or
const basePath = process.env.NODE_ENV === 'production' ? "/dibble_back_end" : "localhost:4000";
const src = `${src}/images/icon.png`;

firebase get current project name react

Is there a way to retrieve the current project name that was activated through firebase use project-name? I've set up several projects in firebase as different environments. Since using the same codebase my problem is that the script doesn't know which configurations to use.
Found this related issue process.env.GCLOUD_PROJECT and according to docs it's automatically populated but only seems to return undefined.
So I have a config and using it like this;
const config = {
prod: {
apiKey: ...
},
stage: {
apiKey: ...
}
};
const config = process.env.ACTIVE_ENV === 'production' ? prodConfig : devConfig;
firebase.initializeApp(config);
What I'm trying to achieve is that when I run firebase use stage-proj it will populate the right config details and also for running firebase deploy.

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