[{"data":1,"prerenderedAt":488},["ShallowReactive",2],{"article-bootstrap-vue-asset-save":3},{"id":4,"title":5,"body":6,"category":475,"createdAt":477,"description":5,"extension":478,"index":479,"meta":480,"navigation":52,"path":481,"publish":52,"seo":482,"series":479,"seriesTitle":479,"stem":483,"tag":484,"thumbnail":486,"updatedAt":479,"__hash__":487},"articles\u002Farticles\u002Fbootstrap-vue-asset-save.md","bootstrap-vue,iconのバンドルを減らす。開発時に気をつけたいbootstrap-vueの使い方",{"type":7,"value":8,"toc":465},"minimark",[9,13,16,20,23,66,69,72,83,131,138,145,278,285,289,299,391,394,397,404,433,440,444,447,450,458,461],[10,11,12],"p",{},"こんにちはjunです。Nuxt.js or Vue.js x Bootstrap-vue の構成を使って管理画面UIを作成する機会が多く、それらの融合性や使いやすさに虜になっています。しかしやけにビルドの時間がかかるなーと思っていたら、なんとバンドルサイズが1MBを超いたという事実に気付き、慌てて対処しました。（他のライブラリもあります）",[10,14,15],{},"今回はそのbootstrap-vueを使ったアプリのバンドルサイズを減らす方法として、開発時から気をつけたいことについて述べます。",[17,18,19],"h2",{"id":19},"そのままいれるな",[10,21,22],{},"ドキュメントの最初の方にある通り、bootstrap-vueとboo-strap-iconを以下のようにいれるとかなりサイズを食います。",[24,25,30],"pre",{"className":26,"code":27,"language":28,"meta":29,"style":29},"language-javascript shiki shiki-themes material-theme-ocean","import Vue from 'vue'\nimport { BootstrapVue, IconsPlugin } from 'bootstrap-vue';\n\nVue.use(BootstrapVue);\nVue.use(IconsPlugin);\n","javascript","",[31,32,33,41,47,54,60],"code",{"__ignoreMap":29},[34,35,38],"span",{"class":36,"line":37},"line",1,[34,39,40],{},"import Vue from 'vue'\n",[34,42,44],{"class":36,"line":43},2,[34,45,46],{},"import { BootstrapVue, IconsPlugin } from 'bootstrap-vue';\n",[34,48,50],{"class":36,"line":49},3,[34,51,53],{"emptyLinePlaceholder":52},true,"\n",[34,55,57],{"class":36,"line":56},4,[34,58,59],{},"Vue.use(BootstrapVue);\n",[34,61,63],{"class":36,"line":62},5,[34,64,65],{},"Vue.use(IconsPlugin);\n",[10,67,68],{},"理由はnode_modulesのBootstrap-vueの全てを入れているためです。別に全てのbootstrapモジュールを使用しているならば問題ありませんが、基本的にそんな状況はないと思います。importでモジュールを読み込む時は原則、必要なものだけインポートして置くことがベストです。それを意識するだけでも自然とバンドルサイズが小さくなります。",[17,70,71],{"id":71},"必要なものだけ指定する",[10,73,74,75,82],{},"やり方は",[76,77,81],"a",{"href":78,"rel":79},"https:\u002F\u002Fbootstrap-vue.org\u002Fdocs#vue-cli-3",[80],"nofollow","公式ドキュメント","にもありますが、必要なコンポーネントだけ使用する場合は以下のようにします。",[24,84,87],{"className":26,"code":85,"filename":86,"language":28,"meta":29,"style":29},"import {  \n    BButton,BSpinner,BTable,BAlert\n} from 'bootstrap-vue';\n\nVue.component('b-button',BButton);\nVue.component('b-spinner',BSpinner);\nVue.component('b-table',BTable);\nVue.component('b-alert',BAlert);\n","parent.js",[31,88,89,94,99,104,108,113,119,125],{"__ignoreMap":29},[34,90,91],{"class":36,"line":37},[34,92,93],{},"import {  \n",[34,95,96],{"class":36,"line":43},[34,97,98],{},"    BButton,BSpinner,BTable,BAlert\n",[34,100,101],{"class":36,"line":49},[34,102,103],{},"} from 'bootstrap-vue';\n",[34,105,106],{"class":36,"line":56},[34,107,53],{"emptyLinePlaceholder":52},[34,109,110],{"class":36,"line":62},[34,111,112],{},"Vue.component('b-button',BButton);\n",[34,114,116],{"class":36,"line":115},6,[34,117,118],{},"Vue.component('b-spinner',BSpinner);\n",[34,120,122],{"class":36,"line":121},7,[34,123,124],{},"Vue.component('b-table',BTable);\n",[34,126,128],{"class":36,"line":127},8,[34,129,130],{},"Vue.component('b-alert',BAlert);\n",[10,132,133,134,137],{},"上記はapp.jsのような元締めのファイルでグローバルコンポーネントとして登録する場合です。こうすれば配下のファイルで",[31,135,136],{},"\u003Cb-badge>\u003C\u002Fb-badge>","という風に使用できます。",[10,139,140,141,144],{},"グローバルでなく、局所的に単体のvueファイルで使用したい場合は",[31,142,143],{},"Vue.component()","でなく、そのvueファイルにいて以下のようにします。",[24,146,151],{"className":147,"code":148,"filename":149,"language":150,"meta":29,"style":29},"language-vue shiki shiki-themes material-theme-ocean","\u003Ctemplate>\n  \u003CBButton variant=\"danger\">Clikc\u003C\u002FBButton>\n\u003C\u002Ftemplate>\n\nimport { BButton } from 'bootstrap-vue';\n\u003Cscript>\nexport default{\n  components:{\n    BButton\n  }\n}\n\u003C\u002Fscript>\n","child.vue","vue",[31,152,153,166,204,212,216,221,230,242,251,257,263,269],{"__ignoreMap":29},[34,154,155,159,163],{"class":36,"line":37},[34,156,158],{"class":157},"sAklC","\u003C",[34,160,162],{"class":161},"s-wAU","template",[34,164,165],{"class":157},">\n",[34,167,168,171,174,178,181,184,188,190,193,197,200,202],{"class":36,"line":43},[34,169,170],{"class":157},"  \u003C",[34,172,173],{"class":161},"BButton",[34,175,177],{"class":176},"sJ14y"," variant",[34,179,180],{"class":157},"=",[34,182,183],{"class":157},"\"",[34,185,187],{"class":186},"sfyAc","danger",[34,189,183],{"class":157},[34,191,192],{"class":157},">",[34,194,196],{"class":195},"s0W1g","Clikc",[34,198,199],{"class":157},"\u003C\u002F",[34,201,173],{"class":161},[34,203,165],{"class":157},[34,205,206,208,210],{"class":36,"line":49},[34,207,199],{"class":157},[34,209,162],{"class":161},[34,211,165],{"class":157},[34,213,214],{"class":36,"line":56},[34,215,53],{"emptyLinePlaceholder":52},[34,217,218],{"class":36,"line":62},[34,219,220],{"class":195},"import { BButton } from 'bootstrap-vue';\n",[34,222,223,225,228],{"class":36,"line":115},[34,224,158],{"class":157},[34,226,227],{"class":161},"script",[34,229,165],{"class":157},[34,231,232,235,239],{"class":36,"line":121},[34,233,234],{"class":176},"export",[34,236,238],{"class":237},"s6cf3"," default",[34,240,241],{"class":157},"{\n",[34,243,244,248],{"class":36,"line":127},[34,245,247],{"class":246},"s5Dmg","  components",[34,249,250],{"class":157},":{\n",[34,252,254],{"class":36,"line":253},9,[34,255,256],{"class":195},"    BButton\n",[34,258,260],{"class":36,"line":259},10,[34,261,262],{"class":157},"  }\n",[34,264,266],{"class":36,"line":265},11,[34,267,268],{"class":157},"}\n",[34,270,272,274,276],{"class":36,"line":271},12,[34,273,199],{"class":157},[34,275,227],{"class":161},[34,277,165],{"class":157},[10,279,280,281,284],{},"グローバルでやっていたものを",[31,282,283],{},"components","配下で入れてあげるだけです。",[286,287,288],"h3",{"id":288},"アイコンも同様",[10,290,291,292,295,296,298],{},"アイコンが豊富な故にサイズも大きいです。",[31,293,294],{},"Vue.use(IconsPlugin);","とすると全てのアイコンがインポートされるので、これも以下のように",[31,297,283],{},"で使用します。",[24,300,302],{"className":147,"code":301,"language":150,"meta":29,"style":29},"\u003Ctemplate>\n  \u003CBIconXCircleFill variant=\"danger\">\n\u003C\u002Ftemplate>\n\nimport { BIconXCircleFill } from 'bootstrap-vue';\n\u003Cscript>\nexport default{\n  components:{\n    BIconXCircleFill\n  }\n}\n\u003C\u002Fscript>\n",[31,303,304,312,331,339,343,348,356,364,370,375,379,383],{"__ignoreMap":29},[34,305,306,308,310],{"class":36,"line":37},[34,307,158],{"class":157},[34,309,162],{"class":161},[34,311,165],{"class":157},[34,313,314,316,319,321,323,325,327,329],{"class":36,"line":43},[34,315,170],{"class":157},[34,317,318],{"class":161},"BIconXCircleFill",[34,320,177],{"class":176},[34,322,180],{"class":157},[34,324,183],{"class":157},[34,326,187],{"class":186},[34,328,183],{"class":157},[34,330,165],{"class":157},[34,332,333,335,337],{"class":36,"line":49},[34,334,199],{"class":157},[34,336,162],{"class":161},[34,338,165],{"class":157},[34,340,341],{"class":36,"line":56},[34,342,53],{"emptyLinePlaceholder":52},[34,344,345],{"class":36,"line":62},[34,346,347],{"class":195},"import { BIconXCircleFill } from 'bootstrap-vue';\n",[34,349,350,352,354],{"class":36,"line":115},[34,351,158],{"class":157},[34,353,227],{"class":161},[34,355,165],{"class":157},[34,357,358,360,362],{"class":36,"line":121},[34,359,234],{"class":176},[34,361,238],{"class":237},[34,363,241],{"class":157},[34,365,366,368],{"class":36,"line":127},[34,367,247],{"class":246},[34,369,250],{"class":157},[34,371,372],{"class":36,"line":253},[34,373,374],{"class":195},"    BIconXCircleFill\n",[34,376,377],{"class":36,"line":259},[34,378,262],{"class":157},[34,380,381],{"class":36,"line":265},[34,382,268],{"class":157},[34,384,385,387,389],{"class":36,"line":271},[34,386,199],{"class":157},[34,388,227],{"class":161},[34,390,165],{"class":157},[10,392,393],{},"アイコンはグローバルに登録するよりも、必要になったら都度入れとく方がいいです。",[17,395,396],{"id":396},"適宜必要なモジュールを入れる",[10,398,399,400,403],{},"BadgeやButtonは上記のような",[31,401,402],{},"Vue.commponent","で十分ですが、ModalやCollapseは追加のプラグインなどが必要です。例えばModalは以下のモジュールをセットしておく必要があります。",[24,405,407],{"className":26,"code":406,"language":28,"meta":29,"style":29},"import { BModal,VBModal,ModalPlugin } from 'bootstrap-vue';\n\nVue.use(ModalPlugin);\nVue.component('b-modal',BModal);\nVue.directive('b-modal', VBModal)\n",[31,408,409,414,418,423,428],{"__ignoreMap":29},[34,410,411],{"class":36,"line":37},[34,412,413],{},"import { BModal,VBModal,ModalPlugin } from 'bootstrap-vue';\n",[34,415,416],{"class":36,"line":43},[34,417,53],{"emptyLinePlaceholder":52},[34,419,420],{"class":36,"line":49},[34,421,422],{},"Vue.use(ModalPlugin);\n",[34,424,425],{"class":36,"line":56},[34,426,427],{},"Vue.component('b-modal',BModal);\n",[34,429,430],{"class":36,"line":62},[34,431,432],{},"Vue.directive('b-modal', VBModal)\n",[10,434,435,436,439],{},"こうすることでModalのコンポーネントや",[31,437,438],{},"this.$bvModal.show('select-file-modal');","のようなディレクティブや動きを実装できます。",[286,441,443],{"id":442},"どこにかいてある","どこにかいてある？",[10,445,446],{},"それぞのコンポーネントのドキュメントの最後の方にある、Component referenceにあります。さらにいうとその下のImporting individual componentsに詳しく、依存関係が書いてあるのでその通りにインポートしてあげましょう。",[17,448,449],{"id":449},"開発時初期から個別インポートを考える",[10,451,452,453,457],{},"もしこれに気づかず後から単体読み込みにしようと思ったら大変なことになります。 ",[454,455,456],"strong",{},"必要なコンポーネントの洗い出しとそのチェックが必要になるからです。"," ファイル検索でなんとからならくもないですが、後からの修正はかなり大変です。",[10,459,460],{},"であれば最初から個別のインポートで行っていくほうが、必要になった時にエラーで教えてくれるので対処がしやすいです。端末の性能や通信速度が上がっているとはいえ、まだ1Mを超えるのは気が引けます。塵も積もれば山となる精神で不要なインポートは避けましょう。",[462,463,464],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}",{"title":29,"searchDepth":49,"depth":49,"links":466},[467,468,471,474],{"id":19,"depth":43,"text":19},{"id":71,"depth":43,"text":71,"children":469},[470],{"id":288,"depth":49,"text":288},{"id":396,"depth":43,"text":396,"children":472},[473],{"id":442,"depth":49,"text":443},{"id":449,"depth":43,"text":449},[476],"ministack","2021-03-29","md",null,{},"\u002Farticles\u002Fbootstrap-vue-asset-save",{"title":5,"description":5},"articles\u002Fbootstrap-vue-asset-save",[485,150],"css","_mix\u002Fsch-2021-03-29-22.48.45.png","eqyqBM0LwYz49ZyHXkO-fsX2wiHR3pqkEe-fvzvZ4Hg",1780987144412]