【问题标题】:Remove some code lines in production distribution files?删除生产分发文件中的一些代码行?
【发布时间】:2017-08-19 21:03:54
【问题描述】:

我正在使用BabelWebpackES6 生成ES5 代码。有一些验证可以用来减少我在编码时犯的错误。

class Logger {
    /**
     * @param {LogModel} info
     *  {LogTypes} type
     *  {String} message
     *  {Date} date
     */
    static log(info) {
        if(info instanceof LogModel)
            throw new Error("not a instance of LogModel");

        notify(info);
    }
}

log 函数中,我验证参数是否是LogModel 类的实例。这只是为了防止错误。我不希望 if 条件出现在生产中,因为太多的 if 条件会减慢应用程序的速度。是否可以生成带有验证的开发版本和不带有 BabelWebpack 的验证的生产版本?

【问题讨论】:

    标签: javascript webpack babeljs


    【解决方案1】:

    其他答案似乎已过时。使用 webpack 4,您可以在 webpack 配置中设置 mode: 'production'

    在您的代码中,像这样检查开发模式:

    if (process.env.NODE_ENV === 'development') {
        if(info instanceof LogModel)
            throw new Error("not a instance of LogModel");
    }
    

    当 webpack 使用 mode: 'production' 创建一个包时,这些 if 子句中的所有代码以及 if 子句本身都会自动从包中删除。

    无需显式使用define插件(webpack“在后台”使用它),也没有必要使用其他答案中提到的webpack-unassert-loaderwebpack-strip-block之类的东西。

    查看我制作的这个小演示 repo:https://github.com/pahund/webpack-devprod-experiment

    【讨论】:

    • webpack 不会从编译后的代码中移除 if 块
    • 我的错。由于某种原因,webpack 不会覆盖 env.NODE_ENV。
    • 如果您不想剥离该块中的所有代码怎么办。 webpack-strip-block 似乎给了你更多的控制权。
    • @Tamb 该块中的所有代码被webpack剥离
    • 我相信 webpack 在后台使用 ConstPluginif…statements 解析为简单的 true/false。您可以使用 DefinePlugin 这是内部 webpack 插件来实现此行为。该页面还包含一个非常简单的使用示例。
    【解决方案2】:

    更简洁的选择是使用 webpack 中的 define-plugin

    在配置文件中:

    new webpack.DefinePlugin({ __DEV: JSON.stringify(true) })

    app.js:

    if(__DEV){ console.log("logged only in dev env") }

    __DEV 的值将由 webpack 在编译时提供。

    【讨论】:

    • __DEV 在您的示例中似乎总是如此。不应该是JSON.stringify(process.env.NODE_ENV === 'development')吗?
    【解决方案3】:

    webpack-strip-block 是一个很好的解决方案。它会在编译时删除生产代码中的一段代码。

    /* develblock:start */
    /* develblock:end */
    

    不限于asserts 并且产品中没有冗余代码。

    【讨论】:

    • 对于 webpack 4,这不是必需的,它通过 mode config 和 process.env.NODE_ENV 内置支持
    • 即使使用mode = production,webpack 也不会删除开发代码
    【解决方案4】:

    您可以使用assert 包来强制执行您的代码,然后使用webpack-unassert-loaderwebpack-strip-assert 剥离您的断言以用于生产代码。

    var assert = require('assert').ok;
    
    class Logger {
        /**
         * @param {LogModel} info
         *  {LogTypes} type
         *  {String} message
         *  {Date} date
         */
        static log(info) {
            assert(info instanceof LogModel, "Param must be an instance of LogModel");
            notify(info);
        }
    }
    

    【讨论】:

    • 我采用这种方法是因为我希望在生产环境中从源代码中完全剥离断言。但是 webpack-strip-assert 使用 Webpack 4 时出错。我使用 string-replace-webpack-plugin 和替换模式 /\n[ \t]*assert\([^\);]+[\)\s]+[ \t]*[;\n]/g 代替。
    【解决方案5】:

    我创建了一个sample project 来评估此线程中解释的所有不同方法。我最喜欢使用string-replace-webpack-plugin

    【讨论】:

    【解决方案6】:

    这里有一些不错的选择,但我认为我们可以做得更好。如果您尝试完全删除 Logger.log() 函数以及对它的调用,例如:

    Logger.log('Remove me');
    

    ...那么string-replace-loader可以做我们需要的!

    安装string-replace-loader:

    npm install --save-dev string-replace-loader
    

    然后,在你的 Webpack 配置中:

    ...
        module: {
            rules: [
                //Replace strings
                {
                    test: /\.js$/,
                    loader: 'string-replace-loader',
                    options: {
                        multiple: [
                            //Remove calls to Logger.log()
                            {
                                search: /Logger\.log\s*\(.*?\);?\s*?\n/g,
                                replace: ''
                            },
                            //Remove the actual Logger.log() function. This regex may need tweaking depending on your actual code for `log()`.
                            {
                                search: /static\s*log\s*\([^}]*}/gs,
                                replace: ''
                            }
                        ]
                    }
                }
            ]
        },
    ...
    

    无需在实际源代码中添加额外的无意义代码。享受吧!

    【讨论】:

    • 感谢this answer 为我指明了正确的方向(尽管插件已过时)。
    猜你喜欢
    • 2011-11-15
    • 2011-05-11
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    相关资源
    最近更新 更多