Vue コンポーネントを作って npm で公開する

この内容は知見が貯まると共に変更になる可能性が大です。また Vue の最新がvue@2.6.10、Nuxt の最新がnuxt@2.8.0の時に書いています。

Vue コンポーネントを作って公開するおおよその流れは以下のような感じです。

  1. *.vueファイルを実装
  2. *.vueを Rollup を使ってビルド
  3. 生成されたファイルを npm で公開

ちなみに TypeScript とyarnを使っていきます。

*.vue ファイルを実装

まずは僕的に必要なパッケージをインストールします。必要なものは vuevue-property-decorator そして typeScript です。

yarn add -P vue@^2.6.0
yarn add -D \
  vue \
  vue-property-decorator \
  typescript

そしたら軽く*.vueを1つ作ります。src/index.vue辺りに、

<template>
  <div>
    <h1>{{message}}</h1>
  </div>
</template>

<script lang="ts">
import {Component, Vue} from 'vue-property-decorator';
 
@Component
export default class extends Vue {
  public message = 'hello';
}
</script>

<style>
h1 {
  color: orange;
}
</style>

とりあえず現在は対応が不十分のようなのでスタイルのスコープ機能は使わないようにするといいと思います。

*.vueを Rollup を使ってビルド

Webpack よりこちらのほうが出力コードが少ないです。その設定ファイルrollup.config.jsはこんな感じです。

import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
import cssOnly from 'rollup-plugin-css-only';
import vue from 'rollup-plugin-vue';

export default {
  input: 'src/index.vue',
  external: ['vue'],
  plugins: [
    nodeResolve(),
    commonjs(),
    typescript({
      clean: true,
      objectHashIgnoreUnknownHack: true,
    }),
    cssOnly(),
    vue({css: false}),
  ],
};

上2つは環境によって変わります。typescriptのオプションはエラーを回避する為にこうなった的な感じです。下2つは今回のやり方では必須です。必要なプラグインはdevDependenciesに追加するかyarn add -Dが必要なので忘れずに。

下2つはvue({css: false})によって「JavaScript で<style>を作り Dom に挿入しなくていい」と設定しています。これはブラウザでのみ実行が想定するファイルを作る事になってしまうため、Nuxt などでエラーを起こしてしまいます。

`vue({css: true})`のエラー

実は今vue({css: false})により「*.cssということで扱う」(ソースコード中にimport '*.css'で使った)という意味にできています。この*.cssを抜き出し.cssファイルを作ってくれるのがrollup-plugin-css-onlyプラグインです。

さて Rollup の設定ファイルができたのであとは以下のようなコマンドで変換します。

rollup -c rollup.config.js --sourcemap --format esm --file dist/module/index.js

これは--format esmなので ES Module でdist/index.jsに吐き出されると思います。その時にindex.cssも同じディレクトリに存在すればうまくいってます。
同じように--format cjs --file dist/main/index.jsなどで CommonJS や他必要なものを生成します。

生成されたファイルを npm で公開

生成ファイルがちゃんとインストール先で読まれるようにpackage.jsonを編集します。

{
  "name": "vue-xxx",
  "main": "dist/main/index.js",
  "types": "typescript の型へのパス",
  "module": "dist/module/index.js",
  "source": "src/index.vue",
  "browser": "ブラウザ用にビルドしたファイルへのパス",
  "style": "dist/module/index.css"
}

nameには好きな名前を置きます。ただvue-とプレフィックスは付けたほうがいいと思います。あとはyarnで上げるだけです。

yarn publish
# 上によってコミットされたものを `git push`

メモ

CSS も JavaScript で挿入する形で最初考えていて、いろいろ試した結果_vm._ssrEscape is not a functionというエラーが出るまでは行きました。恐らく今度はサーバーサイドでは動いていてブラウザサイドで動かなくなった形な気はしましたがそこで力尽きました。