程序在開發的過程當中,少不了打印調試用的日誌,測試流程時僞造的數據。這些代碼是不能出如今生產環境上的。
這意味着在程序打包前,須要把相關代碼剔除掉。
這些事情用人手去作很麻煩,很容易疏漏。並且打包出來測試時遇到了bug,又得從新把測試代碼添加回去。重複整個繁瑣的過程。
vue
既然人工作這麼麻煩並且容易出錯,那能不能用程序幫咱們完成這些事情呢?
固然能夠,用選擇性編譯技術就行,本文就介紹在webpack下解決這一問題的方法。
其實這個方法在webpack官網就有提到,本文只是提供相關示例及作一些延伸。webpack
選擇性編譯是指根據打包是環境的不一樣,選擇性地讓特定的語句有效,讓特定的語句無效。
最簡單的例子,在開發環境中,咱們打印日誌,但在生產環境中,咱們讓全部打印日誌的語句無效(讓程序不運行打印的語句,甚至讓打包出來的文件根本就不包含打印日誌的語句)。
選擇性編譯是筆者本身瞎想出來的名詞,不知道用的對不對。
添加以下代碼git
new webpack.DefinePlugin({ 'process.env': config.dev.env, IS_DEV: JSON.stringify(true), }),
添加以下代碼github
new webpack.DefinePlugin({ 'process.env': config.dev.env, IS_DEV: JSON.stringify(false), }),
添加以下代碼web
if (IS_DEV) { console.log('this is dev env'); } else { console.log('this is prod env'); }
this is dev env
。在生產環境下運行打印了this is prod env
。this is prod env
。咱們發現IS_DEV變成了false。
由於瀏覽器在運行代碼時,拿到的文件裏面IS_DEV已經被替換成了true或者false,已經不存在IS_DEV這個變量。因此不會報錯。chrome
如TEST_DATA: JSON.stringify({name:'momo',age:18}),npm
如:TWO: "1+1",TOW將被替換成這段代碼的結果,即2。數組
ESLint是一個用來識別 ECMAScript 而且按照規則給出報告的代碼檢測工具,使用它能夠避免低級錯誤和統一代碼的風格。
配置了eslint的項目在使用選擇性編譯功能時,可能會報出這樣的錯誤。
http://exlint.org/docs/rules/no-undef 'IS_DEV' is not defined
正如報錯信息所說的,這是因爲eslint檢測代碼時,發現IS_DEV沒有定義(這側面說明了eslint是先於條件編譯執行的。ESLint檢測時,IS_DEV尚未被替換掉)。解決這個問題有如下三種方法:
'eslint':'recommended'
(這是引用默認配置)。則往rules裏面添加一條規則'no_undef':'warn'
,以覆蓋掉默認配置。若是已經存在'no-undef'的配置,則直接改成'warn'就行。瀏覽器
用if邏輯判斷來輸出log可能略顯繁瑣。其實對於控制檯輸出的日誌,咱們能夠經過UglifyJs在打包時來剔除。
具體操做:app
打開build/webpack.prod.conf.js文件,添加以下語句
compress: { warnings: false, // 去除warning警告 drop_debugger: true, // 發佈時去除debugger語句 drop_console: true // 發佈時去除console語句 },
若是想只去除console.log,同時保留console.error等錯誤提示。能夠指定去除特定的函數
compress: { warnings: false, // 去除warning警告 pure_funcs: ['console.log'], // 配置發佈時,不被打包的函數 // drop_debugger: true, // 發佈時去除debugger // drop_console: true // 發佈時去除console }
注意,添加了這個配置之後,console.log在打包出來的文件就不存在了。因此前面測試用的this is dev env也會消失不見
例如咱們在條件編譯打包出來的代碼中
if (false) { console.log('this is dev env'); } else { console.log('this is prod env'); }
```console.log('this is dev env');```就是不可達代碼。 咱們一樣可使用UglifyJs的功能把這部分無用代碼去除掉。讓條件編譯不留痕跡。 具體配置以下: ``` compress: { warnings: false, // 去除warning警告 dead_code: true, // 去除不可達代碼 }, sourceMap: true ``` ![dead_code](http://upyun.luckly-mjw.cn/Assets/selective-compilation/dead_code.png)
UglifyJs還用不少強大的功能,如代碼混淆,壓縮,重拍版等。這裏附上UglifyJs官方網址。
英文很差的同窗還能夠查看對應的中文文檔(其實這纔是重點#機智臉)。