🧤

Nuxt3に向けて、Nuxt2.xでもvue2.7を利用してscript setupを使いたい!

2022/09/29に公開

はじめに

新人フロントエンドエンジニアをしているRimlと申します。
お久しぶりです。

個人制作であるDotArtをNuxt Bridge対応しようと試行錯誤しています。

本編

  • Vue2.xが来年にはサポート切れる、ではVue3系にメジャーバージョンで対応できていないNuxtはどうすれば…
  • Nuxt Bridgeがありますが移行が大変なので更にNuxt2とNuxtBridgeの中間に移行したい…

それでも今後のNuxt3へ移行する対応がしたい、Vue3の記法(script setup)が利用したい!

そんなつらみを解消する方法にscript setupが使いたいならunplugin-vue2-script-setup を導入する、Vue2.7系を導入するという方法があります。

ですがどうせなら後者のVue2.7を使いたいと思いますよね。

結論

Nuxt-edgeに更新しましょう
yarnを利用しているためnpmやpnpmを使用している方は置き換えて実行してください。

yarnの場合

rm yarn.lock

package.json を更新する

- "nuxt": "^2.15.0"
+ "nuxt-edge": "latest"

パッケージを入れ直す

yarn install

Nuxt-edgeに上げた際のVueのバージョンを確認する

yarn list vue

2.7系になっていれば成功です

今まで通り yarn dev などで実行することが出来ます。

script setup のコンポーネントを書いてみる

Nuxt2.xを利用していてかつ、composition-apiを利用していればimport元が @nuxtjs/composition-api になっていると思います。

ですがVue2系、Vue3系と互換がある vue-demi を利用していきます。
※ Nuxt BridgeやNuxt3では #app を利用するようになるため仮利用です。

counter.vue

<script setup lang="ts">
import { ref } from "vue-demi";

const count = ref<number>(0);

const increment = (): void => {
  count.value++;
};

const decrement = (): void => {
  count.value--;
};
</script>

<template>
  <h1>{{ count }}</h1>
  <button @click="increment">Increment</button>
  <button @click="decrement">Decrement</button>
</template>

こちらの呼び出しは他コンポーネントと同じように呼び出せます。

script setupの書き方については

https://zenn.dev/azukiazusa/articles/676d88675e4e74

importは vue-demi に置き換えてこの記事を参考にすれば問題ないかと思います。

備考

コンパイラが Vue2.6 までは vue-template-compiler だったのですが、Vue2.7 から compiler-sfc に変わっています。

そのためv-deepなどをcssで利用していると

【WARN】[@vue/compiler-sfc] ::v-deep usage as a combinator has been deprecated. Use :deep(<inner-selector>) instead.

が出たりします。

その際はまずstylelint側で怒られないよう、以下を設定します。

stylelint.config.js

rules: {
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ],
    'selector-pseudo-class-no-unknown': [
      true,
      {
        ignorePseudoClasses: ['deep']
      }
    ]
  }

後は

【WARN】[@vue/compiler-sfc] ::v-deep usage as a combinator has been deprecated. Use :deep(<inner-selector>) instead.

で怒られている箇所を

<style lang="scss" scoped>
- ::v-deep .v-data-table {
+ :deep(.v-data-table) {
  white-space: nowrap;
  width: 100%;
}
</style>

のように直していきましょう。

まとめ

前バージョンが保守される破壊的更新であればまだゆったりと更新対応できますが、今回のようにそうはいかず来年にはサポートが切れるとなるとSNSで炎上している理由が納得できてしまいますね。

最後まで読んでいただきありがとうございました!

Discussion