@pika/webを使って.vueファイルをwebpackなしで使ってみる

UI開発者 板垣

この記事はミツエーリンクスアドベントカレンダー2019 - Qiitaの21日目の記事です。

みなさんは@pika/webをご存じでしょうか。
@pika/webを使うと、コマンド1つでnpmパッケージとそのパッケージのESM依存関係にあるパッケージをローカル上にインストールして、それらをブラウザで直接実行できるようにようになります。
つまり、これまでwebpackやrollupなどのバンドルツールで行ってきたESMの依存関係解決を@pika/webが担ってくれるのです。
詳しいことは公式の説明を見ていただくとして、この@pika/webを使うとVue.jsの単一ファイルコンポーネント(以下、SFC)を簡単に使うことができると目にしたので、今回はその方法をご紹介します。

※@pika/webはバージョン1がリリースされる際に「Snowpack」という名前に変更されることがGitHubでアナウンスされていますので、気になっている方はご注意ください(現時点でのバージョンは0.6.1)。

環境構築

環境構築といってもwebpackのような複雑な設定は必要ありません。
いくつかのコマンドと、少しの記述だけで十分です。

package.jsonの作成

npm init -y

@pika/webのインストール

npm i -D @pika/web

vue.jsとhttp-vue-loaderをインストール

npm i -S vue http-vue-loader

Vue.jsとは別に.vueファイルを使用するために必要なhttp-vue-loaderをインストールします。

package.jsonにコマンドと@pika/webのオプションを記述

...
  "scripts": {
    "pika": "pika install"
  },
...
  "@pika/web": {
    "webDependencies": [
      "vue/dist/vue.esm.browser.js",
      "http-vue-loader/src/httpVueLoader.js"
    ]
  }
}

@pika/webはwebDependenciesオプションを使用することによって、インストールするパッケージ指定できます。このオプションがない場合、依存関係にあるすべてのパッケージがインストールされてしまうので注意が必要です。

モジュールのインストール

npm run pika

コマンドを実行すると、「web_modules」というディレクトリが生成されその中にwebDependenciesオプションで指定したモジュールがインストールされます。これで環境構築は終了です。

各ファイルの作成

components
├ package.json
├ package-lock.json
├ node_modules
├ web_modules
├ js
| └ App.js
├ src
| ├ app.vue
| └components
|     └ hello.vue
└ index.html

上記のディレクトリ構造になるようにファイルを作成してください。

/js/App.js

import Vue from '/web_modules/vue/dist/vue.esm.browser.js';
import vueLoader from '/web_modules/http-vue-loader/src/httpVueLoader.js';

Vue.use(vueLoader);

new Vue({
    el: '#app',
    components: {
        'app': 'url:/src/app.vue'
    },
    template: '<app></app>'
});

App.jsにはVue.jsの設定を書き込んでいきます。

Vue.use(vueLoader);という記述は、http-vue-loaderをプラグインとして実行しています。
こうすることで、コンポーネントを使う度にhttp-vue-loaderのメソッドを呼び出す必要がなくなり、URIの先頭に「url:」と付けるだけでコンポーネントが使えるようになります。

src/app.vue

<template>
    <div>
        <hello></hello>
    </div>
</template>

<script>
module.exports = {
    components: {
        hello: 'url:/src/components/hello.vue'
    }
};
</script>

最初にマウントされるファイルです。好きなようにカスタマイズしてください。

/components/hello.vue

<template>
    <div>
        <p>Hello {{msg}}!</p>
    </div>
</template>

<script>
module.exports = {
    data () {
        return {
            msg: 'Vue.js'
        };
    }
};
</script>

テキストが表示されるだけのコンポーネントです。
module.exportsの中身は通常のSFCと同じように書くことができます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="module" src="/js/app.js"></script>
</head>
<body>
<div id="app">
    <hello></hello>
</div>
</body>
</html>

読み込んでいるスクリプトにtype="module"が付いていることに注意してください。
この記述がないと、ESMのインポートなどが行えないためエラーが発生します。

完成

最後に適当なローカルサーバーで、作成したファイルを確認してみましょう。

Hello Vue.js!

お疲れ様でした!

おわりに

今回@pika/webを使ってVueのSFCに挑戦してみましたが、この他にもさまざまな用途で使えそうです。
その他の用途が見つかり次第、このブログで紹介いたしますので楽しみにしていてください。