什么是Feature Flags
Feature Flags是一种允许控制线上功能开启或者关闭的方式,通常会采取配置文件的方式来控制。
例如,在开发组件库或者插件,经常会需要区分多种环境构建,从而实现:
- 提供各种「体积」版本:全量版、精简版、基础版等;
- 提供各种「环境」版本:web 版、nodejs 版等等;
- 提供各种「规范」版本:esm 规范版本、cjs 规范版本、UMD 规范版本等等。
这种时候就可以使用feature flags
Vue 源码实现 Feature Flags
源码例子
// packages/compiler-core/src/errors.tsexport function defaultOnWarn(msg: CompilerError) {__DEV__ && console.warn(`[Vue warn] ${msg.message}`)}
DEV就是一个Feature Flags
在 Vue3 源码中还存在很多其他特性标志,比如:
- COMMIT
- TEST
- GLOBAL
- …
Vue3如何定义Feature Flags
Vue3 中使用了 @rollup/replace 依赖,实现构建时,替换文件中目标字符串内容,比如构建开发环境的包的过程中,将 DEV替换为 true。 还是以上面示例代码为例介绍:``javascript // 本地开发环境 __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 移除掉了。<a name="rgjyV"></a>## 上手Feature Flags<a name="krL9H"></a>### rollup实现```javascriptnpm install @rollup/plugin-replace --save-dev
import replace from '@rollup/plugin-replace';export default {input: 'index.js',output: {file: './dist/index.js',format: 'cjs'},plugins: [replace({__DEV__: true // 构建时将__DEV__替换成true})]};
webpack实现
webpack 中自带了 DefinePlugin可以实现该功能,具体可以看 DefinePlugin 文档,下面看看 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),})],};
vite实现
Vite 默认也是支持自定义全局变量,实现该功能,可以看文档 define option。
/*** Define global variable replacements. 定义全局变量替换* Entries will be defined on `window` during dev and replaced during build.*/define?: Record<string, any>
export default defineConfig({plugins: [vue()],define: {__DEV__: true}})
总结三者使用
- webpack: 使用 DefinePlugin
- Rollup: 使用 @rollup/plugin-replace
- Vite:默认配置,但可以使用define选项覆盖。
参考:
Vue3 如何实现瘦身?
