Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment-specific configurations via polymer.json #2259

Open
cdata opened this issue Sep 16, 2016 · 14 comments
Open

Environment-specific configurations via polymer.json #2259

cdata opened this issue Sep 16, 2016 · 14 comments
Labels

Comments

@cdata
Copy link
Member

@cdata cdata commented Sep 16, 2016

As a Polymer app author,
when I build my sharded application with polymer-cli,
I want to include a specialized environment configuration in the build output,
so that my app can adapt to being deployed to production.

Environment-specific Configurations

This is a design proposal for a new feature of the polymer build command.

Users can include an "environment" field in polymer.json that is a mapping of environment names to configurations. polymer build --env $envName can be used to select one of the configurations. Selecting a configuration causes that configuration to set as Polymer's configuration in the build artifact. So, if I have a polymer.json like:

{
  "entrypoint": "index.html",
  "shell": "src/foo-app/foo-app.html",
  "fragments": [
    "src/foo-app/fragment-one.html",
    "src/foo-app/fragment-two.html",
    "src/foo-app/fragment-three.html"
  ],
  "environment": {
    "production": {
      "lazyRegister": true,
      "custom": "foo"
    }
  }
}

And I run the CLI with polymer build --env production, I get a script tag added to my index that looks like:

<script>
window.Polymer = {
  lazyRegister: true,
  custom: "foo"
};
</script>

Alternative approach: configure global ENV property

One alternative approach would be to configure a global ENV property with the configuration values. This has the advantage of being more generalized, at the cost of requiring additional coordination in the main document. Assuming the above polymer.json is used, the polymer build --env production command would produce this script in the document:

<script>
<!-- NOTE: ENV name is just a strawman -->
window.ENV = window.ENV || {};
window.ENV.lazyRegister = true;
window.ENV.custom = 'foo';
</script>

Using this alternative approach, the same end result as the first design could be achieved with the following basic cooperation by the app author:

<script>
if (window.ENV) {
  window.Polymer = window.ENV;
}
</script>

Rationale

There is some precedence for this feature in other similar CLI tools:

@pdesjardins90
Copy link

@pdesjardins90 pdesjardins90 commented Apr 7, 2017

Any update on this?

@JonathanSidego
Copy link

@JonathanSidego JonathanSidego commented Apr 10, 2017

How are people handling environmental variables in Polymer at the moment?

@pdesjardins90
Copy link

@pdesjardins90 pdesjardins90 commented Apr 10, 2017

Having 3 config files (local, staging, prod), I've resolved to overwrite my config file at build time on my CI server with something like this :

if [ "$BRANCH_NAME" = "staging" ]; then mv app.conf.staging.json app.conf.json; fi

it gets the job done for CI, but a CLI argument would be much better

@bradrydzewski
Copy link

@bradrydzewski bradrydzewski commented Jun 18, 2017

I have two minor requests to consider...

First, would you consider adding these environment-specific configurations to the polymer serve command as well? With our react frontend (now being re-written in polymer) we are able to define certain configuration parameters at runtime which is useful for our contributors:

npm start -- --scheme <drone scheme> \
             --host   <drone host> \
             --token  <drone api token>

which might look something like this:

npm start -- --scheme http \
             --host   localhost:8080 \
             --token  eyJhbGciOiJIUzI1NiIsInR5cCI....

Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined for you, and any other environment variables starting with REACT_APP_.

Second, would you also consider the ability to define and/or override parameters using environment variables similar to how this is handled by react [1]. This could look something like the following:

POLYMER_APP_custom=foo polymer build --env production

or alternatively with command line parameters:

polymer build --env production --env-var custom=bar

[1] https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables

@byjg
Copy link

@byjg byjg commented Jul 10, 2017

This proposal is awesome.

@MeTaNoV
Copy link

@MeTaNoV MeTaNoV commented Sep 14, 2017

It would be definitely be something very useful that most of us are already implementing one way or another...

@bendavis78
Copy link

@bendavis78 bendavis78 commented Oct 1, 2017

I'd love to see this implemented. Has anyone started a branch for this? I think it makes the most sense to put these in something window.ENV, and then any environment-specific global polymer options can be set in the document itself.

@jab
Copy link
Contributor

@jab jab commented Oct 11, 2017

Would it make sense for this to allow specifying some shared configuration that all environments would inherit, which they could extend with any additional fields needed / selectively override any fields they need to override?

@c256985
Copy link

@c256985 c256985 commented Nov 16, 2017

So, if I understand this correctly, we'd need a change to the Polymer CLI to be able to pass in an ENV mode (dev, prod, whatever), and a change to the Polymer framework itself to read the appropriate subtree of the configuration. Would the user put the configuration in polymer.json, or somewhere else? We'd also want the code to be flexible enough to accommodate any ENV mode label.

@mtnourji
Copy link

@mtnourji mtnourji commented Aug 15, 2018

2 years later, there is still no implementation about this ?

@chriszrc
Copy link

@chriszrc chriszrc commented Oct 5, 2018

Looking at the help for the polymer command, I can see this:

Global Options

  --env type                      The environment to use to specialize certain commands, like build          

Does this mean this support is here somehow now?

@chriszrc
Copy link

@chriszrc chriszrc commented Oct 5, 2018

For now, I installed replace-in-file as a dev dependency and added a post build script step in package.json:

npm i --save-dev  replace-in-file

package.json

  "name": "app-name", 
  "main": "app-name.js",
  "scripts":{
    "build:prod":"polymer build",
    "postbuild:prod":"replace-in-file /\\.\\/assets/g \"https://my.awesome.cdn.com/app-name/assets\" ./build/es5prod/app-name.js --isRegex" 
  },
  "dependencies": {
    "@polymer/polymer": "^3.0.0",

and then run:

npm run build:prod

If you have multiple builds you can pass in a glob or other pattern for matching the files. Not ideal, but it's something until we get environment support. Seems I've been spoiled by the angular cli-

@aomarks aomarks transferred this issue from Polymer/polymer-cli Jan 3, 2019
@aomarks aomarks added the Package: cli label Jan 3, 2019
@luwes
Copy link

@luwes luwes commented Mar 14, 2019

I ended up creating a gulp task to replace an .env JS object in index.html...

Requires a .env.development and .env.production file.

package.json

    "prestart": "NODE_ENV=development gulp env",
    "start": "polymer serve",
    "build": "polymer build --auto-base-path && gulp prpl-server",
    "postbuild": "NODE_ENV=production gulp env",

gulpfile.js

const dotenv = require('dotenv');

gulp.task('clear-env', () => {
	const pattern = /\.env ?= ?{([^;]+)/g;

	// development
	gulp.src('index.html')
		.pipe(replace(pattern, `.env = {
				// Populated by the gulp import-env task.
			}`))
		.pipe(gulp.dest('.'));

	// production
	return gulp.src('server/build/**/index.html')
		.pipe(replace(pattern, `.env={}`))
		.pipe(gulp.dest('server/build'));
});

gulp.task('import-env', () => {
	const result = dotenv.config({ path: `.env.${process.env.NODE_ENV}` })
	if (result.error) {
	  throw result.error
	}

	const pattern = /\.env ?= ?{([^;]+)/g;
	const replacement = `.env = ${JSON.stringify(result.parsed)}`;

	if (process.env.NODE_ENV === 'production') {
		return gulp.src('server/build/**/index.html')
			.pipe(replace(pattern, replacement))
			.pipe(gulp.dest('server/build'));
	}

	return gulp.src('index.html')
		.pipe(replace(pattern, replacement))
		.pipe(gulp.dest('.'));
});

gulp.task('env', gulp.series('clear-env', 'import-env'));

index.html

(window.process = window.process || {}).env = {};
@stale
Copy link

@stale stale bot commented Mar 13, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Mar 13, 2020
@stale stale bot removed the wontfix label Mar 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.