Nuxt.js を利用したプロジェクトで、sass のどこからでも利用したい mixin や変数などを、各コンポーネントで個別にインポートせずに一括で読み込みます。 vue-loader にオプションを渡せばいいのですが、nuxt.config.js から webpack の設定を変更するには、少しだけ工夫が必要です。
導入は vue-cil でサクッと進めます。
npx create-nuxt-app your-title
パッケージのインストール
まず vue-loader で sass(scss) を解釈したいので、node-sass と sass-loader のパッケージをインストールします。
yarn add --dev node-sass sass-loader
nuxt.config.js の設定
nuxt.config.js に次のように記述します。
module.exports = {
build: {
extend (config) {
/**
* vue-loader に オプションを渡す
*/
const vueLoader = config.module.rules.find(rule => rule.loader === 'vue-loader');
const { options: {loaders} } = vueLoader || { options: {} }
if (loaders) {
for (const loader of Object.values(loaders)) {
changeLoaderOptions(Array.isArray(loader) ? loader : [loader])
}
}
config.module.rules.forEach(rule => changeLoaderOptions(rule.use))
}
}
}
/**
* loader の名前一致でオプションをセットする
*/
function changeLoaderOptions(loaders) {
if (loaders) {
for (const loader of loaders) {
let options;
switch (loader.loader) {
case 'sass-loader':
options = {
includePaths: [
path.resolve(__dirname, './assets/sass/foundation/variable/'),
path.resolve(__dirname, './assets/sass/foundation/mixin/')
],
data: '@import "_variable";\n@import "_mixin";'
};
break
// 他の loader を追加できる
// case 'stylus-loader':
// options = {
// includePaths: [path.resolve(__dirname, './assets/sass/')],
// import: ['_import']
// }
// break
}
if (options) {
Object.assign(loader.options, options)
}
}
}
}
config
の引数から vue-loader にアクセスして、option
の includePaths
にディレクトリ、 data
に import したいファイルを渡します。
さらにこのコードでは stylus-loader など、Vue-loader の別の loader にもオプションが渡せるようにしています。
これで
$white: #fafafa !default;
と、用意した変数が、
<style lang="scss">
.ex {
background-color: $white;
}
</style>
というふうにしてあげると、各コンポーネントで import せずに、利用できるようになります。
Nuxt Style Resources で かんたんに読み込む
Nuxt Style Resources というモジュールを利用すると、先に紹介したようなコードを記述せずにシンプルに変数の読み込みを実装できます。(nuxt-sass-resources-loader は終了しました)
yarn add @nuxtjs/style-resources
module.exports = {
modules: ['@nuxtjs/style-resources'],
styleResources: {
scss: [
'~/assets/sass/foundation/variable/_index.scss',
'~/assets/sass/foundation/mixin/_index.scss'
]
}
}
というような感じで、手早く実装することができます。ちなみに、Nuxt Style Resources は LESS や Stylus にも対応しているので、同様の方法で必要なリソースを読み込むことができます。
基本はこの方法で実装する方が簡単だしお手軽だとは思いますが、一応 loader にどうやってオプションを渡すのかを理解しておくのも大切かなと思っています。
アトミックデザインの atoms としての変数に
ぼくはここで読み込むような変数や mixin 群を、アトミックデザインの atoms として捉えていて、「components / molecules - organisms」「layouts - templates」「pages - pages」 というように、Nuxt.js のディレクトリ構成と紐づけることができるので、Nuxt.js はアトミックデザインにかなり接近したフレームワークだなあというところで、気に入っています。🍟
nuxt.config.js をうまく扱えるようになると、 Nuxt.js と仲良くなれるみたいなので、またまとめていきたいと思います。
おわります。