1. 程式人生 > 實用技巧 >webpack生產環境保留某些console.log

webpack生產環境保留某些console.log

生產環境中部署js程式碼一般會去掉console.log(),一來大量console.log會影響效能,二來有可能引起安全問題。我們一般在webpack.prod.conf.js檔案配置:

new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: true,
          drop_debugger: true,
          drop_console: true
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: os.cpus().length - 1
}),

通過以上配置,我們的程式碼上生產環境後確實不會再控制檯列印任何東西了。但是,如果我們想保留一些確定的列印呢,類似於百度:

在網上查得方法如下:

Node環境下:

global.console.log("UglifyJs won't remove me")

Browser環境下:

window.console.log("UglifyJs won't remove me")

console.log清除原理淺析

// node_modules/uglify-js/lib/compress.js

// 傳 drop_console: true
if (compressor.option("drop_console")) {
            if (exp instanceof AST_PropAccess) {
                var name = exp.expression;
                while (name.expression) {
                    name = name.expression;
                }
                // 通過Babel生成AST語法樹判斷節點是否為 console
                if (is_undeclared_ref(name) && name.name == "console") { // 沒有對 X.console 這種AST節點進行判斷,所以我們可以 window.console.log(1) 這麼來列印內容
                    return make_node(AST_Undefined, self).optimize(compressor); // 用 AST_Undefined 節點替換當前 console節點(AST節點), AST_Undefined 定義在 node_modules/uglify-js/lib/ast.js 檔案中
                }
            }
}

...
// 生成AST節點
function make_node(ctor, orig, props) {
        if (!props) props = {};
        if (orig) {
            // 將原始console節點(AST節點)start end值賦值給一個空物件(props)     
            if (!props.start) props.start = orig.start;
            if (!props.end) props.end = orig.end;
        }
        return new ctor(props);
 }

總結

明白了uglify-jsconsole.log的處理方法後,我們想要保留console.log就很簡單了,只要不是這麼呼叫console.log(xxx)就行,寫法其實有很多,原理都是用變數保留對console.log的引用

window.log = console.log
log('hahaha')
const {log} = console
log('wawawa')

參考

Webpack Uglify: Keep Certain console.logs