Add webpack config for env specific builds

Add documentation and example files to make environment specific
build modifications.

- Store any env specific router and store modules in
  separate env directory

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I06ff3cb0928707354266dd25b399710847e7fa18
diff --git a/.env.openpower b/.env.openpower
new file mode 100644
index 0000000..26c1c98
--- /dev/null
+++ b/.env.openpower
@@ -0,0 +1,2 @@
+NODE_ENV=production
+VUE_APP_ENV_NAME=openpower
\ No newline at end of file
diff --git a/src/env/env.md b/src/env/env.md
new file mode 100644
index 0000000..d1944c5
--- /dev/null
+++ b/src/env/env.md
@@ -0,0 +1,163 @@
+# Configuring environment specific builds
+
+This document provides instructions for how to add environment specific modifications to the Web UI.
+
+- [Setup](##setup)
+- [Store](##store)
+- [Router](##router)
+- [Conditional template rendering](##conditional-template-rendering)
+- [Local development](##local-development)
+- [Production build](##production-build)
+
+## Setup
+
+1. Create a `.env.<ENV_NAME>` file in the project root
+2. Add `NODE_ENV=production` key value pair in the file
+3. Add `VUE_APP_ENV_NAME` key with the value set to the new environment name
+
+Example `.env.openpower`:
+
+```
+NODE_ENV=production
+VUE_APP_ENV_NAME=openpower
+```
+
+## Store
+
+>[Vuex store modules](https://vuex.vuejs.org/guide/modules.html) contain the application's API calls.
+
+1. Create a `<ENV_NAME>.js` file in `src/env/store`
+    >The filename needs to match the `VUE_APP_ENV_NAME` value defined in the .env file. The store import in `src/main.js` will resolve to this new file.
+2. Import the base store
+3. Import environment specific store modules
+4. Use the [Vuex](https://vuex.vuejs.org/api/#registermodule) `registerModule` and `unregisterModule` instance methods to add/remove store modules
+5. Add default export
+
+Example `src/env/store/openpower.js`:
+
+```
+import store from '@/store; //@ aliases to src directory
+import HmcStore from './Hmc/HmcStore';
+
+store.registerModule('hmc', HmcStore);
+
+export default store;
+```
+
+## Router
+
+>[Vue Router](https://router.vuejs.org/guide/) determines which pages are accessible in the UI.
+
+1. Create a `<ENV_NAME>.js` file in `src/env/router`
+    >The filename needs to match the `VUE_APP_ENV_NAME` value defined in the .env file. The router import in `src/main.js` will resolve to this new file.
+2. Import the base router
+4. Use the [Vue Router](https://router.vuejs.org/api/#router-addroutes) `addRoutes` instance method to define new routes
+5. Add default export
+
+Example `src/env/router/openpower.js`:
+
+```
+import router from '@/router'; //@ aliases to src directory
+import AppLayout from '@/layouts/AppLayout';
+
+router.addRoutes([
+  {
+    path: '/',
+    component: AppLayout,
+    children: [
+      {
+        path: '/access-control/hmc',
+        component: () => import('../views/Hmc'),
+        meta: {
+          title: 'appPageTitle.hmc'
+        }
+      }
+    ]
+  }
+]);
+
+export default router;
+```
+
+## Conditional template rendering
+
+For features that show or hide chunks of code in the template/markup, use the src/`envConstants.js` file, to determine which features are enabled/disabled depending on the `VUE_APP_ENV_NAME` value.
+
+>Avoid complex v-if/v-else logic in the templates. If a template is being **heavily** modified, consider creating a separate View and [updating the router definition](##router).
+
+1. Add the environment specific feature name and value in the `envConstants.js` file
+2. Import the ENV_CONSTANTS object in the component needing conditional rendering
+3. Use v-if/else as needed in the component template
+
+Example for adding conditional navigation item to AppNavigation.vue component:
+
+`src/envConstants.js`
+
+```
+const envName = process.env.VUE_APP_ENV_NAME;
+
+export const ENV_CONSTANTS = {
+  name: envName || 'openbmc',
+  hmcEnabled: envName === 'openpower' ? true : false
+};
+
+```
+
+`src/components/AppNavigation/AppNavigation.vue`
+
+
+```
+<template>
+
+...
+
+  <b-nav-item
+    to="/access-control/hmc"
+    v-if="hmcEnabled">
+    HMC
+  </b-nav-item>
+
+...
+
+</template>
+
+<script>
+import { ENV_CONSTANTS } from '@/envConstants.js';
+
+export default {
+  data() {
+    return {
+      hmcEnabled: ENV_CONSTANTS.hmcEnabled
+    }
+  }
+}
+
+</script>
+
+```
+
+## Local development
+
+1. Add the same `VUE_APP_ENV_NAME` key value pair to your `env.development.local` file.
+2. Use serve script
+    ```
+    npm run serve
+    ```
+
+## Production build
+
+Run npm build script with vue-cli `--mode` [option flag](https://cli.vuejs.org/guide/mode-and-env.html#modes). This requires [corresponding .env file to exist](##setup).
+
+
+```
+npm run build -- --mode openpower
+```
+
+
+**OR**
+
+pass env variable directly to script
+
+```
+VUE_APP_ENV_NAME=openpower npm run build
+```
\ No newline at end of file
diff --git a/src/env/router/openpower.js b/src/env/router/openpower.js
new file mode 100644
index 0000000..dccb2de
--- /dev/null
+++ b/src/env/router/openpower.js
@@ -0,0 +1,6 @@
+import router from '@/router';
+
+// Use router.addRoutes() to add layer specific routes
+// https://router.vuejs.org/api/#router-addroutes
+
+export default router;
diff --git a/src/env/store/openpower.js b/src/env/store/openpower.js
new file mode 100644
index 0000000..70c9b98
--- /dev/null
+++ b/src/env/store/openpower.js
@@ -0,0 +1,7 @@
+import store from '@/store';
+
+// Use store.registerModule() to register env specific
+// store modules
+// https://vuex.vuejs.org/api/#registermodule
+
+export default store;
diff --git a/src/envConstants.js b/src/envConstants.js
new file mode 100644
index 0000000..f9a4c3c
--- /dev/null
+++ b/src/envConstants.js
@@ -0,0 +1,5 @@
+const envName = process.env.VUE_APP_ENV_NAME;
+
+export const ENV_CONSTANTS = {
+  name: envName || 'openbmc'
+};
diff --git a/vue.config.js b/vue.config.js
index 12a723d..882944f 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -26,6 +26,8 @@
   },
   productionSourceMap: false,
   configureWebpack: config => {
+    const envName = process.env.VUE_APP_ENV_NAME;
+
     if (process.env.NODE_ENV === 'production') {
       config.plugins.push(
         new CompressionPlugin({
@@ -33,6 +35,12 @@
         })
       );
     }
+    if (envName !== undefined) {
+      // Resolve store and router modules in src/main.js
+      // depending on environment (VUE_APP_ENV_NAME) variable
+      config.resolve.alias['./store$'] = `./env/store/${envName}.js`;
+      config.resolve.alias['./router$'] = `./env/router/${envName}.js`;
+    }
   },
   chainWebpack: config => {
     if (process.env.NODE_ENV === 'production') {