mqttjs / MQTT.js

The MQTT client for Node.js and the browser
Other
8.61k stars 1.42k forks source link

[Bug]: Build issue with vite ( target: es2015 ) #1901

Closed denandserg closed 4 months ago

denandserg commented 4 months ago

MQTTjs Version

5.8.0

Broker

EMQX

Environment

Browser

Description

Description: We have identified a compatibility issue in our application when we build our app by Vite in target:es2015. This issue is caused by the use of the BigInt type and related operations. Since BigInt is not supported in these versions of ES. Its relates to use BigInt in format when using concat number with 'n' -> 2n or 32n

Suggested Solution: To resolve this issue, we recommend replacing the BigInt type and operations with Number equivalents. This involves changing the code so that it no longer uses BigInt literals (e.g., 2n or 32n) or operations. Instead, the code should use regular numbers and handle any necessary range checks or conversions without relying on BigInt.

Additional Information:

Vite Version: 5.3.3 Build mode: lib, Target: es2015, Node.js Version: v20.13.1 Operating System: Mac OS 14.5 Browser: Safari/Chrome on iOS 13 and below

Action Requested: Please consider updating the relevant parts of the application code to replace BigInt with Number to enhance compatibility with older versions of ES. Thank you for your attention to this matter.

in main bundle:

E2(
        "ERR_OUT_OF_RANGE",
        (str, range, input) => {
          assert2(range, 'Missing "range" argument');
          let received;
          if (Number.isInteger(input) && Math.abs(input) > 2 ** 32) {
            received = addNumericalSeparator(String(input));
          } else if (typeof input === "bigint") {
            received = String(input);
            if (input > 2n ** 32n || input < -(2n ** 32n)) {  // This block breaks build
              received = addNumericalSeparator(received);
            }
            received += "n";
          } else {
            received = inspect(input);
          }
          return `The value of "${str}" is out of range. It must be ${range}. Received ${received}`;
        },
        RangeError
      );

Minimal Reproduction

Steps to Reproduce:

Just try to build App using Vite with target: es2015 !!!

Debug logs

x Build failed in 3.98s error during build: [vite:esbuild-transpile] Transform failed with 4 errors: assets/index-!~{001}~.js:47281:5712: ERROR: Big integer literals are not available in the configured target environment ("es2015" + 2 overrides) assets/index-!~{001}~.js:47281:5716: ERROR: Big integer literals are not available in the configured target environment ("es2015" + 2 overrides) assets/index-!~{001}~.js:47281:5725: ERROR: Big integer literals are not available in the configured target environment ("es2015" + 2 overrides) assets/index-!~{001}~.js:47281:5729: ERROR: Big integer literals are not available in the configured target environment ("es2015" + 2 overrides)

Big integer literals are not available in the configured target environment ("es2015" + 2 overrides) 47279|
47280| var ps=Object.defineProperty;var Kg=Object.getOwnPropertyDescriptor;var Gg=Object.getOwnPropertyNames;var Qg=Object.prototype.hasOwnProperty;var we=(t,e)=>()=>(t&&(e=t(t=0)),e);var M=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Yt=(t,e)=>{for(var r in e)ps(t,r,{get:e[r],enumerable:!0});},Yg=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Gg(e))!Qg.call(t,n)&&n!==r&&ps(t,n,{get:()=>e[n],enumerable:!(i=Kg(e,n))||i.enumerable});return t};var X=t=>Yg(ps({},"_esModule",{value:!0}),t);var P,=we(()=>{P={deviceMemory:8,hardwareConcurrency:8,language:"en-US"};});var C={};Yt(C,{_debugEnd:()=>yu,_debugProcess:()=>gu,_events:()=>Ou,_eventsCount:()=>xu,_exiting:()=>Yl,_fatalExceptions:()=>cu,_getActiveHandles:()=>eu,_getActiveRequests:()=>Zl,_kill:()=>ru,_linkedBinding:()=>Gl,_maxListeners:()=>ku,_preload_modules:()=>Cu,_rawDebug:()=>zl,_startProfilerIdleNotifier:()=>bu,_stopProfilerIdleNotifier:()=>wu,_tickCallback:()=>pu,abort:()=>Eu,addListener:()=>Mu,allowedNodeEnvironmentFlags:()=>lu,arch:()=>xl,argv:()=>Ul,argv0:()=>Ru,assert:()=>uu,binding:()=>Fl,chdir:()=>Hl,config:()=>Jl,cpuUsage:()=>Fi,cwd:()=>$l,debugPort:()=>Tu,default:()=>$u,dlopen:()=>Xl,domain:()=>Ql,emit:()=>Du,emitWarning:()=>jl,env:()=>Ll,execArgv:()=>Nl,execPath:()=>Iu,exit:()=>ou,features:()=>fu,hasUncaughtExceptionCaptureCallback:()=>du,hrtime:()=>ji,kill:()=>su,listeners:()=>Wu,memoryUsage:()=>nu,moduleLoadList:()=>Kl,nextTick:()=>Pl,off:()=>Uu,on:()=>wt,once:()=>Lu,openStdin:()=>au,pid:()=>Su,platform:()=>Ml,ppid:()=>Au,prependListener:()=>ju,prependOnceListener:()=>Fu,reallyExit:()=>tu,release:()=>Vl,removeAllListeners:()=>qu,removeListener:()=>Nu,resourceUsage:()=>iu,setSourceMapsEnabled:()=>Bu,setUncaughtExceptionCaptureCallback:()=>hu,stderr:()=>mu,stdin:()=>vu,stdout:()=>_u,title:()=>Ol,umask:()=>Wl,uptime:()=>Pu,version:()=>ql,versions:()=>Dl});function bs(t){throw new Error("Node.js process "+t+" is not supported by JSPM core outside of Node.js")}function Jg(){!xr||!Jt||(xr=!1,Jt.length?bt=Jt.concat(bt):Di=-1,bt.length&&Bl());}function Bl(){if(!xr){var t=setTimeout(Jg,0);xr=!0;for(var e=bt.length;e;){for(Jt=bt,bt=[];++Di<e;)Jt&&Jt[Di].run();Di=-1,e=bt.length;}Jt=null,xr=!1,clearTimeout(t);}}function Pl(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];bt.push(new kl(t,e)),bt.length===1&&!xr&&setTimeout(Bl,0);}function kl(t,e){this.fun=t,this.array=e;}function ve(){}function Gl(t){bs("_linkedBinding");}function Xl(t){bs("dlopen");}function Zl(){return []}function eu(){return []}function uu(t,e){if(!t)throw new Error(e||"assertion error")}function du(){return !1}function Pu(){return Lt.now()/1e3}function ji(t){var e=Math.floor((Date.now()-Lt.now()).001),r=Lt.now().001,i=Math.floor(r)+e,n=Math.floor(r%1*1e9);return t&&(i=i-t[0],n=n-t[1],n<0&&(i--,n+=ys)),[i,n]}function wt(){return $u}function Wu(t){return []}var bt,xr,Jt,Di,Ol,xl,Ml,Ll,Ul,Nl,ql,Dl,jl,Fl,Wl,$l,Hl,Vl,zl,Kl,Ql,Yl,Jl,tu,ru,Fi,iu,nu,su,ou,au,lu,fu,cu,hu,pu,gu,yu,bu,wu,u,mu,vu,Eu,Su,Au,Iu,Tu,Ru,Cu,Bu,Lt,gs,ys,ku,Ou,xu,Mu,Lu,Uu,Nu,qu,Du,ju,Fu,$u,Hu=we(()=>{v();m();();bt=[],xr=!1,Di=-1;kl.prototype.run=function(){this.fun.apply(null,this.array);};Ol="browser",xl="x64",Ml="browser",Ll={PATH:"/usr/bin",LANG:P.language+".UTF-8",PWD:"/",HOME:"/home",TMP:"/tmp"},Ul=["/usr/bin/node"],Nl=[],ql="v16.8.0",Dl={},jl=function(t,e){console.warn((e?e+": ":"")+t);},Fl=function(t){bs("binding");},Wl=function(t){return 0},$l=function(){return "/"},Hl=function(t){},Vl={name:"node",sourceUrl:"",headersUrl:"",libUrl:""};zl=ve,Kl=[];Ql={},Yl=!1,Jl={};tu=ve,ru=ve,Fi=function(){return {}},iu=Fi,nu=Fi,su=ve,ou=ve,au=ve,lu={};fu={inspector:!1,debug:!1,uv:!1,ipv6:!1,tls_alpn:!1,tls_sni:!1,tls_ocsp:!1,tls:!1,cached_builtins:!0},cu=ve,hu=ve;pu=ve,gu=ve,yu=ve,bu=ve,wu=ve,_u=void 0,mu=void 0,vu=void 0,Eu=ve,Su=2,Au=1,Iu="/bin/usr/node",Tu=9229,Ru="node",Cu=[],Bu=ve,Lt={now:typeof performance<"u"?performance.now.bind(performance):void 0,timing:typeof performance<"u"?performance.timing:void 0};Lt.now===void 0&&(gs=Date.now(),Lt.timing&&Lt.timing.navigationStart&&(gs=Lt.timing.navigationStart),Lt.now=()=>Date.now()-gs);ys ... and 39 lines more

robertsLando commented 4 months ago

cannot you use an higher target env?

denandserg commented 4 months ago

Unfortunately we have to support ios 13 and below( All other libs and places we can cover by polyfills except BigInt.

robertsLando commented 4 months ago

problem is that bigint isn't used in mqttjs but in an underlying lib: https://github.com/nodejs/readable-stream/blob/main/lib/ours/errors.js#L314

Could you try to ask there?

denandserg commented 4 months ago

Thanks will do

robertsLando commented 4 months ago

I see it's also used on Buffer polifilly but I'm not sure that causes problem as we are not using those buffer methods (and them are using BigInt instead the literal notation like 2n

robertsLando commented 4 months ago

@denandserg Just to try you could write a patch that converts that using BigInt and see if the build succeed so (or just remove the n from numbers)

denandserg commented 4 months ago

@robertsLando ok may be second variant will be more appropriate for us, because patch for lib in nested lib looks impossible.

robertsLando commented 4 months ago

@denandserg The patch should be done on mqtt dist/mqtt.xxx file as that is the one that will be picked up by the browser.

There is a super useful package I use in such situations: https://www.npmjs.com/package/patch-package

Did you tried to ask the question in readable-stream repo?

denandserg commented 4 months ago

I have applied my custom vite plugin for it. It works for us. Thanks.
No i didn`t ask in readable-stream repo.