作者:水濤 座右銘:天行健,君子以自強不息 自白:我寫博文上來蹭蹭就是乾,我突然覺得我需要幽默一點了,好了,下麵我們說正經的 一、官方定義: DefinePlugin 允許創建一個在 編譯 時可以配置的全局常量。這可能會對開發模式和生產模式的構建允許不同的行為非常有用。如果在開發構建中,而不在發佈構 ...
作者:水濤
座右銘:天行健,君子以自強不息
自白:我寫博文上來蹭蹭就是乾,我突然覺得我需要幽默一點了,好了,下麵我們說正經的
一、官方定義:
DefinePlugin
DefinePlugin
允許創建一個在編譯時可以配置的全局常量。這可能會對開發模式和生產模式的構建允許不同的行為非常有用。如果在開發構建中,而不在發佈構建中執行日誌記錄,則可以使用全局常量來決定是否記錄日誌。這就是 DefinePlugin
的用處,設置它,就可以忘記開發環境和生產環境構建的規則。
new webpack.DefinePlugin({
// Definitions...
});
用法
每個傳進 DefinePlugin
的鍵值都是一個標誌符或者多個用 .
連接起來的標誌符。
- 如果這個值是一個字元串,它會被當作一個代碼片段來使用。
- 如果這個值不是字元串,它會被轉化為字元串(包括函數)。
- 如果這個值是一個對象,它所有的 key 會被同樣的方式定義。
- 如果在一個 key 前面加了
typeof
,它會被定義為 typeof 調用。
這些值會被內聯進那些允許傳一個代碼壓縮參數的代碼中,從而減少冗餘的條件判斷。
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify('5fa3b9'),
BROWSER_SUPPORTS_HTML5: true,
TWO: '1+1',
'typeof window': JSON.stringify('object'),
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
});
console.log('Running App version ' + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require('html5shiv');
When defining values for
process
prefer'process.env.NODE_ENV': JSON.stringify('production')
overprocess: { env: { NODE_ENV: JSON.stringify('production') } }
. Using the latter will overwrite theprocess
object which can break compatibility with some modules that expect other values on the process object to be defined.
註意,因為這個插件直接執行文本替換,給定的值必須包含字元串本身內的實際引號。通常,有兩種方式來達到這個效果,使用
'"production"'
, 或者使用JSON.stringify('production')
。
二、個人分析
1、官網中說的“可以使用這個插件定義一些編譯時的全局常量”
編譯時這幾個字很重要,webpack會根據配置文件將將入口文件解析、打包、轉譯為瀏覽器可識別的js文件最後輸出到出口,而他轉譯的過程其實就是webpack編譯過程,也就是官網說的編譯時。
2、官網中說的“插件會直接替換文本”
> 在編譯過程中(轉譯為瀏覽器可識別的js文件時),會將源文件中所有用到DefinePlugin中定義的常量的地方直接替換為對應的值文本,註意,是文本無論語義上是對象還是字元串還是函數,都直接作為文本替換過去。
示例1:
假設在配置文件中定義編譯時全局常量 process.env.firstName
new webpack.DefinePlugin({
'process.env.firstName': JSON.stringify("ShuiTao")
});
源文件index.js內容如下
console.log(process.env.firstName)
最終轉譯後的js文件
console.log('ShuiTao')
可以看到,在編譯生成新js文件時,將process.env.firstName
常量直接替換成了他對應的值文
示例2:
假設在配置文件中定義編譯時全局常量 process.env.info
new webpack.DefinePlugin({ 'process.env.info': JSON.stringify({
name:'ShuiTao',
age:23
}) });
源文件index.js內容如下
console.log(process.env.info)
最終轉譯後的js文件
console.log({
name:'ShuiTao',
age:23
})
可以看到,在編譯生成新js文件時,將process.env.info
常量直接替換成了他對應的值文本
示例3:
假設在配置文件中定義編譯時全局常量 process.env.info
new webpack.DefinePlugin({ 'process.env.info': JSON.stringify({
name:'ShuiTao',
age:23
}) });
源文件index.js內容如下
console.log(process.env);
console.log(process.env.info);
最終轉譯後的js文件
console.log(process.env);
console.log({
name:'ShuiTao',
age:23
});
可以看到,在編譯生成新js文件時,將process.env.info
常量直接替換成了他對應的值文本,而process.env
沒有被替換,因為沒有在DefinePlugin中定義process.env
運行最終轉譯後的js文件時,process.env
指向的是Node中的process
,在process.env
中找不到info
屬性,足以證明在DefinePlugin定義的process.env.info
和Node
的process
沒有任何關係,他只是一個在插件中定義的編譯時的常量,編譯後就已經被替換了,因此 理解清楚概念,他只是個編譯時的常量,轉譯後就會被替換,只是恰好常量的名字是process.env.info