npm
TypeScript
vue.js
webpack

Vue.js + TypeScript + webpack + npm v5でローカルフォルダをinstallしてハマった話

試行錯誤してみたものの根本解決に至らなかったので、ひとまず記録として書き残します。

何をしたのか?

  • vue-cliのwebpackでローカルに汎用コンポーネント用プロジェクト作成
  • Vue.js + TypeScriptで汎用コンポーネント作成
  • buildの際、webpackの設定でVueを外部依存ライブラリに指定してバンドル
  • 別のVueプロジェクト(以降は親プロジェクトと表記)で「npm install ローカルフォルダ」
  • installしたコンポーネントをimportして使用した

何が起きたか?

  • npm run devするとブラウザのコンソールログにエラーが発生
  • Unknown custom elementとか$attrさわんな!とかボコボコに怒られた
  • ログをよくよく見ると、どうも親プロジェクトのvue.esm.jsと汎用コンポーネントプロジェクトのvue.esm.jsがどちらも実行されているらしい

試したこと

  • Vue.js単独で汎用コンポーネント作成、親プロジェクトでの使用はエラーにならなかった
  • buildした場合はエラーが発生しなかった

調べたこと

  • npmはローカルフォルダをinstallするとシンボリックリンクを張る
    • バージョン3以前は親プロジェクトのnode_modulesにコピーしていた(普通のパッケージをinstallするのと同じ挙動)
  • Vue.js + TypeScriptの場合、Vue.extendするにしろvue-class-componentを使うにしろ、import Vue from "vue"は必須
    • バンドルされたjsの中をのぞいてみると、冒頭にrequire("vue")のコードあり
    • 外部依存の設定はしていてもvue.esm.jsへの参照が残ってしまう?

推測したエラー発生への流れ

  1. 親プロジェクトのvue.esm.jsが実行される
  2. 汎用プロジェクトのバンドルされたjsを読み込む
  3. バンドルされたjsの中のrequire('vue')が、親プロジェクトではなく汎用プロジェクトのnode_modulesのvue.esm.jsをrequireしてしまう
  4. vue.esm.jsが多重起動してしまいエラー

暫定対応

  • install-localモジュールを使用し、親プロジェクトのnode_modulesに汎用プロジェクトを直接コピーした

課題

  • 最低限の再現性あるプロジェクトを作成してgithubに上げたい
  • webpackでバンドルしたjsを解析してみたい
  • webpackの設定やプラグインで回避できそうな気もするので調べたい

もし解決策をご存知の方はコメントしていただけると大変ありがたいです。