Skip to content

lovetingyuan/vue-flags-webpack-plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vue-flags-webpack-plugin

Remove useless code by setting flags(toggles) in .vue SFC file

npm version Build Status JavaScript Style Guide

⚙ Usage

install:

npm install vue-flags-webpack-plugin -D

options:

  • flags ({[k: string]: boolean} | string, required)

    A plain object that contains flags value(boolean).

    Or a file path(will be executed many times!) which exports the final flags object.

    flags: {
      FLAG_A: true,
      FLAG_B: false,
    }
    // or
    flags: './config/allFlags.js'
  • namespace (string, required)

    used as namespace of flags in JavaScript, must be a valid variable name.

  • watch (boolean | string[], default: false)

    Support to modify flags and reload your app when this option is set.

    Set this option ONLY in development mode.

    If watch is true, option flags must be a file path.

    watch could also be an array including extra files paths which will be watched.

    watch: process.env.NODE_ENV === 'development'
    // or (no need to add extra files in most cases, just set it true)
    watch: [ './config/flag1.js', './config/flag2.js' ]
  • ignoreFiles ({[k: string]: RegExp | RegExp[]})

    A plain object that uses flag name or expression as key and regexp as value.

    Modules(absolute path) matched by the regexps will be ignored when the value of flags is false.

    ignoreFiles: {
      // if FLAG_A is false, a.js will be ignored,
      'FLAG_A': [/a\.js$/],
      // if FLAG_A is false or FLAG_B is true, a-b.js will be ignored
      'FLAG_A && !FLAG_B': [/a-not-b\.js$/],
    }

🌰 Example

flags file: ./allFlags.js

module.exports = {
  FLAG_A: true,
  FLAG_B: false,
}

webpack config:

const VueFlagsPlugin = require('vue-flags-webpack-plugin');
const postcssFlagsPlugin = VueFlagsPlugin.postcssFlagsPlugin;
module.exports = {
  module: {
    rules: [{
      test: /\.css$/,
      loader: 'postcss-loader',
      options: {
        plugins: [
          postcssFlagsPlugin()
        ]
      }
    }]
  },
  plugins: [
    new VueFlagsPlugin({
      flags: './allFlags.js',
      namespace: 'FLAGS',
      watch: process.env.NODE_ENV === 'development',
      ignoreFiles: {
        FLAG_B: [/b-related-module\.js$/]
      }
    })
  ]
};

vue component:

<template>
  <div>
    <p v-if-flag="FLAG_A">feature a will be enabled</p>
    <p v-elif-flag="FLAG_B">{{msg}}</p>
    <p v-else-flag>both feature a and b will be disabled</p>
  </div>
  <!-- will be transformed as
  <div>
    <p>feature a will be enabled</p>
  </div>
   -->
</template>

<script>
  import moduleB from './b-related-module';
  export default {
    data() {
      return {
        // "FLAGS" as namespace
        msg: FLAGS.FLAG_B ? 'feature b content' : '...';
      }
    },
    mounted() {
      // if FLAG_B is false, moduleB is undefined
      if (moduleB) { moduleB() }
    }
  }
</script>

<!-- could also use sc(a)ss, less, stylus, etc. -->
<style>
  p { color: yellow; }
  @supports (--flag: FLAG_A) {
    p { font-size: 2em; }
  }
  @supports not ((--flag: FLAG_A) or (--flag: FLAG_B)) {
    p { display: none; }
  }
  /**
    You must use "--flag" as custom property name
    see @supports: https://developer.mozilla.org/en-US/docs/Web/CSS/@supports
    above will be transformed as:
    p { color: yellow; }
    p { font-size: 2em; }
  */
</style>

⚠️ Caveats

  • requires vue-loader >= 15, webpack >= 4, vue-template-compiler >= 2.5.0

  • v-*-flag can not be used with vue condition directive(v-if,v-else-if,v-else).

    💡use <template v-*-flag> to wrap the condition block.

  • v-*-flag can not be used with v-pre directive or under it.

  • v-*-flag should not be used with slot-scope or v-slot.

  • The plugin will execute flag expression, make sure the flag value is safe.

License

MIT