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コマンドが動かないとき
こういうパターンの時です.
解決策
このissueに書かれている通り wsl --unregister docker-desktop
を行います.
github.com
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してるpath
をnext-images
ではexcludeするという処理をすれば動きます.
next-compose-plugins
はwithXXX
に対応する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年のカレンダーを買いました
購入したカレンダー
ひそなさんのサークルsuoiretsymでカレンダーを買い続けて5年目となりました!2016年から買い続けているのでこの時期(紅楼夢から12月あたり)になると毎年ワクワクしながら待ってます.
このカレンダーのおかげで毎月の変わり目がとても楽しくなります. 僕はその月にならないとカレンダーを絶対めくらない縛りをしてて,それがカレンダーの僕なりの楽しみ方だからですね~
すべて保管してるんですが,2016年の記憶もちょっとよみがえってきていいですね......毎年カレンダーを作ってくださっているひそなさんに感謝です:pray:本当に毎年の楽しみになっています!!!!
よく使いそうなtemplate-literal-typesを使った型定義
いつもTSのPlaygroundで作ってるなぁと思うやつをメモする
下に書いてあるやつすべてplaygroundで実行しているやつ
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.js
にwithXXX
でコンパイラをいじったりしていい感じにするとかかなぁ....わかりません
// 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
最近買ったけどこれが最高すぎる。起動1、2回目までは30分くらい掃除してるんですが3回目くらいからは15分くらいで掃除してくれます。音は結構大きい。ルンバに掃除させながらAPEXをやると何も聞こえなくて普通に背後に寄られて死ぬのが容易になる。まぁ普通に掃除機なのでそれはそうだね。
地形を覚えてくれて仕切りを自分で設定して仕切りごとに掃除できる。これが便利〜〜〜いいね
2. hue
正社員になってからコロナの影響でフルリモートだったので気持ちの切り替えが大変だったんですが、これで割と僕は解決しました。始業時間と就業時間になったらライトの色を変えるように設定していたのでスパッとモード切替できてよかった〜。これもおすすめ。Amazon Echoとの相性もとてもいい。最高
3. ウォーターサーバー
ウォーターサーバー自体はどこでもいいじゃないかと思ってるけど僕はこれ使ってます。温水と冷水が常に出てくるのはめちゃくちゃいいですね〜。東京は想像以上に水道水が飲めたものじゃないのでこれがあると家がペットボトルまみれにならないのが最高です。まじでいい。ごみ捨てが楽になるので。
4. webカメラ
別にストリーマーってわけじゃないけど無駄にいいカメラを買った。カメラは最高すぎる。自分の顔を移したいわけじゃないが高画質のwebカメラはいろいろな遊び道具になるからね。いいもの!
5. マイク・オーディオインターフェース(これは前から持ってた)
フルリモートだったのでMTGすべてがオンラインだったので聞こえづらいとか相手の耳障りにならないようにコンデンサーマイクを買いました。オーディオインターフェースがあるとハードウェアミュートがあるので色々便利ですよ。ミュートマークが出ずにミュートできるので〜
さいごに
今年も色々買った。AirPods ProとかMacBookProもかったけどフルリモートという関係上あまり効力を発揮せずランクインならずって感じです。ほと〜〜〜〜んど家にいたからね。来年は椅子とディスプレイを買いたいです。あとキーボードかな〜キーボード。ゴミ箱からひろってきたHHKBを漂白して使ってるのでそろそろ新品をね......