アセットディレクトリ
assets
ディレクトリには、Stylus や Sass ファイル、画像、フォントなどコンパイルされていないアセットが含まれます。
画像
vue
テンプレートの中で assets
ディレクトリにリンクする必要がある場合は、assets の前にスラッシュを付け ~/assets/your_image.png
と記述します。
<template>
<img src="~/assets/your_image.png" />
</template>
css
ファイルの中で assets
ディレクトリにリンクする必要がある場合は、スラッシュなしで ~assets/your_image.png
と記述します。
background: url('~assets/banner.svg');
動的イメージを使う場合は、require を使う必要があります。
<img :src="require(`~/assets/img/${image}.jpg`)" />
スタイル
Nuxt では、グローバル (すべてのページ)に設定したい CSS ファイルやモジュール、ライブラリを定義することができます。nuxt.config 内で CSS プロパティを使って簡単にスタイルを追加することができます。
export default {
css: [
// 直接 Node.js モジュールをロード (ここは Sass ファイル)
'bulma',
// プロジェクト内の CSS ファイル
'~/assets/css/main.css',
// プロジェクト内の SCSS ファイル
'~/assets/css/main.scss'
]
}
Sass
sass
を使用したい場合、sass
と sass-loader
プラグインがインストールされているか確認してください。
yarn add --dev sass sass-loader@10
npm install --save-dev sass sass-loader@10
Nuxt は拡張子からファイルの種類を自動的に推測して webpack に適したプリプロセッサローダーを使用します。それでも必要な場合は、必要なローダーをインストールする必要があります。
フォント
ローカルフォントをアセットフォルダに追加することで使用できるようになります。追加したら @font-face を使用して css からアクセスすることができます。
-| assets
----| fonts
------| DMSans-Regular.ttf
------| DMSans-Bold.ttf
@font-face {
font-family: 'DM Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('~assets/fonts/DMSans-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'DM Sans';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('~assets/fonts/DMSans-Bold.ttf') format('truetype');
}
Webpack アセット
デフォルトでは、Nuxt は webpack の vue-loader、file-loader、url-loader を使用してアセットを提供します。また webpack を通して実行されるべきではないアセットのために、静的ディレクトリを使用することもできます。
Webpack
vue-loader は、css-loader
と Vue Template Compiler を用いて、スタイルやテンプレートファイルを自動的に処理します。このコンパイル処理の中で、<img src="...">
や background: url(...)
や CSS @import
などのすべてのアセット URL はモジュールの依存関係として解決されます。
例えば、次のようなファイル構成があるとします:
-| assets/
----| image.png
-| pages/
----| index.vue
CSS で url('~assets/image.png')
と記述した場合、それは require('~/assets/image.png')
に変換されます。
~/
エイリアスは CSS ファイルで正しく解決されないでしょう。CSS の url
の参照には、~assets
(スラッシュなし)を使わなければなりません。例: background: url("~assets/banner.svg")
pages/index.vue
で画像を参照する場合:
<template>
<img src="~/assets/image.png" />
</template>
次のようにコンパイルされます:
createElement('img', { attrs: { src: require('~/assets/image.png') } })
.png
は JavaScript ファイルではないため、Nuxt は file-loader](https://github.com/webpack/file-loader ) と url-loader を使ってそれらを処理できるよう webpack を設定します。
これらのローダーを利用する利点:
file-loader
は、アセットファイルをコピー・配置する場所と、キャッシュ改善のためにバージョンハッシュを用いてファイル名を指定することができます。本番環境では、デフォルトで長期的なキャッシングの恩恵を受けることができます。
url-loader
は、指定した閾値よりも小さい場合に、Base64 データ URL として条件付きでファイルに埋め込むことができます。これにより、小さなファイル取得のための HTTP リクエスト数を減らすことができます。もし閾値よりも大きい場合は、file-loader に自動的にフォールバックします。
これら 2 つのローダーのデフォルトの設定は次の通りです:
// https://github.com/nuxt/nuxt/blob/2.x-dev/packages/webpack/src/config/base.js#L382-L411
{
test: /\.(png|jpe?g|gif|svg|webp|avif)$/i,
use: [{
loader: 'url-loader',
options: {
esModule: false,
limit: 1000, // 1kB
name: 'img/[name].[contenthash:7].[ext]'
}
}]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [{
loader: 'url-loader',
options: {
esModule: false,
limit: 1000, // 1kB
name: 'fonts/[name].[contenthash:7].[ext]'
}
}]
},
{
test: /\.(webm|mp4|ogv)$/i,
use: [{
loader: 'file-loader',
options: {
esModule: false,
name: 'videos/[name].[contenthash:7].[ext]'
}
}]
}
つまり、1 KB 未満のすべてのファイルは Base64 データ URL としてインライン化されます。 それ以外の場合、画像やフォントは、対応するフォルダ(.nuxt
ディレクトリの下)にコピーされ、より良いキャッシュのためにバージョンハッシュを含む名前が付けられます。
nuxt
コマンドでアプリケーションを起動するときの pages/index.vue
のテンプレートは以下の通りです:
<template>
<img src="~/assets/your_image.png" />
</template>
次のように生成されます:
<img src="/_nuxt/img/your_image.0c61159.png" />
ローダの設定を変更したい場合は build.extend を使用してください。
エイリアス
デフォルトでは、ソースディレクトリ (srcDir) とルートディレクトリ (rootDir) は同じディレクトリを意味します。ソースディレクトリには ~
のエイリアスを使うことができます。../assets/your_image.png
のような相対パスを記述する代わりに、~/assets/your_image.png
と記述することができます。
どちらも同じ結果になります。
<template>
<div>
<img src="../assets/your_image.png" />
<img src="~/assets/your_image.png" />
</div>
</template>
エイリアスとして ~
を使うことをお勧めします。@
はまだサポートされていますが、CSS の background image などすべてのケースで機能するわけではありません。
ルートディレクトリには、エイリアスの ~~
や @@
を使用することができます。
Option
+ ñ
)、または Windows では(Alt gr
+ 4
)で ~
にアクセスできます。











































