Use nanoid in WeChat Mini Program
2 min read
Developing WeChat mini program
Want to use nanoid to generate unique id or something like that
npm i nanoid
“node:crypto” is not defined, “crypto” is not defined
Surpise! nanoid is relying on Web Crypto API
WeChat don’t have Web Crypto API
What to do now?
Peek the source code
|
|
Oh, it just need only crpyto.getRandomValues
. Don’t require entire crypto API
Fortunately, WeChat mini program has built-in wx.getRandomValues!
Let’s try to port this
First, change cryto.getRandomValues()
to wx.getRandomValues
export let nanoid = (size = 21) =>
wx.getRandomValues({
length: size,
succes: res => new Uint8Array(res.randomValues
})
.reduce(/* ... */)
wx.getRandomValues
it not immediately return value, instead it is a callback style so can’t just simple call .reduce
Need to move reduce into the success callback function
Don’t like that way
Make it promise!
export let nanoid = async (size = 21) => {
const randomValues = await new Promise((resolve) => {
wx.getRandomValues({
length: size,
success: res => resolve(new Uint8Array(res.randomValues))
}
})
return randomValues.reduce(/* ... */)
};
It work!
Copy and paste it some where in the project
npm remove nanoid. No need it in node_modules any more
Here the final code
export default async function nanoid(size = 21) {
const randomValues = await new Promise((resolve) => {
wx.getRandomValues({
length: size,
success: (res) => resolve(new Uint8Array(res.randomValues)),
});
});
return randomValues.reduce((id, byte) => {
byte &= 63;
if (byte < 36) {
id += byte.toString(36);
} else if (byte < 62) {
id += (byte - 26).toString(36).toUpperCase();
} else if (byte > 62) {
id += "-";
} else {
id += "_";
}
return id;
}, "");
}
Usage
const id = await nanoid();