Enviroment古い環境からViteへの載せ替えについて
astro
pug
Rollup.js
typescriptル
Vite
コンパイconfig
いつもは Gulp + webpack という構成でサイトを構築するのですが、
ある案件(npm-scriptsの構築環境)で IntelMac 時代には動いた環境構成が M1Mac では動かないということが起こったので、
「環境を載せ替え変えないといけないよね。後々のことを考えるとしないといけないよね。」ということになり、
初Vite 環境を構築することになりました。
のちに M1Mac のせいではないことが発覚しました。
元々の npm-scripts の環境構成
前任者(もう退職して在籍していない)が残した環境は、以前ならばモダンと言われる様な環境だったと思うのですが、
如何せん 2019年 の環境構成だったため、色々と古く新たに npm iを行うと、
IntelMacでは問題なかったことが、M1Macではうまくいかないことが発生して、
ローカルサーバーを立ち上げるのにも一苦労でした。
元々の技術選定
- npm-scripts
- es5 Typescript
- babel v7
- webpack v4
- browser-sync v2
- pug
- stylus
- jquery v3
- gsap v2
- slick v1.8
上記の技術で構成されている環境でした。
これをVite に載せ替えて、構築環境にストレスが発生しないようにすることが目標です。
目指すべき構成
- Vite
- pug
- stylus
- jquery v3
- gsap v2
- slick v1.8
jquery v3 (slickのためだけのjQuery),gsap v2 ,slick v1.8 を残して(バージョンアップする、他ライブラリへの移行の工数を取れなかったため)、
Typescriptっぽく書かれていたもの(ほぼほぼJS)も、型づけして書き換えて、
元々あった資産(pug,stylus )を活用し、外側(Vite)だけモダンな環境を目指します。
載せ替えるにあたっての動かせない物・動かしたくないもの
当然既に公開されているサイトなので、
公開された環境(ディレクトリ構成、ファイル名)は当然動かせないわけですが、
それに加えて、構築環境のディレクトリ構成も動かしたくないわけで、
Viteの初期環境から元々の環境になるように設定していく必要がありました。
Viteの初期環境
.
├── dist
├── index.html
├── node_modules
├── package.json
├── public
├── src
├── tsconfig.json
└── yarn.lock
目指すべき環境
.
├── dist(build 結果)
│ ├── about
│ │ └── index.html
│ ├── assets
│ │ ├── images
│ │ ├── scripts
│ │ └── styles
│ └── index.html
├── node_modules
├── package-lock.json
├── package.json
└── src
├── public
└── サイト構築に関わるすべてのソースファイル
あまりにも違う初期環境なので当然頭を悩ましました。
とりあえず、
「公式のドキュメントを読もう!!!」
です。
若干補足しますが、
「サイトを構成するファイルは静的なファイル(画像、フォント、動画など)も含めすべて、srcディレクトリに押し込めたい。」
ということがあり、Viteの環境下での publicディレクトリは srcディレクトリの配下に移動させました。
共通オプション: 基本中の基本
共通オプションである下記のオプションを設定する必要があります
他にも共通オプションはたくさんありますが、
共通オプションとしては下記の2つに加えて plugin を含めての3つ程度しか使用しませんでした。
plugin に関しては pug を使用するためのプラグインを下記のページを参考に作成しました。
@yend724 zenn Viteで純粋なPugを使う
- root
- プロジェクトのRootとするところの設定ですが、index.htmlを設置する箇所なので、今回は srcにします。
共通オプション root - publicDir
- 静的ファイル群の使用の有無なので、画像、フォントファイルなどの使用があるため、
デフォルトで public が設定されていますが明示的に設定します。
共通オプション publicDir
serverオプション
こちらは特に設定しなくても期待通りの動きだったので、そのまま使用しています。
buildオプション
ここの設定が1番のキモでした。
目指すべき環境のディレクトリ構成にするための設定はここでしか設定することができなく、
ここを設定することで、ディレクトリ構成を自由に操作できるというところでした。
設定した項目
- modulePreload
- デフォルトは { polyfill: true }になっています。
後述の rollupOptions.inputを設定する場合、polyfillを必ず import する必要があるということで、
今回はこちらを .ts ファイルに記述して、コンパイル結果の .js ファイルに含まれる様にしました。
ビルドオプション build.modulePreload - outDir
- コンパイル結果を吐き出す先を指定する
こちらはデフォルトと同じですが、distを明示的に設定しています。
ビルドオプション build.outDir - emptyOutDir
- 本来であればビルドした時に dist ディレクトリの中を空にしたいところですが、
ドキュメントに記載されているようなディレクトリ構成ではないので、デフォルトの動きの中で空にすることは諦めました。
そののまでは Warning のテキストが表示されるので、emptyOutDir: falseを設定し、
package.json の build コマンドの先頭で、dist をコマンドラインから削除する形に設定しました。
ビルドオプション build.emptyOutDir - copyPublicDir
- public の中身を dist の直下にコピーして欲しいので、
こちらは true を設定します。
ビルドオプション build.copyPublicDir - rollupOptions
- コンパイル後のバンドルに関する設定はこちらで行うのですが、
その部分は Rollup.jsが担っているので、別枠で記載します。
ビルドオプション build.rollupOptions
rollupOptions の設定
rollupOptions.input への設定
Viteのデフォルトの環境では index.html が使用され、
buildコマンドを実行した際は、root直下の index.html をコンパイル対象としてみなし、実行してくれます。
しかしながら、今回は元々の資産を使う(.pugファイル)を使用するために、
input へ index.pug の位置を明示してあげないといけませんでした。
index: new URL('src/index.pug', import.meta.url).pathname
注意事項:
rollup.jsはあくまでファイルのバンドラー(一つにまとめるまめのツール)なので、rollup.js自体はpugのコンパイルは行なっていなく、
pugファイルのコンパイル結果(htmlソース)に記載されているjsファイルを読み込んでいる記述をもとに
jsファイル(今回は .tsファイル)をバンドル・コンパイルしています。
ここでpugファイルを登録しているのは、プラグインで pug->html へのコンパイルを行うのに明示しないといけないためです。
コンパイルによる結果について
トップページの index.pug の設定を終えたのち、buildコマンドを実行すると、次の問題が出てきます。
js, cssファイルの名前違う問題です。
Viteのデフォルトでは、
root配下にある(publicフォルダ内を除く)js, cssファイルを htmlが記載されているファイル(今回はpugファイル) で読み込んでいる場合、
自動的に検出され、index-[hash].js, index-[hash].cssという形でコンパイルされ、assets直下に吐き出されます。
元々の環境に合わせたいので、
jsファイルは assets/scripts/app.js に
cssファイルは assets/styles/app.css に
変換したいので、出力設定を行わないといけませんでした。
rollupOptions.output への設定
JSファイルのファイル名を変更する
jsファイルの名前を変更するにあたって、input へ変換対象であることを明示する必要があります。
なので、input へ kv形式で追加する必要があります。
js: new URL('src/assets/script/index.ts', import.meta.url).pathname
jsファイルの名前を変更するにあたって、output で jsファイルを検知するためには、
entryFileNamesで input で設定(エントリー)した key をもとに変換する必要があります。
input にはhtml(pug)ファイルも登録されていますが、
実際にこの中で処理されるのは、js もしくは jsライク(.jsx, .mjs, .ts等) なファイルのみが変換対象となります。
jsファイル名変換の設定方法
rollupOptions: {
input: {
'js': new URL("src/assets/scripts/index.ts", import.meta.url).pathname,
...
},
output: {
entryFileNames: (chunkInfo) => {
// chunkInfo.name には input 設定した key が落ちてきます。
// js という key の時は "app.js" というファイル名に変更
// それ以外は key を使ってファイル名を設定
// /(スラッシュ)で区切ると出力先である dist のなかにディレクトリを作成することができます。
if (chunkInfo.name == 'js') {
return 'assets/scripts/app.js'
}
return 'assets/scripts/[name].js'
}
}
}
chunkInfo には name だけではなく他の情報も設定されていて、rollup.js より確認していただけます。
rollup.js: output.entryFileNames
CSSファイルのファイル名を変更する
cssファイルのファイル名を変換するためには、input への登録は必要ありません。
htmlファイルを読み込んだ際に、
src配下のcssに関するファイル(今回はstylusを使用しているので .stylファイル)が読み込まれている場合、
自動で検知してcssファイルにコンパイルしてくれるからです。
例 ) link(rel='stylesheet' href='/assets/styles/index.styl')が pugファイル内に記述されている場合、cssファイルへコンパイルされる。
上記の記述を検知するには、jsファイルは entryFileNames でしたが、
cssファイルの時はassetFileNamesを使用します。
これを使用した場合、cssファイルだけでなく、コンパイル結果のhtmlファイル、画像ファイルなど全ての読み込みファイルをに関してを操作できます。
しかしながら、publicフォルダ配下のファイルは検知してくれません。
jsファイル名変換の設定方法
rollupOptions: {
input: ...,
output: {
entryFileNames: ... ,
assetFileNames: (assetInfo) => {
const {name} = assetInfo
// 今回は name にはファイル名が入ってくるので、ファイル名の拡張子によってディレクトリを分け、cssファイルの名前を変更していきます。
// [] を使い name を括ると拡張子がなくなったファイル名を取得できます。
// [extname] は .(ドット) 付き拡張子を取得できます。
// [name][extname] == name になります。
if (/\.(jpe?g|png|gif|svg)$/.test(name ?? '')) {
return 'assets/images/[name][extname]';
}
// cssファイルが来たときにはファイル名を「app.css」に変換する
// このサイトでは全てのページで1つのcssファイルを参照しているので、ファイルが別の内容で上書きされることを想定していません。
if (/\.css$/.test(name ?? '')) {
return 'assets/styles/app[extname]';
}
return 'assets/[name][extname]';
}
}
assetInfo には name だけではなく他の情報も設定されていて、rollup.js より確認していただけます。
rollup.js: output.assetFileNames
ここでは画像とcssファイルのみの設定ですが、他にも読み込ませているファイルによってディレクトリを切る設定しても問題ないと思います。
最終的なconfigファイル内容
Viteのデフォルトの環境から
index.html を pugファイルに変更して srcディレクトリに移動し、
publicディレクトリを srcディレクトリに移動し、
元々のソースファイルを srcディレクトリに置いて、
下記の vite.config.js を利用することで、
目指すべきディレクトリ構成と、凄まじいまでのコンパイル速度を手に入れることができました。
import vitePluginPug from "./plugins/vite-plugin-pug";
export default defineConfig(({ mode }) => {
return {
root: "src"
publicDir: true,
build: {
modulePreload: {
polyfill: true
},
outDir: "dist",
emptyOutDir: false,
copyPublicDir: "public",
rollupOptions: {
input: {
'js': new URL("src/assets/scripts/index.ts", import.meta.url).pathname,
'index': new URL("src/index.pug", import.meta.url).pathname,
'about': new URL("src/about/index.pug", import.meta.url).pathname,
},
output: {
entryFileNames: (chunkInfo) => {
const {name} = chunkInfo
if (name == 'js') {
return `assets/scripts/app.js`
}
return `assets/scripts/[name].js`
},
assetFileNames: (assetInfo) => {
const {name} = assetInfo
if (/\.(jpe?g|png|gif|svg)$/.test(name ?? '')) {
return 'assets/images/[name][extname]';
}
if (/\.css$/.test(name ?? '')) {
return 'assets/styles/app[extname]';
}
return 'assets/[name][extname]';
}
}
},
},
plugins: [
vitePluginPug({
mode
})
},
}
});
まとめ
今回環境を載せ替えるにあたって、
元々のサイト構成が静的なページで構成されていてページ数が少なく、シンプルな作りだったことが幸いして、
載せ替えが実現できました。
これがもし動的サイトであったり、特殊な構造であった場合このように進めることができなかったのではと思いました。
単純に静的なページのサイトを作る分にはとても有用な感じがします。
今回の件で、script要素の type="module" について疑問に思ったことで書いた記事もあるので、
合わせて確認していただければと思います。
rollup.js がベースとして使われることが多くなったのではと思います。
astro も Vite をベースにしているので、根幹としては rollup.js を使用しています。
rollup.js と仲良くなれれば、さらに世界が広がる気がします。