投稿者「araken」のアーカイブ

ToutchDesignerで、指定フレーム後にスクリプト実行する

動作環境

サンプルコード

run("op('text1').run()",delayFrames=60)

このサンプルでは、text1 DATを60フレーム後に実行する動作になります。第1引数で、文字列として実行するスクリプトを与え、第2引数で遅延させるフレーム数を指定します。

1フレーム内で実行する処理を分散する時やタイミングをずらし描画をスタートする時などに便利です。

nuxt.config.jsに、dotenvの環境変数を反映させる

.envファイルに設定した環境変数をnuxt.config.jsでも反映される方法。firebaseなどのプラグインを設定するときに、便利。

動作環境

.env.* ファイル

各環境毎の.envファイルをつくる。

your-app
|-- .env.development 開発サーバ用
|-- .env.local       ローカル開発用
|-- .env.production  本番サーバ用
`-- package.json

例えば、次の様な環境変数を設定する

FIREBASE_API_KEY="*****************"
FIREBASE_AUTH_DOMAIN="*****************.firebaseapp.com"
FIREBASE_PROJECT_ID="*****************"
FIREBASE_STORAGE_BUCKET="*****************.appspot.com"
FIREBASE_MESSAGING_SENDER_ID="*****************"
FIREBASE_APP_ID="*****************"
FIREBASE_MEASUREMENT_ID="*****************"

nuxt.config.js

nuxt.config.js内で、.env.*ファイルで設定した環境変数を読み込むには、以下の設定を冒頭の2行に加える。

// ...
const envPath = `.env.${process.env.NODE_ENV || 'local'}`
const envSet = require('dotenv').config({ path: envPath })

// ...

export default defineNuxtConfig({

//..

})

nuxt.config.js内から、次の様な形で環境変数を読み込める。

//..

export default defineNuxtConfig({

//..

  firebase: {
    config: {
      apiKey: process.env.FIREBASE_API_KEY,
      authDomain: process.env.FIREBASE_AUTH_DOMAIN,
      projectId: process.env.FIREBASE_PROJECT_ID,
      storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
      messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
      appId: process.env.FIREBASE_APP_ID,
      measurementId: process.env.FIREBASE_MEASUREMENT_ID
    },
    services: {
      auth: true,
      firestore: true,
    },
  },

//..

package.json

dotenvとcross-envを組み合わせて、以下の様なスクリプトを組む

// ..

    "generate:prod": "cross-env NODE_ENV='production' nuxt generate",
    "generate:dev": "cross-env NODE_ENV='development' nuxt generate",

// ..

NODE_ENVの引数で、開発環境を指定する

node.jsのインストール先を知る方法

fnmでパッケージ管理しnode.jsをインストールしている際などに、インストール先を知る方法。

動作環境

コマンド実行例

% npm bin -g

/Users/USER_NAME/Library/Application Support/fnm/node-versions/v16.17.0/installation/bin

windows環境やnfm下で管理していてwhichコマンドでインストール先を調べれらないときに便利です。

※Mac, Windowsでも使えます

Nuxt(Vue)の<template>でエラーが出る

VS Code上で、<template>でエラーが出る場合、tsconfig.jsonの設定を変更

動作環境

*.vue

1行目の<template>でエラーが出る

tsconfig.jsonの設定

以下の設定を追加する

{
  "compilerOptions": {
    ...
    "jsx": "preserve",
    ...
    "vueCompilerOptions": {
      ...
      "experimentalDisableTemplateSupport": true
    },
}

配列やオブジェクトを更新しても、画面が更新されない

Nuxt/Vueでリアクティブな配列やオブジェクトを更新しても、Template側が更新されない場合の対処方法

基本的な内容は公式ドキュメントにも掲載されている
https://jp.vuejs.org/v2/guide/reactivity.html#%E5%A4%89%E6%9B%B4%E6%A4%9C%E5%87%BA%E3%81%AE%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85

反映されない例(失敗例)

state.items[indexOfItem] = newValue

配列のインデックスを直接指定して、値を更新しても、画面は更新されない。もしくは、遅延が起こる。

反映される例(成功例)

Vue.setを使って、配列かオブジェクトを更新する。

import Vue from 'vue'
...
Vue.set(state.items, indexOfItem, newValue)

this.$setで、更新することもできる。

Nuxt.jsでSpotifyのoEmbed APIをプラグイン化

Spotifyでは、oEmbedの方法で、未ログインでも再生ができるWEB向けのiFrameプレイヤーをAPIから取得できる。これをNuxt.jsのプラグイン化する方法。

通常、iFrameのURLをHTMLに記述してプレイヤーを埋め込むが、そのiFrameの内容をJSON形式でも取得できる。

動作環境

通常のiFrame

<iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/25Wlc36nhO0sd8mNOQbOv1?utm_source=generator" width="100%" height="380" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe>

このようHTMLを埋め込むと、

と、表示される。

取得API

既出のiFrameのソースコードをこのAPIで取得可能

https://open.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Fplaylist%2F{id}

{id}の部分をプレイリストのIDを指定する。

取得結果

{
  html: "<iframe style="border-radius: 12px" width="100%" height="380" title="Spotify Embed: 昼の放送 #27" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" src="https://open.spotify.com/embed/playlist/25Wlc36nhO0sd8mNOQbOv1?utm_source=oembed"></iframe>",
  width: 456,
  height: 380,
  version: "1.0",
  provider_name: "Spotify",
  provider_url: "https://spotify.com",
  type: "rich",
  title: "昼の放送 #27",
  thumbnail_url: "https://mosaic.scdn.co/300/ab67616d0000b273115c265fae60f66103a965c9ab67616d0000b2736dba235db4ccbec24606f0d9ab67616d0000b273bf6bcb4f1d2c4c49e67d6999ab67616d0000b273d6c059712a4916f1b278405a",
  thumbnail_width: 300,
  thumbnail_height: 300
}

実装的には、プレイリストのタイトル、サムネイル画像のURLを取得できる点が便利。

プラグイング化

import { Plugin } from '@nuxt/types'
import { NuxtHTTPInstance } from '@nuxt/http'

class SpotifyEmbed {
  http: NuxtHTTPInstance

  constructor(http: NuxtHTTPInstance) {
    this.http = http
  }

  /**
   * iFrameを取得
   * @param id spotifyのプレイリストのid
   * @returns
   */
  public async get(id: string): Promise<any> {
    try {
      return await this.http.$get(
        `https://open.spotify.com/oembed?url=https%3A%2F%2Fopen.spotify.com%2Fplaylist%2F${id}`
      )
    } catch (error) {
      console.log('response error', error)
    }
  }
}

export const spotifyEmbedPlugin: Plugin = (context, inject) => {
  const spotifyEmbed = new SpotifyEmbed(context.app.$http)

  inject('spotifyEmbed', spotifyEmbed)
}
export default spotifyEmbedPlugin

declare module '@nuxt/types' {
  interface Context {
    $spotifyEmbed: SpotifyEmbed
  }
}

.vueファイルからはこういう形で使う

<script lang="ts">
...

import { useSpotify } from '@/composables/spotifyState'
import {
  defineComponent,
  ref,
  useContext,
} from '@nuxtjs/composition-api'
...

export default defineComponent({
    const { app } = useContext()
...

const spotifyId = '25Wlc36nhO0sd8mNOQbOv1'

...

  setup(props) {
    ...

    async created() {
      const searchResult = await app.$spotifyEmbed.get(spotifyId)
    }

    ...
  }
}

asyncを宣言しているメソッド内で、await で実行結果を受け取ることができる。後は、ref宣言した変数にhtml部分を入れて、テンプレート内に表示することが可能。

    const spotifyIFrame = ref({ html: '' })
      const searchResult = await app.$spotifyEmbed.get(spotifyId.value)
      spotifyIFrame.value = searchResult

Vuetifyを使ってテンプレートに表示する例

<div v-html="spotifyIFrame.html"></div>

refで初期化する際に、htmlを空白にすることで、レンダリングのエラーを回避している

Nuxt.js + TSで読み込むJSONデータの型を定義

外部API、もしくは自データのJSONをTypeScriptで型定義して読み込む方法

動作環境

JSON

次のようなJSONを読み込むとする

[
  {
    "id": "25Wlc36nhO0sd8mNOQbOv1",
    "category": "dayprogram",
    "title": "昼の放送 #27",
    "count": 12,
    "total": 3397723,
    "cassetteType": 1
  },
  {
    "id": "33ewifXD4g0t1KfiGkzSlb",
    "category": "dayprogram",
    "title": "昼の放送 #26",
    "count": 11,
    "total": 2864799,
    "cassetteType": 2
  },
  {
    "id": "3fwnwowsaDzdW6GEZuU2r2",
    "category": "dayprogram",
    "title": "昼の放送 #25",
    "count": 11,
    "total": 2441976,
    "cassetteType": 1
  }
]

JSONファイルなどを置く場所は、/data以下に置く

型指定

次にJSONに含まれる配列内のオブジェクトの型について定義する。

export interface Playlist {
  id: string
  cassetteType?: number
  category: string
  title: string
  count: number
  total: number
}

ここでは、Playlistというインターフェースを定義している。
定義されたプロパティは、基本的に必須になるが、

  cassetteType?: number

という様に、プロパティ名の後ろに?を付けると、非必須項目になり、省略することができる。

JSONと型定義の関連付け

次に、読み込まれるJSONファイルの型宣言をし、型定義と関連付けを行う。

import { Playlist } from '~/lib/playlist'

declare module '~/data/playlists.json' {
  const data: Playlist[]

  export default data
}

このJSONは、Playlist型の配列を持つJSONなので、

  const data: Playlist[]

と記述し、Playlistの配列であることを定義する。

JSONファイルのインポート

実際に、スクリプト内にJSONを読み込むには、

<script lang="ts">
...

import playlistJson from '~/data/playlists.json'

...
</script>

の様な形でインポートする。こうすることによって、IDEなどでも、定義された型で参照することができるようになる。

Cannot find module ‘#app’ or its corresponding type declarations. と言われたら

エラー内容

Cannot find module '#app' or its corresponding type declarations.

というエラーが、Nuxt Bridge(TypeScript)の開発時に、VS Codeで発生。

例えば、このようなコードでエラーが発生する

import { readonly, useState, Ref } from '#app'

動作環境

Nuxt Bridgeの導入環境

  • node 16.13.1
  • npm 8.1.2
  • nuxt-edge 2.16.0
  • @nuxt/bridge 3.0.0
  • Type Script 4.6.2
  • Visual Studio Code 1.65.2
  • Volar 0.33.2

解決策

tsconfig.jspathsを以下の様に修正

"paths": {
  "~/*": ["./*"],
  "@/*": ["./*"],
  "#app": ["./node_modules/@nuxt/bridge/dist/runtime/index.d.mts"]
},

原因

nuxiが生成する.nuxt/tsconfig.jsonで設定される#appのパスが、TypeScript用のファイルに通っていないのが原因の模様。

"#app": [
  "node_modules/@nuxt/bridge/dist/runtime/index"
],