Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
ember-cli-conditional-compile
Advanced tools
Conditional compilation (feature-flags) for Ember apps
The goal of ember-cli-conditional-compile is to provide easy to use feature switches to Ember applications such that code that is hidden behind a disabled feature switch is not in the compiled code.
This is an ember-cli addon, so all you need to do is
ember install ember-cli-conditional-compile
Version 2.x targets Ember 3.x and beyond. It is tested against the latest ember release and the latest beta release (See config/ember-try.js for the testing matrix)
Our workaround around a broccoli pipeline bug in newer versions of ember-cli slightly changes the semantics of includeDirByFlag
. Instead of a RegExp, you now need to specify a Glob-style pattern.
To actually use the feature switches you'll need to add some configuration in your environment.js
file. For example, lets pretend you want to have two feature switches; ENABLE_FOO
and ENABLE_BAR
:
var ENV = {
// other settings ...
featureFlags: {
ENABLE_FOO: true,
ENABLE_BAR: true,
},
includeDirByFlag: {
ENABLE_FOO: ["pods/foos/**", "pods/foo/**"],
ENABLE_BAR: [],
},
};
// other environments ...
if (environment === "production") {
ENV.featureFlags.ENABLE_FOO = false;
}
Alternatively, you can define your feature flags in config/feature-flags.js
looking like this:
module.exports = function (environment) {
const GLOBAL_FLAGS = {
featureFlags: {
ENABLE_FOO: true,
ENABLE_BAR: true,
},
includeDirByFlag: {
ENABLE_FOO: [/pods\/foos/, /pods\/foo/],
ENABLE_BAR: [],
},
};
if (environment === "production") {
GLOBAL_FLAGS.featureFlags.ENABLE_FOO = false;
}
return GLOBAL_FLAGS;
};
This has two advantages: It declutters environment.js
a bit, especially if you have many flags, but also prevents your flag names from leaking into the application code under certain circumstances.
We'll look at the two new options in more detail below, but for now we can see that by default both features are enabled, but in the production
environment ENABLE_FOO
is disabled, and related code under the pods/foos
and pods/foo
directories are excluded from compilation.
This setting sets up which flags will be available to actually switch use. A value of true
means that the flag will be enabled, false
means that it will not be.
Given a key which has been defined above, the value is an array of regexes of files/paths which will only be included in the compiled product if the related feature flag is enabled. In the example above, in the development environment ENABLE_FOO
is true
, so the pods/foo
and pods/foos
paths will be included.
However, since the flag is false
in production, any code in those directories will not be compiled in.
ember-cli-conditional-compile adds itself to the Broccoli compile pipeline for your Ember application. Depending on which environment you're building it acts in two different ways:
Global variables are injected into the page which have the current state of the feature flags. For example:
if (ENABLE_FOO) {
this.route("foo");
console.log("The feature ENABLE_FOO is enabled in this environment");
}
will be represented in development and test environments as:
window.ENABLE_FOO = true;
if (ENABLE_FOO) {
this.route("foo");
console.log("The feature ENABLE_FOO is enabled in this environment");
}
In Handlebars/HTMLBars templates, you can also make use of the flags using the if-flag
block helper:
{{#if-flag ENABLE_FOO}}
<p>Foo is enabled! \o/</p>
{{else}}
<p>Foo is disabled</p>
{{/if-flag}}
You can also use the unless-flag
style block helper:
{{#unless-flag ENABLE_FOO}}
<p>Foo is disabled</p>
{{else}}
<p>Foo is enabled! \o/</p>
{{/unless-flag}}
We use UglifyJS's global_defs
feature to replace the value of feature flags with their constant values. UglifyJS's dead code implementation then cleans up unreachable code and performs inlining, such that:
if (ENABLE_FOO) {
this.route("foo");
console.log("The feature ENABLE_FOO is enabled in this environment");
}
will be represented in the production environment as the following if ENABLE_FOO
is configured to be true
:
this.route("foo");
console.log("The feature ENABLE_FOO is enabled in this environment");
or the following if ENABLE_FOO
is configured to be false
;
// empty since the condition can never be satisfied!
Furthermore, if you use the HTMLBars helpers the AST transformations will shake out and remove impossible-to-reach sides of the condition:
{{#if-flag ENABLE_FOO}}
<p>Foo is enabled</p>
{{else}}
<p>This won't be reached, because ENABLE_FOO is true</p>
{{/if-flag}}
will get transformed into:
<p>Foo is enabled</p>
This is really handy, since it vastly cuts down on the amount of precompiled template code that your users need to download even though it'll never be executed!
By defining ENV.featureFlagsEnvironment
you can separate your feature flags by more than just test/development/production, for example to have a beta environment that is identical to production but has a couple more flags activated. This only works if you have your flags in config.featureFlags
- The environment
passed in into the wrapper function will be ENV.featureFlagsEnvironment
if set.
This library is lovingly brought to you by the FreshBooks developers. We've released it under the MIT license.
2.0.0
The semantics of includeDirByFlag
have changed and now take a file glob pattern instead of a RegExp. This is because the mechanism for removing files from the build pipeline has changed to work around a bug in broccoli. (#111)
FAQs
Conditional compilation (feature-flags) for Ember apps
The npm package ember-cli-conditional-compile receives a total of 122 weekly downloads. As such, ember-cli-conditional-compile popularity was classified as not popular.
We found that ember-cli-conditional-compile demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.