ember-cli-build-variants v1.0.4
ember-cli-build-variants
This is a little ember-cli plugin to add different build variants to the same codebase. For example you can build a free version and a premium version of your application using the same codebase.
Installation
Run (using npm)
ember install ember-cli-build-variantsUsage
The plugin is simple to use:
- Create a config file my-project/config/flavors.js(See example below).
- Start buildorservecommand by using the flavor flag:ember build --flavor FREEorember build --flavor PREMIUMIf you do not specify a flavor via command line (or your flavor does not exist in the config file) it will be started using no flavor, i.e.flavor.name === nullandflavor.data === {}
Example
Config file:
module.exports = {
  flavors: [
    {
      name: "FREE",
      // Use the data hash to provide your own flavor specific data.
      // The is completley up to you, how you design the data hash.
      // For future compatibility you should not use properties the level above.
      data: {
        title: "Free version",
        features: {
          description: true,
          image: false
        }
      }
    },
    {
      name: "PREMIUM",
      data: {
        title: "Paid version",
        features: {
          description: true,
          image: true
        }
      }
    }
  ]
};Benefits
Built-in helpers
You can access the name and data property of your active flavor in your templates by using the included helpers:
<h1> {{get (flavor-data) 'title'}} </h1>
<p>
  Using flavor: {{flavor-name}}
</p>
{{#if (get (flavor-data) 'features.description' )}}
  <p> Lorem ipsum dolor sit amet. </p>
{{/if}}
{{#if (get (flavor-data) 'features.image' )}}
  <img src="xyz.png" alt="something">
{{/if}}Output will then be:
- Using ember build --flavor FREE:
<h1> Free version </h1>
<p>
  Using flavor: FREE
</p>
<p> Lorem ipsum dolor sit amet. </p>- Using ember build --flavor PREMIUM:
<h1> Paid version </h1>
<p>
  Using flavor: PREMIUM
</p>
<p> Lorem ipsum dolor sit amet. </p>
<img src="xyz.png" alt="something">Config
You can access the active flavor hash via config. In some javascript file do the following (no matter if controller, route, component, service, helper, ...):
In a controller for example:
import Controller from '@ember/controller';
import config from '../config/environment';
export default Controller.extend({
  importantThing: function(){
    console.log(config.flavor);
    // will output:
    /* ember build --flavor FREE
    {
      name: "FREE",
      data: {
        title: "Free version",
        features: {
          description: true,
          image: false
        }
      }
    }
    */
    // or
    /* ember build --flavor PREMIUM
    {
      name: "PREMIUM",
      data: {
        title: "Paid version",
        features: {
          description: true,
          image: true
        }
      }
    */
    // Now you can do something like
    if( config.flavor.data.features.image ) {
      // Do something
    }
    // Or
    if( config.flavor.name === "PREMIUM")  {
      // Do something else
    }
  }.on('init')
});Flavor specific assets
You can go one step further and provide different assets/files for different flavors. The built project will then only contain the assets for the specific flavor.
You can do this for javascript, stylesheets, templates et cetera. It will process everything that is handled by broccolijs during the build.
For example the following situation in app/styles:
- app/styles/colors.css
- app/styles/colors.FREE.css
- app/styles/colors.PREMIUM.css
When you build the project using:
- ember build:- app/styles/colors.FREE.cssand- app/styles/colors.PREMIUM.csswill be discarded before build.
- ember build --flavor FREE:- app/styles/colors.cssand- app/styles/colors.PREMIUM.csswill be discarded from build.- app/styles/colors.FREE.csswill be used as replacement for- app/styles/colors.css.
- ember build --flavor PREMIUM:- app/styles/colors.cssand- app/styles/colors.FREE.csswill be discarded from build.- app/styles/colors.PREMIUM.csswill be used as replacement for- app/styles/colors.css.
The same is possible for controllers, routes et cetera. With this mechanic you can have completley different controllers for each build flavor and the other controller variant will be deleted and thus its code not included in the build output.
Caveats
- Flavor names: Have to be uppercase, containing only latin letters (A-Z), no special chars and at least 3 characters long to work properly.
- File names: Before build all files that contain a section that matches one of the following regex will be deleted from build /\.[A-Z]{3,}(\.[A-Za-z]*)?/.
Contribute
Feel free to open a pull request / issue if you find bugs or if you want to add more features.