《Webpack入門系列》DefinePlugin插件用法理解

做者:水濤
座右銘:天行健,君子以自強不息
自白:我寫博文上來蹭蹭就是幹,我忽然以爲我須要幽默一點了,好了,下面咱們說正經的javascript

1、官方定義:

DefinePlugin

DefinePlugin 容許建立一個在編譯時能夠配置的全局常量。這可能會對開發模式和生產模式的構建容許不一樣的行爲很是有用。若是在開發構建中,而不在發佈構建中執行日誌記錄,則可使用全局常量來決定是否記錄日誌。這就是 DefinePlugin 的用處,設置它,就能夠忘記開發環境和生產環境構建的規則。html

new webpack.DefinePlugin({
  // Definitions...
});

用法 

每一個傳進 DefinePlugin 的鍵值都是一個標誌符或者多個用 . 鏈接起來的標誌符。html5

  • 若是這個值是一個字符串,它會被看成一個代碼片斷來使用。
  • 若是這個值不是字符串,它會被轉化爲字符串(包括函數)。
  • 若是這個值是一個對象,它全部的 key 會被一樣的方式定義。
  • 若是在一個 key 前面加了 typeof,它會被定義爲 typeof 調用。

這些值會被內聯進那些容許傳一個代碼壓縮參數的代碼中,從而減小冗餘的條件判斷。java

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')over process: { env: { NODE_ENV: JSON.stringify('production') } }. Using the latter will overwrite the process object which can break compatibility with some modules that expect other values on the process object to be defined.webpack

注意,由於這個插件直接執行文本替換,給定的值必須包含字符串自己內的實際引號。一般,有兩種方式來達到這個效果,使用 '"production"', 或者使用 JSON.stringify('production')web

2、我的分析

一、官網中說的「可使用這個插件定義一些編譯時的全局常量」瀏覽器

編譯時這幾個字很重要,webpack會根據配置文件將將入口文件解析、打包、轉譯爲瀏覽器可識別的js文件最後輸出到出口,而他轉譯的過程其實就是webpack編譯過程,也就是官網說的編譯時。函數

二、官網中說的「插件會直接替換文本」ui

 > 在編譯過程當中(轉譯爲瀏覽器可識別的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.infoNodeprocess沒有任何關係,他只是一個在插件中定義的編譯時的常量,編譯後就已經被替換了,所以 理解清楚概念,他只是個編譯時的常量,轉譯後就會被替換,只是剛好常量的名字是process.env.info

相關文章
相關標籤/搜索