🎲
crypto.randomUUIDをブラウザとサーバーとNext.jsのミドルウェアで使用するサンプルコード
crypto
のrandomUUID
を使えばuuidを生成できます。
開発においてモノレポ構成をとっており、どうせならuuidを生成するコードを、ブラウザとサーバーサイドで統一しようと思ったところ、思った以上に難しかったためサンプルコードを共有します。
おさらい
nodejs環境でcrypto.randomUUIDを使用する
nodejs環境でのcrypto
利用方法。require
もしくはimport
します。randomUUID
API自体はnodeのv14.17
かv15.6
から使用できます。
const crypto = require('crypto');
crypto.randomUUID();
ブラウザ環境でcypto.randomUUIDを使用する
crypto.randomUUID();
Next.jsでcypto.randomUUIDを使用する
Next.jsには2つのランタイム環境が共存します。middleware
はedgeランタイム環境で使用できるnodejsのAPIが制限されています。ランタイム環境の識別はprocess.env.NEXT_RUNTIME
でできます。
ややこしいことに、edgeランタイムではcryto
はグローバルで使用できます。
if(process.env.NEXT_RUNTIME === 'edge'){
crypto.randomUUID();
} else {
const crypto = require('crypto');
crypto.randomUUID();
}
共通で使用想定のライブラリ
uuidからハイフンを抜いて、すべての環境で使えるように共通化したコードです。
interface CryptoType {
randomUUID: () => string;
}
let cryptoUtil: CryptoType;
// for browser
if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
cryptoUtil = crypto as unknown as CryptoType;
} else {
// https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation#importing-runtime-specific-code
// for next edge runtime
if (process.env.NEXT_RUNTIME === 'edge') {
cryptoUtil = crypto as unknown as CryptoType;
// for next nodejs runtime
} else if (process.env.NEXT_RUNTIME === 'nodejs') {
const nodeCrypto = require('crypto');
cryptoUtil = {
randomUUID: () => nodeCrypto.randomUUID(),
};
// for others (maybe server)
} else {
const nodeCrypto = require('crypto');
cryptoUtil = {
randomUUID: () => nodeCrypto.randomUUID(),
};
}
}
export function createUUID() {
return cryptoUtil.randomUUID().replace(/-/g, '');
}
Discussion