元ソース
jsx
1const bigIntRadix = BigInt(9007199254740991);
2const count = BigInt(2);
3const number = BigInt(2);
4let sum = 0n;
5
6export default function IndexPage() {
7 sum = bigIntRadix ** count * number;
8 return <div>{sum}</div>;
9}
ビルドした場合
next build
やreact-scripts build
にてビルドを行うと、どちらもエラーが発生します。
これは、 (webpack自体かreact-scriptsかはわかりませんが) バンドル時にコードが変換されるためです。
js
1 var u = i(5893),
2 r = BigInt(9007199254740991),
3 _ = BigInt(2),
4 c = BigInt(2),
5 e = 0n;
6 function f() {
7 return (
8 (e = Math.pow(r, _) * c),
9 (0, u.jsx)("div", { children: e })
10 );
Math.pow
はnumber
を引数に取りますので、BigInt
が与えられるとcan't convert BigInt to number
エラーが発生します。これはjsの通常の動作です。
DevServerで動かした場合
DevServerで動かした場合、reactではべき乗演算子**
が保たれ、nextではビルド時と同様Math.pow
に変換されています。
react
jsx
1const bigIntRadix = BigInt(9007199254740991);
2const count = BigInt(2);
3const number = BigInt(2);
4let sum = 0n;
5
6function App() {
7 sum = bigIntRadix ** count * number;
8 return /*#__PURE__*/(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", {
9 // 省略
next
jsx
1var bigIntRadix = BigInt(9007199254740991);
2var count = BigInt(2);
3var number = BigInt(2);
4var sum = 0n;
5function IndexPage() {
6 sum = Math.pow(bigIntRadix, count) * number;
7 return /*#__PURE__*/ (0, react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxDEV)(
8 // 省略
この違いによってreactのdevサーバではエラーが出ず、nextでは出る事になっています。
どちらにせよビルドをするとエラーになりますので、べき乗演算子は使用せず、独自の関数を実装することをおすすめします。
追記
変換はbabelによって行われています。べき乗演算子**
はes2016で実装されたので(普通に使うブラウザではもう大丈夫ですが)古いブラウザサポートのためにbabelは昔の記法にトランスパイルします。これは正しい仕様です。
es2016以上のブラウザに対応させるにはbabel.config.js
や.babelrc
などで@babel/preset-env/targets
を指定する必要があります。
babel.config.js
1module.exports = {
2 presets: [
3 [
4 "next/babel",
5 {
6 "preset-env": {
7 targets: {
8 chrome: 52,
9 edge: 14,
10 firefox: 52,
11 },
12 },
13 },
14 ],
15 ],
16};
https://caniuse.com/?search=**
正確なサポートを指定しないのであれば、last 1 versionでも良いと思います。
targets:[
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
],
追記2
※ここからの内容は今調べました。
babelがBitIntの変換をサポートしていないからです。変換パフォーマンスの低下を避けることが理由のようです。
前の追記ではサポートブラウザバージョンの指定を提案しましたが、BigIntの計算を行う場合はネイティブのBitIntと同様の動作をするライブラリJSBIを使用したほうが良いかもしれません。