javascript下条件编译的实现(基于webpack的js-conditional-compile-loader插件)

条件编译,是指 用同一套代码和一样的编译构建过程,根据设置的条件,选择性地编译指定的代码,从而输出不一样程序的过程。通常用在C++、Java、C#这样的编译执行语言。对于javascript,咱们也可使用基于webpackjs-conditional-compile-loader插件实现相似的条件编译功能。javascript

应用场景举例

咱们常常会遇到相似这样的需求:前端

  • 代码须要根据运行环境,运行不一样的代码。好比,测试环境能够控制台输出一些信息,生产环境则不提示;同时又不但愿输出的代码中存在判断环境的if-else代码使程序包体积增大。
  • 项目交付给多个客户使用,而某些客户会有一些定制模块。这些定制模块只给特定用户使用,不但愿也一块儿打包在不相干客户的程序包中,但也不但愿给定制客户单独维护一个特殊项目而增长维护成本。
  • 前端为了调试,引用了不少mock数据。可是生产环境打包时也包含了这些mock数据和mock插件,增大了代码包体积。但愿生产环境程序包彻底不含这些(即便是异步按需加载也不要)。

使用条件编译的方法,能够优雅地解决这样的问题,同时代码维护方便,发布的程序包中也不会有多余的代码存在。vue

插件原理

js-conditional-compile-loader插件是一个webpack的loader插件,它会在webpack处理js代码以前,将js代码根据设置的条件进行修改,去掉当前条件下不须要的代码,保留须要的代码,从而实现条件编译的功能。java

使用步骤

可参考这里的中文文档webpack

1. 安装

npm i -D js-conditional-compile-loader

2. 配置webpack

在rules中为js文件添加loader,做为第一步处理js文件,并配置编译条件。git

module: {
    rules: [
        {
            test: /\.js$/,
            include: [resolve('src'), resolve('test')],
            use: [
                //step-2
                'babel-loader?cacheDirectory',
                //step-1
                {
                    loader: 'js-conditional-compile-loader',
                    options: {
                        isDebug: process.env.NODE_ENV === 'development', // optional, this is default
                        myFlag: process.env.npm_config_ali, // any name, used for /* IFTRUE_myFlag ...js code... FITRUE_myFlag */
                    }
                },
            ]
        },
        //other rules
    ]
}

3. 项目代码中使用

插件支持IFDEBUG和IFTRUE两个条件编译指令。用法是:在js代码的任意地方以/*IFDEBUG/*IFTRUE_xxx开头,以FIDEBUG*/FITRUE_xxx*/结尾,中间是被包裹的js代码。xxx是在webpack中指定的条件属性名,如上面的myFlag。github

举个例子,web

源码:

咱们用这样的源代码:npm

/* IFTRUE_forAlibaba */
var aliCode = require('./ali/alibaba-business.js')
aliCode.doSomething()
/* FITRUE_forAlibaba */

$state.go('win', {dir: menu.winId /*IFDEBUG , reload: true FIDEBUG*/})

条件1输出

当webpack中插件的options配置为{isDebug: true, forAlibaba: true}时,构建后输出的内容:element-ui

var aliCode = require('./ali/alibaba-business.js')
aliCode.doSomething()

$state.go('win', {dir: menu.winId, reload: true })

条件2输出

当webpack中插件的options配置为{isDebug: false, forAlibaba: false}时,构建后输出的内容为:

$state.go('win', {dir: menu.winId})

如此便实现了条件编译。结合命令参数关联到环境变量,能够用命令参数指定不一样的编译条件。例如本文中的配置条件:myFlag: process.env.npm_config_ali,执行命令时带上--ali便可激活为truenpm run build --ali
实际项目中能够按照你的须要尽情发挥。

示例项目

这里是个完整项目的例子,可供参考。

相关文章
相关标签/搜索