實用webpack插件之ProvidePlugin

ProvidePlugin.png

現代化前端的全局引入是一個頗有趣的東西。
先來看下如下幾個場景:前端

  • 在webpack中,咱們能夠在resolve的alias中定義一個層級較高的目錄爲一個自定義變量。例如resolve: { alias: { '@': path.join(__dirname, '..', 'src') }}
  • 在webpack中,咱們也能夠經過DefinePlugin將配置文件按照環境變量進行區分,高效的完成配置文件的按環境引入,不管是開發構建仍是生產構建,都十分有用。
  • 在vue中,咱們能夠將一個經常使用的方法或者庫定義在Vue.ptototye上,能夠經過直寫屬性,也能夠經過vue中的plugin install上去。例如Vue.prototype.$_ = lodash,在應用了vue的應用上下文中,能夠經過this.$_得到對lodash的引用。
  • 在vue中,還有mixins,inject以及vuex等等這些全局綁定或者叫混入、注入方式的全局引入的實現。

來思考一個問題:vue

若是咱們再Vue.prototype上綁定了太多,太大的第三方庫,會不會致使root vue過大?
答案是確定的。

有沒有辦法解決這個問題?
你可能會說,我不用this.xxx。用到的vue單文件組件直接import或者require就行了。

若是數以百計,數以千計甚至是數以萬計的.vue文件中用到了呢?一直引入嗎?
能夠一直引入。可是會形成沒必要要的工做量。

有沒有更加優雅的解決辦法?webpack

再來思考一個問題:web

若是我要在一個webpack打包覆蓋的地方的xxx.js文件中用到lodash,該怎麼作?
一般來說,咱們會直接`import _ from' lodash'`或者`const _ = require('lodash')`。

若是和.vue同樣,有不少不少js文件須要引入呢?一直引入嗎?
能夠一直引入。一樣會形成沒必要要的工做量。

有沒有更加優雅的實現方式?vuex

看一張一直引入moment,引了99次的圖先來感覺一下:ide

image.png
雖然個人項目中是在優化moment的引入,可是爲了直觀明瞭,我將以引入lodash爲例。函數

  • 使用ProvidePlugin的三種方式
  • 爲什麼一直引入形成沒必要要工做量
  • 使用ProvidePlugin引入實踐
  • 思考優化

    • 使用ProvidePlugin後會比一直引入減少打包體積嗎?
    • 使用ProvidePlugin有哪些注意事項?

使用ProvidePlugin的三種方式

// 語法
new webpack.ProvidePlugin({
  identifier: 'module1',
  // identifier: ['module1', 'property1'],
});
  • module.exportsui

    • 直接引入
    • 引入某個函數
  • export default

module.exports

直接引入
new webpack.ProvidePlugin({
  $_: 'lodash',
});
引入某個函數
new webpack.ProvidePlugin({
  $_uniqBy: ['lodash','uniqBy']
});

export default

new webpack.ProvidePlugin({
  Vue: ['vue/dist/vue.esm.js', 'default']
});

爲什麼一直引入形成沒必要要工做量

加入咱們有a~z,a.js到z.js總結26個js文件,每一個文件都須要引入lodash。this

// a.js
import $_ from 'lodash';
// b.js
import $_ from 'lodash';
// c.js
import $_ from 'lodash';
// d.js
import $_ from 'lodash';
// e.js
import $_ from 'lodash';
// f.js
import $_ from 'lodash';
...
// z.js
import $_ from 'lodash';

這樣作有如下幾個弊端

  • 要乖乖引入26次
  • import進來以後的自定義名稱可能會不統一,致使全局搜索困難

好比說下面這種場景,對於代碼可讀性是很很差的。

// a.js
import $_ from 'lodash';
// b.js
import _ from 'lodash';

使用ProvidePlugin引入實踐

  • webpack的plugins中增長$_的配置
  • eslint的globals增長$_的配置
  • 頁面中如何使用$_

webpack的plugins中增長$_的配置

// webpack.base.config.js
plugins: [
    new webpack.ProvidePlugin({
      $_: 'lodash',
    }),
],

eslint的globals增長$_的配置

// .eslintrc.js
globals: {
    $_: 'readonly', // 或者true
},

配置爲readonly是由於咱們不會改寫lodash,僅僅是調用其方法。

頁面中如何使用$_

假設在a.js中。
刪除單獨的lodash引入 :import from 'lodash'
直接使用$_ :$_.uniqBy(...)

思考

使用ProvidePlugin後會比一直引入減少打包體積嗎?

不會。
這是我本身對比使用ProvidePlugin前使用ProvidePlugin後打包文件體積大小得出的結論。
至於具體緣由還有待探索。

使用ProvidePlugin有哪些注意事項?

這些注意事項其實主要是爲了加強代碼可讀性和可維護性。

  • 儘可能定義出惟一性高的全局變量,例如$_,$moment
  • 同一個前端小組的成員都採用全局變量的方式引入
  • 最好是能維護一個全局變量的文檔,在新人入職時特殊強調

看到這裏,文章開頭Vue.prototype.xxx和import和require重複引入的問題」有沒有更加優雅的實現方式?「就迎刃而解啦。

快到你的項目中試試ProvidePlugin吧~

相關文章
相關標籤/搜索