什麼是 ProvidePlugin
ProvidePlugin 是基於 webpack 裡的一個設定方法,可以用來指定變數讓 JS 套件模組運作於 webpack 下使用,但無法在全域下使用。
ProvidePlugin 在 webpack 內以模組方式使用與全域執行的情形
jQuery 與 axios 的 JS 套件,在全域下的使用情形
將 jQuery 直接在 index.html 的 HTML 頁面將 jQuery 透過 <script src="jquery.js"></script> 方置到注入點 index.js 的方上,這樣的方式會讓 jQuery 變成一個全域物件,也就會在瀏覽器下直接輸入 $ 下方取到 jQuery 的物件。
在這裡要了解沒經模組化,將 JS 套件直接於全域下以 src 的方式引入情形,先進到 webpack 中把所有透過 import <自定模組變數名> from '<模組名>' 加入模組的套件先註解起來不使用。
直接在 index.html 的 </body> 結尾標籤處,在 <script src="./js/index.js"></script> 的 webpack 注入點前方加上下面 CDN,來執行看看二個掛載於全域下的情形。
1 2 | <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script> |
接著在 index.js 中的最後方,加入下面的程式碼,查看 JS 套件引入的情形。
1 2 3 4 | console.log('jQuery 變數 $', $); // jQuery 變數 $ ƒ (e,t){return new S.fn.init(e,t)} console.log('jQuery 變數 jQuery', jQuery); // jQuery引入後變數.html:14 jQuery 變數 jQuery ƒ (e,t){return new S.fn.init(e,t)} console.log('jQuery 變數 window.jQuery', window.jQuery); // jQuery引入後變數.html:15 jQuery 變數 window.jQuery ƒ (e,t){return new S.fn.init(e,t)} console.log('axios', axios); // axios ƒ (){for(var n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.apply(t,n)} |
在 $、 jQuery、 window.jQuery 這三個物件,也都是表示 jQuery 物件本身,直接掛於 window 的 $ 物件之下來使用,在成功引入 jQuery 時可以透過下面三個 console.log() 取得 jQuery 物件。
另外 axios 也是一樣的概念,使用 axios 會直接回應是一個函式。
以上就是二個套件在引入 JS 套件後,全域下透過 console.log() 取用情形,另外在瀏覽器開發工具上直接輸入 $、 jQuery、 window.jQuery 或是 axios 也會一樣直接對應上的結果。
使用 webpack 的 ProvidePlugin 設定,在模組裡與全域下的使用情形
webpack 在注入點多或元件多的情形下使用與設定的麻煩
在使用 webpack 進行開發使用模組,像是使用到 jQuery 來說,就需要在注入點 index.js 檔中輸入 import $ from 'jquery' 將模組引入使用。
以模組化的使用優點來說,就是在要使用時才透過 import <自定模組變數名> from '<模組名>' 的方式將模組引入使用。
這裡不使用前面直接在 index.html 檔直接把 jQuery 與 axios 透過 CDN 引入為全域物件的方式,先把 CDN 註解起來接著下面的操作。
再以使用 axios 的方式來說在多加上 import axios from 'axios' 引入使用,另外若要在加上 swiper 的概念也是一樣。
這樣的引用模組方式,在注入點多或是元件多的情形下使用上也會變的很麻煩,每個部份都要引入相關的模組進來使用。
透過 ProvidePlugin 指定 JS 套件於變數名稱,讓所有的 .js 與元件一次設定下共用
接下來要進行以 jQuery 的模組設定,先將 npm 中加入 jQuery 與 axios,這裡要使用會是上線後的生產模組還要用到 jQuery 與 axios 所以要使用 --save 而不是使用開發模組,不用在後方加上 -dev。
1 | npm run i jquery axios -S |
透過 webpack 的功能 ProvidePlugin 來設定,就可以讓每支 js 檔,以不用 import 引入第三方套件的方式。
設定內容如下。
1 2 3 4 5 6 7 8 | plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', axios: 'axios', }), ] |
以下說明在 ProvidePlugin 的設定方式,是直接在 plugins: [] 裡以 new webpack.ProvidePlugin() 中帶入一個物件 {} 來說定,物件中的屬性名稱都可用來在 webpack 中使用所表示的引用的套件名,以上面的設定來說就分別是 $ jQuery window.jQuery 設定三組,當然也可以自已另外命一個名稱自定義,以 axios: 'axios' 就是將 axios 模組指定變數為 axios。
接著在 index.js 的注入點透過 console.log($(‘#box1’)) 查看 jQuery 取 DOM 元素的結果。
使用指令 npm run dev 啟用 webpack-dev-server 查看執行結果。
瀏覽器往啟後查看後會取得訊息如下,這樣就表非 jQuery 是在全域的設定下取得 #box1 的位置。
$ jQuery window.jQuery 設定三組和 jQuery 本身在全域的使用名稱一樣,但透過 webpack 包進模組後,無法直接在 window 下直接取得,所以需要在 webpack 裡設定變數名稱,指定在模組內以變數名取用引入的 JS 套件的模組。
如何証明 axios 與 jQuery 不是全域物件呢。
在瀏覽器直接輸入 axios 與 jQuery 與 window.jQuery,在 global (全域) 上無法取得 jQuery 的物件,這樣就是透過 webpack 把 JS 套件透過模組直接包進來,外層的 window 呼叫不到。
前面是在 index.js 注入點執行 console.log() 的 jQuery 與 axios 呼叫與執行 AJAX 正常,而後方是直接在瀏覽器的全域下的呼叫, window 下找不到對應的套件出來。
ProvidePlugin 的設定,在 webpack 裡失去了透過模組化 js 的好處了,會有不好除錯的情形產生
1. 你會無法得知哪個 js 組件引入了那些 lib
2. 當組件出現bug時我們無法得知是第三方套件問題還是自己問題
很重要說所以說三次
非必要盡量不要使用 ProvidePlugin 這個做法!!!
非必要盡量不要使用 ProvidePlugin 這個做法!!!
非必要盡量不要使用 ProvidePlugin 這個做法!!!
Comments are closed.