Im in a project where we will create different sites using the same codebase.
I would like to have a brand style and config for each site which I specify somehow in my build process.
Anyone have an idea of the best way to achieve this ?
I would treat the different sites in much the same way I'd treat different environment (dev, test, prod). If there aren't a lot of changes, just use environment variables on each server where the site will run that define which site it is. Your code can then conditionally do things (e.g. add a class site-x to the body for styling).
You can use something like dotenv to make setting environment vars easier (remember Windows does it differently to *NIX) if you're setting environments in a script. That way you're changing a file rather then actual environment variables when you want to test what a particular site looks like.
If there are many different config items that are different between sites then you can have multiple config files (config-site-one.js, config-site-two.js) and a central config.js file that returns the correct config based on some environment variable like MY_SITE_NAME.
However if you actually want to package up the site to 'send' somewhere (?) then you could run your build command with a flag like webpack blahblahblah --site=site-one.
You can use yargs to get that 'site' variable and use it in your build process however you like.
Related
Reacts documentation says "Environment variables are embedded into the build, meaning anyone can view them by inspecting your app's files".
I am assuming its because the .env. file where I would define them will be included in the build (or not because of that?!)?
So then,what the point of using react environment variables if i cannot hide any keys?
Or do I just not understand it and I can hide keys using react environment variables (a tutorial I am watching says you can hide them using it)?
What if I define those variables inside my shell? Are they exposed as well?
Thank you!!
Environment variables help because they can let you customize settings without changing the source code. In terms of the code that runs, the end result is the same - yes, whatever client runs the code will be able to see what's going on, including any API keys you include with the app - but it makes the development process easier when there's a single place where you can set settings that can differ between environments without changing the code itself.
This is of the greatest benefit when using source control like Git. If you make a change to a build setting - such as the change to an API key - it wouldn't make sense for that change to be checked into the codebase's history. Rather, the convention is to instead have the application read its environment variables, and have those not checked into source control, allowing the settings to be easily changed without changing anything else in the application's code itself.
See An Introduction to Environment Variables and How to Use Them for a decent summary.
if i cannot hide any keys?
Hiding API keys is a completely separate issue - it's not something that environment variables are meant to solve. If you want to hide your keys, there are at least two approaches:
Put the keys on your server, and then have the client make requests to your server, and have your server use the (secret) API key to the external service, then echo the result back to the client
Some APIs which provide keys also provide the ability to whitelist requests from certain domains, and to block requests from others. For example, depending on what you're using, you may have the ability to go into the API's settings to enable your key with mysite.com, and block it from being recognized as valid from any other site. This way, even if the API key is public, it's not (much) of a problem.
Environmental variables in react are always prefixed with REACT_APP_ and are used when you want to change values across your frontend react application. They're not designed to hide API keys which are intended to be private.
Variables that do not start with that prefix will not be visible in the final build (You can also use two .env files).
No variables defined inside your server shell will be exposed.
I whant to get the type.name from components at production build. I created https://codesandbox.io/s/w505nnql7 from sandbox here and development build works perfect. But in my production environment https://www.ginte.com.br/ you can see at the console that return 'e' where in the sandbox return 'Button'
This is intended behaviour. For the production build, your build tool (most likely webpack) shortens all variable names to optimise the bundle. If you have a look at your compressed javascript file you'll find out none of your variables, including variables like component names are the way they were when you wrote your code. They are now replaced with single characters so as to save memory when executing the bundle thus increasing performance.
If you want to save component name in production build, try saving the component name in a permanent way like setting it to state or as static properties. At build time these can't be affected.
I am trying to make a folder to be not watched. Is there a way to make one of the folders not watched in Meteor? I don't want my project to reload if I change a content in that folder.
Not exactly. Meteor assumes that if the folder content changes, it also needs to reload/restart the server, because the business logic of the application might have changed. Therefore it reloads these files and restarts the server
However, you might be able to "abuse" the tests/ directory or any of the directories/files mentioned below for that purpose. As explained in the Meteor guide on Application Structure, paragraph "Special directories":
Any directory named tests/ is not loaded anywhere. Use this for any test code you want to run using a test runner outside of Meteor’s built-in test tools.
The following directories are also not loaded as part of your app code:
Files/directories whose names start with a dot, like .meteor and .git
packages/: Used for local packages
cordova-build-override/: Used for advanced mobile build customizations
programs: For legacy reasons
So the reasonable choice would be to create a dot directory, e.g. .myStuff, and place anything that you might need to update but do not want to trigger a server restart there.
Just build your app in a package so you can decide which files you want to make available or not :)
I have an angular constant which defines webservice end point
angular.module('myModule').constant('mywebservice_url', 'http://192.168.1.100')
The problem is that for dev I have a different end point while staging and production its different. Every time I try to check in to git I have to manually reset this file.
Is there any way git permenantly ignore this file but checks out the file while clone or checkout?
Is there any way I can make angular pickup file dynamically from something like environment variable.
NOTE: I don't want to depend on server to do this, ie I don't want to use apach SSI or any of those technologies as it will work only one set of servers.
Delaying the injection via backend processing. I usually just create a global object on html page called pageSettings which values like this is getting injected from the backend, i.e. environment variables, etc. and just pass that global pageSettings object into that angular constant or value.
Build system injection. If you don't have a backend, i.e. pure SPA... maybe you can put this inside your build system, i.e. create multiple task for building the different environments in gulp or grunt and replace that value during the build process.
In e.a. your app init code:
var x = location.hostname;
Then define 2 different constants.
One based off the domain name of your develop environment and one for your production.
I'd like my Play app to use different databases for test, local and production (production is Heroku) environments.
In application.conf I have:
db.default.driver=org.postgresql.Driver
%dev.db.default.url="jdbc:postgresql://localhost/foobar"
%test.db.default.url="jdbc:postgresql://localhost/foobar-test"
%prod.db.default.url=${DATABASE_URL}
This doesn't seem to work. When I run play test or play run,
all DB access fails with:
Configuration error [Missing configuration [db.default.url]] (Configuration.scala:258)
I have a few questions about this:
In general, I'm a little confused about how databases are configured
in Play: it looks like there's plain db, db.[DBNAME] and db.
[DBNAME].url and different tutorials make different choices among
those. Certain expressions that seem like they should work (e.g. db.default.url = "jdbc:..." fail with an error that a string was provided where an object was expected).
I've seen other people suggest that I create separate prod.conf, dev.conf and test.conf files that each include application.conf and then contain DB-specific configuration. But in that case, how do I specify what database to use when I run test from the Play console?
Is the %env syntax supposed to work in Play 2?
What's the correct way to specify an environment for play test to use?
In Play 2 there aren't different config environments. Instead you just set or override the config parameters in the conf/application.conf file. One way to do it is on the play command line, like:
play -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=$DATABASE_URL ~run
You can also tell Play to use a different config file:
play -Dconfig.file=conf/prod.conf ~run
For an example Procfile for Heroku, see:
https://github.com/jamesward/play2bars/blob/scala-anorm/Procfile
More details in the Play Docs:
http://www.playframework.org/documentation/2.0/Configuration
At least in Play 2.1.1 it is possibly to override configuration values with environment variables, if they are set. (For details see: http://www.playframework.com/documentation/2.1.1/ProductionConfiguration)
So you can set the following in your conf/application.conf:
db.default.url="jdbc:mysql://localhost:3306/my-db-name"
db.default.url=${?DATABASE_URL_DB}
per default it will use the JDBC-URL defined unless the environment variable DATABASE_URL_DB defines a value for it.
So you just set your development database in the configuration and for production or stages you define the environment variable.
But beware, this substitution does NOT WORK if you put your variable reference inside quoted strings:
db.default.url="jdbc:${?DATABASE_URL_DB}"
Instead, just unquote the section to be substituted, for example.
database_host = "localhost"
database_host = ${?ENV_DATABASE_HOST}
db.default.url="jdbc:mysql://"${?database_host}":3306/my-db-name"
In this example, localhost will be used by default if the environment variable ENV_DATABASE_HOST is not set. (For details see: https://www.playframework.com/documentation/2.5.x/ConfigFile#substitutions)
You can actually still use the Play 1.0 config value naming method, in Play 2, if you, when you load config values, check if Play.isTest, and then prefix the properties you load with 'test.'. Here's a snipped:
def configPrefix = if (play.api.Play.isTest) "test." else ""
def configStr(path: String) =
Play.configuration.getString(configPrefix + path) getOrElse
die(s"Config value missing: $configPrefix$path")
new RelDb(
server = configStr("pgsql.server"),
port = configStr("pgsql.port"),
database = configStr("pgsql.database"),
user = ...,
password = ...)
And the related config snippet:
pgsql.server="192.168.0.123"
pgsql.port="5432"
pgsql.database="prod"
...
test.pgsql.server="192.168.0.123"
test.pgsql.port="5432"
test.pgsql.database="test"
...
Now you don't need to remember setting any system properties when you run your e2e test suite, and you won't accidentally connect to the prod database.
I suppose that you can optionally place the test. values in a separate file, which you would then include at the end of the main config file I think.
There is another approach which is to override Global / GlobalSettings method onLoadConfig and from there you can setup application configuration with generic config and specific environment configuration like below...
conf/application.conf --> configurations common for all environment
conf/dev/application.conf --> configurations for development environment
conf/test/application.conf --> configurations for testing environment
conf/prod/application.conf --> configurations for production environment
You can check http://bit.ly/1AiZvX5 for my sample implementation.
Hope this helps.
Off-topic but if you follow 12-factor-app then having separate configurations named after environments is bad:
Another aspect of config management is grouping. Sometimes apps batch config into named groups (often called “environments”) named after specific deploys, such as the development, test, and production environments in Rails. This method does not scale cleanly: as more deploys of the app are created, new environment names are necessary, such as staging or qa. As the project grows further, developers may add their own special environments like joes-staging, resulting in a combinatorial explosion of config which makes managing deploys of the app very brittle
source: http://12factor.net/config