なぽろぐ

気ままに感じたことを記事にまとめます。

Next.js で Babylon.js を扱う

Next.js と Babylon.js とwebGL が全く分からない俺

分からないので動かしたかった.バンドラーとして Next.js つかったら next.config.js 書かなきゃ動かなかったので備忘録的に文字に起こしておきます.

Babylon.js を動かす

babylonjs で npm ライブラリも公開されているが nextjs だと動かないので @babylonjs/core を使用する

yarn add -D next-transpile-modules next-compose-plugins
yarn add @babylonjs/core
const withTM = require('next-transpile-modules')(['@babylonjs/core']);
const withPlugins = require('next-compose-plugins');

const nextConfig = {
  /* 任意の config */ 
}
module.exports = withPlugins([
  [withTM],
], nextConfig);

これだけで build ができるようになります. next-transpile-module が必要なのは @babylonjs/core の js ファイルが es6 import を使用してるからです.@babylonjs/core を install したあとに node_modules をみてみるとわかると思います.

shader ファイルを raw-loader で読む

.glsl, .vert, .frag ファイルを raw-loader で string として読み込んで使えるようにします. next.config.js は babylonjs を使えるようにしたものを拡張しています.

yarn add -D raw-loader glslify-loader
const withTM = require('next-transpile-modules')(['@babylonjs/core']);
const withPlugins = require('next-compose-plugins');

const nextConfig = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.(glsl|frag|vert)$/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: "raw-loader"
        },
        {
          loader: "glslify-loader"
        },
      ],
      exclude: /node_modules/,
    });
    return config;
  }
}

module.exports = withPlugins([
  [withTM],
], nextConfig);

import fragment from "./fragment.frag" としたときに fragment が string になるように typescript の型定義も追加しておきます.

declare module "*.vert" {
  declare const value: string;
  export default value;
}

declare module "*.frag" {
  declare const value: string;
  export default value;
}

declare module "*.glsl" {
  declare const value: string;
  export default value;
}

以上です.もしこれで動いたならばうれしいです.

wsl2 で docker が起動できないときにすること

wsl2 環境を用意したがdockerコマンドが動かないとき

f:id:Naporitan:20210104111738p:plain

こういうパターンの時です.

解決策

このissueに書かれている通り wsl --unregister docker-desktop を行います. github.com

f:id:Naporitan:20210104111806p:plain

bug アイコンを押すと restart docker desktop という項目が出てくるので restart します

以上の手順を踏むと docker コマンドを実行できます.

おわり.やっとまともに wsl2 をつかえる

Nextjsでsvgをインラインで読み込んでreact componentとして使う

Nextjsでもsvgをreact componentで使いたい

素のreactのプロジェクトだとこれ使ってパチッとやってたやつをNextjsでもやりたいってやつです. github.com

次のように書ければ目的達成という感じです.

import Icon from "~/assets/icons/icon.svg"
export const Component = () => {
  return (
    <Icon />
  )
}

Nextjs用のライブラリがあるですね~.うれしい.これを使うだけなのですが,next-imagesを併用してると動かないときもあるのでメモしておこうと思います. github.com

next-react-svg と next-images を併用する

next-images"jpg", "jpeg", "png", "svg", "gif", "ico", "webp", "jp2", "avif" の拡張子を含むファイルをすべて url-loader 通しちゃうので next-react-svg を使っていても svg は url 形式になってしまいます.なので次のようにnext-react-svgがincludeしてるpathnext-imagesではexcludeするという処理をすれば動きます.

next-compose-pluginswithXXXに対応するconfigを見やすく記述することができるpluginなのでいれています.

const { withPlugins } = require("next-compose-plugins")
const withImages = require('next-images')
const withReactSvg = require("next-react-svg")
const path = require('path')

const nextCofig = {
  / * someconfig .... */
  webpack(config) {
    config.resolve.alias['~'] = path.resolve('src')

    return config
  }
}

module.exports = withPlugins([
  [withImages, {
    exclude: path.resolve(__dirname, "src/assets/icons")
  }],
  [withReactSvg, {
    include: path.resolve(__dirname, "src/assets/icons")
  }]
], nextConfig)

typescriptを使う人向けにsvgの型定義を置いておきます.~/assets/icons/*.svgからimportするときはComponentで読み込んでほしいので次のようにどこかに記述して置けれいいはずです.

declare module '*.svg'
declare module '~/assets/icons/*.svg' {
  const value: React.FunctionComponent<React.SVGAttributes<SVGElement>>

  export = value
}

これで次のような記述をすることでsvgをcomponentとして扱うことができます.

import Icon from "~/assets/icons/icon.svg"
export const Component = () => {
  return (
    <Icon />
  )
}

2021年のカレンダーを買いました

購入したカレンダー

booth.pm

ひそなさんのサークルsuoiretsymでカレンダーを買い続けて5年目となりました!2016年から買い続けているのでこの時期(紅楼夢から12月あたり)になると毎年ワクワクしながら待ってます.

このカレンダーのおかげで毎月の変わり目がとても楽しくなります. 僕はその月にならないとカレンダーを絶対めくらない縛りをしてて,それがカレンダーの僕なりの楽しみ方だからですね~

f:id:Naporitan:20201225022136j:plain

すべて保管してるんですが,2016年の記憶もちょっとよみがえってきていいですね......毎年カレンダーを作ってくださっているひそなさんに感謝です:pray:本当に毎年の楽しみになっています!!!!

よく使いそうなtemplate-literal-typesを使った型定義

いつもTSのPlaygroundで作ってるなぁと思うやつをメモする

下に書いてあるやつすべてplaygroundで実行しているやつ

www.typescriptlang.org

splitの型定義

// 文字列を受け取って受け取ってその文字列をDelimiterでsplitする型
type Split<T, U extends string> = T extends string
                                    ? T extends ""
                                      ? []
                                      : T extends `${infer Head}${U}${infer Tail}`
                                        ? [Head, ...Split<Tail, U>]
                                        : [T]
                                    : []
type UseSplit1 = Split<"aaaaaa", ""> // 1文字づつ区切る
type UseSplit2 = Split<"abababab", "b"> // 特定文字で区切る
type UseSplit3 = Split<"a,b,c", ","> // csv的なやつ

nestしたobjectのkeyを列挙する型定義

// nestしたオブジェクトのkeyをすべて列挙する型
// json to csv的なやつに使えそうかも
type NestObjectKeys<T, D extends string = "."> = {
  [K in keyof T]: K extends string ? T[K] extends Record<string, unknown> ? `${K}${D}${NestObjectKeys<T[K], D>}` : K : never
}[keyof T]

const obj1 = {
  a: 1,
  b: null,
  c: "c",
  d: {
    a: 1,
    b: undefined,
    c: "dc",
    d: {
      a: 2,
      b: null,
      c: "ddc"
    }
  }
} as const
type Keys1 = NestObjectKeys<typeof obj1> // objectのkeyを.でつなげる
type Keys2 = NestObjectKeys<typeof obj1, "-"> // 特定の文字でつなげる

よくあるrouterライブラリのpath文字列を型に落とし込む型定義

// あるあるのrouterライブラリのpath文字列を型に落とし込む型
type AnalyzePath<T> = T extends string
                      ? T extends `/${infer Head}/${infer Tail}`
                        ? Head extends `:${infer U}`
                          ? { [K in U]: string } & AnalyzePath<`/${Tail}`>
                          : AnalyzePath<`/${Tail}`>
                        : T extends `/:${infer U}`
                          ? { [K in U]: string }
                          : {}
                      : {}
type AnalizedPath1 = AnalyzePath<"/users/:user_id/">
type AnalizedPath2 = AnalyzePath<"/users/:user_id/tweets/:tweet_id">

Nextjsのpath文字列を型に落とし込む型

これ型に落とし込めてもnextjsはfsでroutingされているからあまり意味ないんだよなぁと言うのが最近の悩み。ずっと考えてるけどいい方法思いつかないなぁ.....next.config.jswithXXXコンパイラをいじったりしていい感じにするとかかなぁ....わかりません

// Nextjsのpath文字列を型に落とし込む型
type AnalizeNextJSPath<T> = T extends string
                            ? T extends `${infer Head}[${infer U}]${infer Tail}`
                              ? U extends `...${infer U1}`
                                ? { [K in U1]: string[] } & AnalizeNextJSPath<Tail>
                                : { [K in U]: string } & AnalizeNextJSPath<Tail>
                              : {}
                            : {}
type AnalizedNextJSPath1 = AnalizeNextJSPath<"/users/[id]/">
type AnalizedNextJSPath2 = AnalizeNextJSPath<"/users/[id]/directory/[...directories]/">

snake caseをcamel caseにする型

// snake case to camel case
type SnakeToCamel<T> = T extends string
                        ? T extends `${infer Head}_${infer Tail}`
                          ? `${Lowercase<Head>}${Capitalize<Tail>}`
                          : never
                        : never
type UseSnakeToCamel = SnakeToCamel<"user_id" | "tweet_id">

camel caseをsnake caseにする型

// camel case to  snake case
type CamelToSnake<T> = T extends string
                        ? T extends `${infer Head}${infer Tail}`
                          ? Head extends Uppercase<Head>
                            ? `_${Lowercase<Head>}${CamelToSnake<Tail>}`
                            : `${Head}${CamelToSnake<Tail>}`
                          : T
                        : never
type UsecCamelToSnake = CamelToSnake<"userId" | "tweetId">

まとめ

便利ですね。template-literal-types。一生遊べる

ここ1年で買ってよかったものシリーズ

買ってよかったものシリーズ2020

1. ルンバi7

store.irobot-jp.com

最近買ったけどこれが最高すぎる。起動1、2回目までは30分くらい掃除してるんですが3回目くらいからは15分くらいで掃除してくれます。音は結構大きい。ルンバに掃除させながらAPEXをやると何も聞こえなくて普通に背後に寄られて死ぬのが容易になる。まぁ普通に掃除機なのでそれはそうだね。

地形を覚えてくれて仕切りを自分で設定して仕切りごとに掃除できる。これが便利〜〜〜いいね

f:id:Naporitan:20201201180602p:plain

2. hue

www.philips-hue.com

正社員になってからコロナの影響でフルリモートだったので気持ちの切り替えが大変だったんですが、これで割と僕は解決しました。始業時間と就業時間になったらライトの色を変えるように設定していたのでスパッとモード切替できてよかった〜。これもおすすめ。Amazon Echoとの相性もとてもいい。最高

3. ウォーターサーバー

premium-water.net

ウォーターサーバー自体はどこでもいいじゃないかと思ってるけど僕はこれ使ってます。温水と冷水が常に出てくるのはめちゃくちゃいいですね〜。東京は想像以上に水道水が飲めたものじゃないのでこれがあると家がペットボトルまみれにならないのが最高です。まじでいい。ごみ捨てが楽になるので。

4. webカメラ

www.logicool.co.jp

別にストリーマーってわけじゃないけど無駄にいいカメラを買った。カメラは最高すぎる。自分の顔を移したいわけじゃないが高画質のwebカメラはいろいろな遊び道具になるからね。いいもの!

5. マイク・オーディオインターフェース(これは前から持ってた)

www.marantzpro.jp

フルリモートだったのでMTGすべてがオンラインだったので聞こえづらいとか相手の耳障りにならないようにコンデンサーマイクを買いました。オーディオインターフェースがあるとハードウェアミュートがあるので色々便利ですよ。ミュートマークが出ずにミュートできるので〜

さいごに

今年も色々買った。AirPods ProとかMacBookProもかったけどフルリモートという関係上あまり効力を発揮せずランクインならずって感じです。ほと〜〜〜〜んど家にいたからね。来年は椅子とディスプレイを買いたいです。あとキーボードかな〜キーボード。ゴミ箱からひろってきたHHKBを漂白して使ってるのでそろそろ新品をね......