どうもエンジニアのやまぐちです。
年末はビルドツールを触る機会が多かったため寝ても覚めてもWebpackな感じでした。 そんな中で単一ファイルコンポーネントでSCSS共通の変数やmixinを使う場合に少し悩んだので、 同じように苦労している方がいれば参考にしていただけたら幸いです。
https://github.com/webpack-contrib/sass-loader
ディレクトリ構成
ディレクトリ構成は以下で進めていきます。
/example ├ webpack.config.js ├ dist │ ├ app.js │ └ index.html └ src └ assets ├ script │ ├ app.js │ └ App.vue └ style ├ global.scss ├ _mixins.scss └ _variables.scss
/src/assets/style/global.scss
では、更に変数とMixinのファイルをimportします。
# global.scss @charset "utf-8"; @import "_variables"; @import "_mixins";
単純に@import
styleの中で@importすれば読み込むことが可能です。
# App.vue <template>...</template> <script>...</script> <style lang='scss' scoped> @import "../style/global.scss"; h1 { @include font-size($font-md); } </style>
しかし、この方法だと各ファイルのstyleに@importを記述する必要があり、保守性も悪いため実用的ではありません。
vue-loaderで設定
vueファイル内でscssを使うためにvue-loaderのオプションにsass-loaderを設定していると思います。
このsass-loaderのオプションを更に設定することで共通のscssファイルを読み込むことができます。
# webpack.config.js module.exports = { entry: './resorces/assets/script/app.js', output: { path: './dist', filename: '[name].js', }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { css: { loader: 'css-loader', }, scss: { loader: 'sass-loader', options: { data: '@import "global.scss";', includePaths: path.resolve(__dirname, './src/assets/sass/'), } }, }, }, }, ... ], ... }, ... }
sass-loaderオプションのdata
とincludePaths
を指定することにより共通のSCSSファイルを読み込むことができます。
data
にはstringが設定でき@import
を記述することでビルドに読み込まれるvueファイル内に自動的に追加されます。includePaths
にはimportしたいファイルが格納されているパスを指定します。
上記の設定をすることで全ての.vueファイルのscssの記述で@importが必要なくなります。
もちろんこちらの設定はSCSSファイルをビルドする際にも使用できます。
(SCSSファイルのビルド時には起点となるファイルでimportすれば良いのであまり必要なさそうですが。。)
# App.vue <template>...</template> <script>...</script> <style lang='scss' scoped> h1 { @include font-size($font-md); } </style>
まとめ
Webpack側で上記の設定しておくことで単一ファイルコンポーネント側に余計な記述をしなくて済みました。
ただしwebpack.config.jsへ単純に記述してしまうとmoduleの中が冗長になってしまうので関数化するなどの対応をしたほうが良いと思いました。
頑張って調べたけれどもっと効率の良い方法などありましたらご教授お願いいたします!