7

Hi this question is most likely just a cordova question. I've seen simular questions but never with a satisfactory answer.

What my end goal would be, is a simple way to build multiple Flavors of both an Android, iOS and Windows Phone app.

What my biggest requirements are:

  • Change the namespace. So the widget attributes in config.xml would preferably be overwritten. Also the name and description would help.
  • Generating different icons and splash screens. I'd likely set up directories relevant to the package name I'm using. Putting a high res Splash and Icon in here, using ionic's resources command to generate the correct files.
  • Color scheme changes based on target
  • Optionally, dynamic configuration.

What I've currently done is added some code in my webpack.config (my ionic project uses webpack). To change sass colours, I could easily add some other options here as well.

This is probably the worst way to implement it but I just needed a working prototype

var flavour = "some.namespace.dir";
var ENV = "TEST";

for(var i = 0; i < args.length ; i++) {
    if (args[i] == "--env") {
        if (args[i+1]) {
            ENV = args[i+1];
        }
    }

    if (args[i] == "--flavour") {
        if (args[i+1]) {
            flavour = args[i+1];
        }
    }
}

So this would check if the node command had any --flavour or --env flag to set these properties. after this I'll load the config in a dumb way.

var config =
    JSON.parse(
        require('fs').readFileSync(
            require('path').resolve(
                __dirname,
                'flavours/' + flavour + ".json"),
            'utf8'));

Allright so I have a json object, I can put nearly anything in here, so for doing custom styling we can use the sass loader.

sassLoader: {
    includePaths: [
        'node_modules/ionic-angular',
        'node_modules/ionicons/dist/scss'
    ],
    data: "$custom-primary: " + config.colorPrimary + " ; $custom-accent: " + config.colorAccent + " ;"
},

So this actually lets me add variables to the sass build, great! as for the configuration:

new DefinePlugin({
   'ENV': JSON.stringify(ENV),
   'appConfig': JSON.stringify(config)
})

So I've got these things which I can use to have the logic inside the app be specific to a flavour.

I'd love to hear how dissapointed people are in my implementation and if they have suggestions to improve any of this.

Also as of now I'm thinking I will need a bash script to change my config.xml and the resources. I can either have a template file in which I replace the namespaces, or I just create config.xml files in my "flavour" folders and copy these in place.

Any suggestions or wtf's people can share? As for now I'll probably go with the config in each directory approach, together with the resources. That way I could just hit a bash file to build compile and sign for any flavour.

Mathijs Segers
  • 6,168
  • 9
  • 51
  • 75
  • I m not sure whether i understood your question correctly but basically what i m guessing is that you are looking customizing your config.xml before building the various flavours of the app. I would suggest hooks will be the way to go for this. I suggest you to look at this link - http://stackoverflow.com/questions/37816035/using-environment-variables-parameterizing-config-xml where we discussed customizing config.xml before build in details. Let me know whether it helps. – Gandhi Aug 02 '16 at 14:34
  • Heya Gandhi, I checked out your github project. But like commented it seems like you're just implementing a simular solution which is also a windows only solution by using a bat. Of course this could be done by providing both a bat and a sh file. I myself right now have .bat files for compilation time, which for the android project also sign a released version etc. And uses perl replace to change appId etc. So what I could do of course, it use your approach to make a hook, but how do I provide params then? Read them in the hook? – Mathijs Segers Aug 03 '16 at 06:47
  • Params can be temporarily set in environment variables just before executing the hooks as mentioned in my project's readme file. – Gandhi Aug 03 '16 at 06:56
  • For the package name, check out my answer here: http://stackoverflow.com/a/41886578/517193 – Guillaume Jan 27 '17 at 03:35

1 Answers1

0

To read out the app id from config.xml you can use this snippet of JS code.

const fs = require('fs').promises;
const xml2js = require('xml2js');

async function getAppId() {
    const data = await fs.readFile('config.xml') ;
    const parser = new xml2js.Parser();
    const result = await parser.parseStringPromise(data);
    const appId = result.widget['$'].id;
    return appId
}
L--
  • 286
  • 5
  • 7