Ionic 3 > custom watch script for "ionic_watch" live reload

This will be quite a long winded question so please bare with me as I try and explain everything. Our company works on white labelling one of our products, this has extended to not just basic css and styling changes but even logic change requests at times.

Our platform started off in Ionic 1/AngularJS. Here to build our white label solution we implemented grunt and logic based around “folder replacing”. We had a ‘base’ folder with folder/file paths, and each white label had their own folder with the exact folder/file paths to rebuilt those in base that were the same.

A few months ago we migrated to Ionic 3. A previous colleague already implemented bash and with that I have managed to create the same ‘folder/file’ replacing logic. All works if I just build or ionic serve the application. HOWEVER, this is where I need help with now, I need to set up a customised watcher so that when I edit any files the script runs again. Please see below for some details:


My script gets the files and folders from the code/base folder and copies them to the app root and then does the same for the code/themes/$theme folder, replacing any files which are already there with what is needed in the theme:

#!/usr/bin/env bash

PS3='Please select your configuration by typing the corresponding number: '
themes=("demo" "production" "quit")
platformOptions=("ios" "android" "quit")

select theme in "${themes[@]}"
    case $theme in
            echo ">>>>> building the files and folders for your theme <<<<<"
            rsync -avh code/base/*  ./
            rsync -avh code/themes/$theme/*  ./
            rm -rf www/$theme/*
            ionic-app-scripts build --wwwDir www/$theme --buildDir www/$theme/build       # change the www build directory to include brand path
            # TODO: how to set up watch on any file changes in code/base* or code/theme/$theme/* ?
            echo "Invalid option $REPLY"

My package.json references the scripts and within “config” I now want to create a customised watch.config.js logic to reflect the changes I’ve made regarding my folder structure:

  "name": "muulla-app",
  "version": "3.3.7",
  "private": true,
  "description": "Muulla App",
  "scripts": {
    "theme-serve": "./bin/",
    "start": "ionic-app-scripts serve",
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint"
  "config": {
    "ionic_watch": "./config/watch.config.js"

At the moment this is my config/watch.config.js file which is being read correctly, but I am having trouble understanding or implementing the logic I require:

var watch = require('@ionic/app-scripts/dist/watch.js');
var copy = require('@ionic/app-scripts/dist/copy.js');
var copyConfig = require('@ionic/app-scripts/dist/copy.config.js');

// this is a custom dictionary to make it easy to extend/override
// provide a name for an entry, it can be anything such as 'srcFiles' or 'copyConfig'
// then provide an object with the paths, options, and callback fields populated per the Chokidar docs

module.exports = {
  srcFiles: {
    paths: ['{{SRC}}/**/*.(ts|html|s(c|a)ss)', '../code/base/src/**/*.(ts|html|s(c|a)ss)', '../code/themes/demo/src/**/*.(ts|html|s(c|a)ss)'],
    options: { ignored: ['{{SRC}}/**/*.spec.ts', '{{SRC}}/**/*.e2e.ts', '**/*.DS_Store', '{{SRC}}/index.html'] },
    callback: watch.buildUpdate
  copyConfig: copy.copyConfigToWatchConfig()

// TODO: find a way to dynamically inject the $theme, currently hard coded 'demo'

Basically on a high level I want to:

  • watch any changes made in the code/base folders
  • watch any changes made in the code/themes/$theme folders
  • if there has been any changes made to the above, the script logic needs to be applied again where it copies over the files from the base, then copies over the files from the themes/$theme and builds again (I am unsure if the entire script needs to run, or if there is a way to single out only replacing the edited file?)

Please ask me any questions for clarification. I’ve been struggling with this for a while and have no one else in the company to help me with this. Any advice, feedback, tips or tricks would be greatly appreciated!