nuxt3でログ出力したいとき、provideを活用するといいのでは?というのを思ってtry中です.
期待すること
将来的にOSSのログモジュールを使用することになっても変更が最小で済むこと。
またはログをバックエンドに送る場合にも変更が最小で済むこと。
(pageやcomponentといったロガーの使用者側に影響がないこと)
実装
provide
// /plugins/logger.ts
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal'
/** 公開される型 */
export interface ILogger{
  debug(...obj: any[]): void
  info(...obj: any[]): void
  warn(...obj: any[]): void
  error(...obj: any[]): void
  fatal(...obj: any[]): void
  /** logLevelの変更 */
  setLevel(level: LogLevel):void
  /** 現在のlogLevelの取得 */
  getLevel(): LogLevel
}
/** インターフェースの実装は公開されない */
abstract class BasicLogger implements ILogger{
  private level:LogLevel = 'info'
  private whiteList:Set<LogLevel> = new Set<LogLevel>(['info', 'warn', 'error', 'fatal'])
  
  constructor(level:LogLevel = 'info') {
    this.setLevel(level)
  }
  getLevel(): LogLevel {
    return this.level
  }
  setLevel(level: LogLevel): void {
    this.level = level
    switch (this.level){
      case 'debug':
        this.whiteList = new Set<LogLevel>(['debug', 'info', 'warn', 'error', 'fatal'])
        return
      case 'info':
        this.whiteList = new Set<LogLevel>(['info', 'warn', 'error', 'fatal'])
        return
      case 'warn':
        this.whiteList = new Set<LogLevel>(['warn', 'error', 'fatal'])
        return
      case 'error':
        this.whiteList = new Set<LogLevel>(['error', 'fatal'])
        return
      case 'fatal':
        this.whiteList = new Set<LogLevel>(['fatal'])
        return
    }
  }
  debug(...obj: any[]): void {
    if (this.whiteList.has('debug')){
      this.log('debug', obj)
    }
  }
  info(...obj: any[]): void {
    if (this.whiteList.has('info')){
      this.log('info', obj)
    }
  }
  warn(...obj: any[]): void {
    if (this.whiteList.has('warn')){
      this.log('warn', obj)
    }
  }
  error(...obj: any[]): void {
    if (this.whiteList.has('error')){
      this.log('error', obj)
    }
  }
  fatal(...obj: any[]): void {
    if (this.whiteList.has('fatal')){
      this.log('fatal', obj)
    }
  }
  abstract log(logLevel: LogLevel, ...obj:any[]): void
}
/** インターフェースの実装は公開されない */
class ConsoleLogger extends BasicLogger{
  constructor(logLevel: LogLevel) {
    super(logLevel)
  }
  log(logLevel: LogLevel, ...obj: any[]): void {
    // 
    // productionではログ出力しないなど
    // 
    switch(logLevel){
      case "fatal":
        console.error(logLevel, obj)
        return
      case "error":
        console.error(logLevel, obj)
        return
      case "warn":
        console.warn(logLevel, obj)
        return
      default:
        console.log(logLevel, obj)
        return
    }
  }
}
export default defineNuxtPlugin(nuxtApp => {
  const logger: ILogger = new ConsoleLogger('debug')
  return {
    provide: {
      logger: logger
    }
  }
})
page側
<setup lang="ts" setup>
const {$logger} = useNuxtApp()
$logger.debug("message")
</setup>