关于javascript:Vue3-如何实现-Feature-Flags

38次阅读

共计 3783 个字符,预计需要花费 10 分钟才能阅读完成。

在开发组件库或者插件,常常会须要辨别多种环境构建,从而实现:

  • 提供各种 体积 版本:全量版、精简版、根底版等;
  • 提供各种 环境 版本:web 版、nodejs 版等等;
  • 提供各种 标准 版本:esm 标准版本、cjs 标准版本、UMD 标准版本等等。

那么如何可能不便实现下面性能呢?这种场景就适宜应用 Feature Flags,在构建过程中,通过开关的启用和敞开,对构建代码的过程进行动静设置,从而更好的实现 Tree Shaking。

Tree Shaking 是一种通过打消最终文件中未应用的代码来优化体积的办法。

本文会从 Vue 源码 (版本号:3.0.11) 中应用的 Feature Flags 进行构建的过程开始介绍,而后通过简略示例进行学习,最初介绍 rollup、webpack 和 Vite 中的实现。

一、什么是 Feature Flags

Feature Flag(又名 Feature Toggle、Flip 等)是一种容许控制线上性能开启或者敞开的形式,通常会采取配置文件的形式来管制。

​http://fex.baidu.com/blog/201…

能够了解为在代码中增加一个开关,当开关开启,则逻辑会执行上来,否则不会执行,通常代码表现形式为 if语句,举个简略示例:

const flags = true;
const test = () => flags && console.log('Hello Feature Flags');

flagstrue则执行输入,否则不会。
当初咱们想管制日志会不会输入,只需扭转 flags的值即可,test办法逻辑不必批改。

😺 能够将 Feature Flag 翻译成 个性标记。

二、Vue 源码实现 Feature Flags

2.1 应用示例

从上一节对个性标记的介绍后,大家应该对其有点了解,接下来从 Vue3 源码中看一个应用示例:

// packages/compiler-core/src/errors.ts
export function defaultOnWarn(msg: CompilerError) {__DEV__ && console.warn(`[Vue warn] ${msg.message}`)
}

这里的 __DEV__就是一个 Feature Flag,当 __DEV__值为 true时,会输入前面的日志,否则不会输入。
在 Vue3 源码中还存在很多其余个性标记,比方:

  • __COMMIT__
  • __TEST__
  • __GLOBAL__

还有很多,有趣味的小伙伴能够在 Vue3 源码中找找。

2.2 如何定义个性标记

下面只是带大家看了下源码中如何应用,那么接下来看看 __DEV__ 这些个性标记是如何定义的。
Vue3 中应用了 @rollup/replace 依赖,实现构建时,替换文件中指标字符串内容,比方构建开发环境的包的过程中,将 __DEV__替换为 true
还是以下面示例代码为例介绍:

// 本地开发环境 __DEV__ 为 true,通过 @rollup/replace 依赖打包后如下:export function defaultOnWarn(msg: CompilerError) {true && console.warn(`[Vue warn] ${msg.message}`)
}

// 生成环境中 __DEV__ 为 false,通过 @rollup/replace 依赖打包后如下:export function defaultOnWarn(msg: CompilerError) {}

构建后 defaultOnWarn办法内的 console.warn语句就被 Tree Shaking 移除掉了。

三、上手 Feature Flags

这一节通过将别离应用 rollup、webpack 和 Vite 实现三个 Feature Flags 的 Demo。其外围原理就是在构建阶段的时候,曾经明确的 Feature Flags 值的内容会被替换成具体的值,而后进行 Tree Shaking。

三个示例的全副代码能够到上面仓库查看:

首先咱们先创立一个 index.js文件,输出上面测试内容:

// index.js 

const name = 'pingan8787';
const age = 18;

const featureFlags = () => {console.warn(name)
    __DEV__ && console.log(name)
}

featureFlags();

咱们须要实现的指标是:当 __DEV__变量的值为 true 时,打包后的 index.js 将不蕴含 __DEV__ && console.log(name)这一行代码。
那么开始看看如何实现:

3.1 rollup 实现

在 rollup 中,须要应用 @rollup/replace 包实现构建时替换文本,咱们先装置它:

npm install @rollup/plugin-replace --save-dev

而后在 rollup.config.js中应用:

import replace from '@rollup/plugin-replace';

export default {
    input: 'index.js',
    output: {
        file: './dist/index.js',
        format: 'cjs'
    },
    plugins: [
        replace({__DEV__: true})
    ]
};

接下来通过 rollup打包命令,能够看到输入内容如下:

const name = 'pingan8787';
const age = 18;

const featureFlags = () => {console.warn(name)
    __DEV__ && console.log(name)
}

featureFlags();

能够看到 __DEV__true时代码并没有 Tree Shaking,再试试改成 false,输入如下:

'use strict';

const name = 'pingan8787';

const featureFlags = () => {console.warn(name);
};

featureFlags();

这边 __DEV__ && console.log(name)就被移除了,实现 Tree Shaking。
照着雷同原理,再看看 webpack 和 Vite 的实现:

3.2 webpack 实现

webpack 中自带了 DefinePlugin能够实现该性能,具体能够看 DefinePlugin 文档,上面看看 webpack.config.js配置:

// webpack.config.js

const path = require('path')
const webpack = require('webpack')

module.exports = {
    entry: './index.js',
    output: {path: path.resolve(__dirname, 'dist'),
        filename: 'index.js',
    },
    mode: 'production',
    plugins: [
        new webpack.DefinePlugin({__DEV__: JSON.stringify(true),
        })
    ],
};

因为这是应用 mode: 'production'模式,所以打包进去的代码会压缩:

(()=>{const n="pingan8787";console.warn(n),console.log(n)})();

能够看出 __DEV__曾经不存在,但 console.log(n)还存在,这时候把 __DEV__改成 false再看看打包后果:

console.warn("pingan8787");

只剩下这句,其余都被 Tree Shaking 掉了。

3.3 Vite 实现

Vite 默认也是反对自定义全局变量,实现该性能,能够看文档 define option。
通过 pnpm create vite创立一个简略 Vite 我的项目,并删除多余内容,并在 main.js中退出咱们的测试代码:

import {createApp} from 'vue'
import App from './App.vue'

const name = 'pingan8787';
const age = 18;

const featureFlags = () => {console.warn(name)
    __DEV__ && console.log(name)
}

featureFlags();

createApp(App).mount('#app')

并且在 vite.config.js中设置 __DEV__

// vite.config.js

export default defineConfig({plugins: [vue()],
  define: {__DEV__: true}
})

而后执行 pnpm build构建我的项目,能够看到压缩后的代码还存在 __DEV__ && console.log(name)

接下来批改 __DEV__的值为 false,再从新打包,能够看到代码曾经被 Tree Shaking 了:

到这里咱们就应用 rollup、webpack 和 Vite 别离实现了一遍 Feature Flags 了。

四、总结

本文通过简略例子和 Vue3 源码,与大家介绍了 Feature Flags 的概念和简略的实现,最初别离应用 rollup、webpack 和 Vite 别离实现了一遍 Feature Flags。

在理论业务开发中,咱们能够通过设计各种 Feature Flags,让代码可能更好的进行 Tree Shaking。

参考文章

  1. Feature Flag 性能公布管制

正文完
 0