ourzora/zora-docs

Uncaught ReferenceError: "process is not defined" thrown on fresh clone at 91f43f2b

almndbtr opened this issue ยท 5 comments

Summary

๐Ÿ‘‹ Hello, @ourzora! I hit this error when running a local instance of the site:

Uncaught ReferenceError: process is not defined

  • Steps to reproduce ๐Ÿ’
  • Why does this happen? ๐Ÿ•ต๏ธโ€โ™‚๏ธ
  • Possible paths forward ๐Ÿ’ญ

Steps to reproduce ๐Ÿ’

First, clone the repo, install the dependencies, and start it:

git clone https://github.com/ourzora/zora-docs
cd zora-docs
yarn install
yarn start

Next, open the developer console and observe the following errors:

Uncaught ReferenceError: process is not defined
    at eval (ShaderComponent.js?c1b7:9:1)
    at invokePassiveEffectCreate (react-dom.development.js?61bb:23487:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:3945:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:3994:1)
    at invokeGuardedCallback (react-dom.development.js?61bb:4056:1)
    at flushPassiveEffectsImpl (react-dom.development.js?61bb:23574:1)
    at unstable_runWithPriority (scheduler.development.js?3069:468:1)
    at runWithPriority$1 (react-dom.development.js?61bb:11276:1)
    at flushPassiveEffects (react-dom.development.js?61bb:23447:1)
    at performSyncWorkOnRoot (react-dom.development.js?61bb:22269:1)
    at eval (react-dom.development.js?61bb:11327:1)
    at unstable_runWithPriority (scheduler.development.js?3069:468:1)
    at runWithPriority$1 (react-dom.development.js?61bb:11276:1)
    at flushSyncCallbackQueueImpl (react-dom.development.js?61bb:11322:1)
    at flushSyncCallbackQueue (react-dom.development.js?61bb:11309:1)
    at scheduleUpdateOnFiber (react-dom.development.js?61bb:21893:1)
    at updateContainer (react-dom.development.js?61bb:25482:1)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js?61bb:26037:1)
    at render (react-dom.development.js?61bb:26103:1)
    at eval (VM940 clientEntry.js:19:216)

The above error occurred in the <ShaderComponent> component:

    at ShaderComponent (webpack-internal:///./src/components/ShaderComponent.js:10:257)
    at div
    at MobileSecondaryMenuProvider (webpack-internal:///./node_modules/@docusaurus/theme-common/lib/utils/mobileSecondaryMenu.js:13:217)
    at DocsPreferredVersionContextProviderUnsafe (webpack-internal:///./node_modules/@docusaurus/theme-common/lib/utils/docsPreferredVersion/DocsPreferredVersionProvider.js:26:877)
    at DocsPreferredVersionContextProvider (webpack-internal:///./node_modules/@docusaurus/theme-common/lib/utils/docsPreferredVersion/DocsPreferredVersionProvider.js:26:490)
    at UserPreferencesProvider (webpack-internal:///./node_modules/@docusaurus/theme-classic/lib-next/theme/UserPreferencesProvider/index.js:13:157)
    at AnnouncementBarProvider (webpack-internal:///./node_modules/@docusaurus/theme-common/lib/utils/announcementBarUtils.js:21:485)
    at ThemeProvider (webpack-internal:///./node_modules/@docusaurus/theme-classic/lib-next/theme/ThemeProvider/index.js:13:142)
    at LayoutProviders (webpack-internal:///./node_modules/@docusaurus/theme-classic/lib-next/theme/LayoutProviders/index.js:14:30)
    at Layout (webpack-internal:///./node_modules/@docusaurus/theme-classic/lib-next/theme/Layout/index.js:21:33)
    at Home
    at LoadableComponent (webpack-internal:///./node_modules/@docusaurus/react-loadable/lib/index.js:1:2843)
    at Route (webpack-internal:///./node_modules/react-router/esm/react-router.js:464:29)
    at Switch (webpack-internal:///./node_modules/react-router/esm/react-router.js:670:29)
    at Route (webpack-internal:///./node_modules/react-router/esm/react-router.js:464:29)
    at PendingNavigation (webpack-internal:///./node_modules/@docusaurus/core/lib/client/PendingNavigation.js:18:180)
    at C (webpack-internal:///./node_modules/react-router/esm/react-router.js:725:37)
    at Root (webpack-internal:///./node_modules/@docusaurus/core/lib/client/theme-fallback/Root/index.js:18:16)
    at App (webpack-internal:///./node_modules/@docusaurus/core/lib/client/App.js:23:94)
    at Router (webpack-internal:///./node_modules/react-router/esm/react-router.js:93:30)
    at BrowserRouter (webpack-internal:///./node_modules/react-router-dom/esm/react-router-dom.js:59:35)

Uncaught (in promise) ReferenceError: process is not defined
    at eval (ShaderComponent.js?c1b7:1:1)
    at invokePassiveEffectCreate (react-dom.development.js?61bb:23487:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:3945:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:3994:1)
    at invokeGuardedCallback (react-dom.development.js?61bb:4056:1)
    at flushPassiveEffectsImpl (react-dom.development.js?61bb:23574:1)
    at unstable_runWithPriority (scheduler.development.js?3069:468:1)
    at runWithPriority$1 (react-dom.development.js?61bb:11276:1)
    at flushPassiveEffects (react-dom.development.js?61bb:23447:1)
    at performSyncWorkOnRoot (react-dom.development.js?61bb:22269:1)
    at eval (react-dom.development.js?61bb:11327:1)
    at unstable_runWithPriority (scheduler.development.js?3069:468:1)
    at runWithPriority$1 (react-dom.development.js?61bb:11276:1)
    at flushSyncCallbackQueueImpl (react-dom.development.js?61bb:11322:1)
    at flushSyncCallbackQueue (react-dom.development.js?61bb:11309:1)
    at unbatchedUpdates (react-dom.development.js?61bb:22438:1)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js?61bb:26020:1)
    at render (react-dom.development.js?61bb:26103:1)
    at eval (clientEntry.js?12b7:21:1)

Why does this happen? ๐Ÿ•ต๏ธโ€โ™‚๏ธ

The aforementioned trace references ShaderComponent.js, responsible for rendering this beautiful motion graphic:

shadercomponent-demo

The specific line referenced in the trace is:

const rpcProvider = new ethers.providers.JsonRpcProvider(process.env.RPC_ENDPOINT)

It expects process to be defined, but it isn't. Under the hood, the docusaurus2-dotenv package automatically imports the variables defined in .env via its config file:

plugins: [
[
'docusaurus2-dotenv',
{
safe: false,
systemvars: true,
silent: false,
expand: false,
defaults: false,
RPC_ENDPOINT: process.env.RPC_ENDPOINT,
GTAG_ID: process.env.GTAG_ID,
},
],
],

On a fresh clone, the project doesn't have a .env file. But, it does have a .env.example file. Working from other projects, we could copy the contents into a new .env file...

cp .env.example .env

... and restarting the server seems to do the trick:

no-motion-dev-page

But, a different error is output to the console:

Error: could not detect network (...)
geturl.js?21de:27 POST http://localhost:8545/ net::ERR_BLOCKED_BY_CLIENT
eval @ geturl.js?21de:27
eval @ geturl.js?21de:8
__awaiter @ geturl.js?21de:4
getUrl @ geturl.js?21de:13
eval @ index.js?baf7:143
eval @ index.js?baf7:8
__awaiter @ index.js?baf7:4
eval @ index.js?baf7:139
_fetchData @ index.js?baf7:233
fetchJson @ index.js?baf7:275
send @ json-rpc-provider.js?3e80:384
eval @ json-rpc-provider.js?3e80:333
rejected @ json-rpc-provider.js?3e80:6
Promise.then (async)
step @ json-rpc-provider.js?3e80:7
fulfilled @ json-rpc-provider.js?3e80:5
Promise.then (async)
step @ json-rpc-provider.js?3e80:7
eval @ json-rpc-provider.js?3e80:8
__awaiter @ json-rpc-provider.js?3e80:4
_uncachedDetectNetwork @ json-rpc-provider.js?3e80:325
detectNetwork @ json-rpc-provider.js?3e80:316
eval @ base-provider.js?bc79:419
rejected @ base-provider.js?bc79:6
Promise.then (async)
step @ base-provider.js?bc79:7
eval @ base-provider.js?bc79:8
__awaiter @ base-provider.js?bc79:4
_ready @ base-provider.js?bc79:408
BaseProvider @ base-provider.js?bc79:390
JsonRpcProvider @ json-rpc-provider.js?3e80:290
eval @ ShaderComponent.js?c1b7:1
invokePassiveEffectCreate @ react-dom.development.js?61bb:23487
callCallback @ react-dom.development.js?61bb:3945
invokeGuardedCallbackDev @ react-dom.development.js?61bb:3994
invokeGuardedCallback @ react-dom.development.js?61bb:4056
flushPassiveEffectsImpl @ react-dom.development.js?61bb:23574
unstable_runWithPriority @ scheduler.development.js?3069:468
runWithPriority$1 @ react-dom.development.js?61bb:11276
flushPassiveEffects @ react-dom.development.js?61bb:23447
performSyncWorkOnRoot @ react-dom.development.js?61bb:22269
eval @ react-dom.development.js?61bb:11327
unstable_runWithPriority @ scheduler.development.js?3069:468
runWithPriority$1 @ react-dom.development.js?61bb:11276
flushSyncCallbackQueueImpl @ react-dom.development.js?61bb:11322
flushSyncCallbackQueue @ react-dom.development.js?61bb:11309
unbatchedUpdates @ react-dom.development.js?61bb:22438
legacyRenderSubtreeIntoContainer @ react-dom.development.js?61bb:26020
render @ react-dom.development.js?61bb:26103
eval @ clientEntry.js?12b7:21
Promise.then (async)
eval @ clientEntry.js?12b7:21
./node_modules/@docusaurus/core/lib/client/clientEntry.js @ main.js:87
__webpack_require__ @ runtime~main.js:36
__webpack_exec__ @ main.js:772
(anonymous) @ main.js:773
__webpack_require__.O @ runtime~main.js:83
(anonymous) @ main.js:774
webpackJsonpCallback @ runtime~main.js:1314
(anonymous) @ main.js:9
index.js?ffb2:185 Uncaught (in promise) Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.4.5)
    at Logger.makeError (index.js?ffb2:185:1)
    at Logger.throwError (index.js?ffb2:194:1)
    at JsonRpcProvider.eval (json-rpc-provider.js?3e80:350:1)
    at Generator.throw (<anonymous>)
    at rejected (json-rpc-provider.js?3e80:6:1)

Possible paths forward ๐Ÿ’ญ

  • Code: Setting an explicit error boundary if .env isn't set and presenting a "friendly" error message would be the most impactful change. I'm also interested in the tradeoff cost of having this "just work" even if .env isn't explicitly defined.
  • Docs: update the documentation with instructions for setting .env in development versus production.

๐Ÿ‘‹ Hello, @ourzora! I'm interested in assigning myself to this issue, but I don't have the appropriate access level.

May I ask that someone from the team assign me? ๐Ÿ™

I'd like to cut a draft PR starting work on this by end-of-day today (PST). ๐Ÿ”ช

Leaving an observation. The ShaderComponent relies on an RPC Provider to retrieve the latest block number before rendering the shader:

const rpcProvider = new ethers.providers.JsonRpcProvider(process.env.RPC_ENDPOINT)
rpcProvider.getBlockNumber().then((num) => {
sandbox.load(ShaderFragment)
sandbox.setUniform('u_seed', Math.pow(num, 0.5))
})

To confirm my understanding, I cut an experimental PR in my fork that removes the RPC provider and hardcodes the integer:

almndbtr#1

This deployment preview renders the site without that error:

https://zora-docs-git-almndbtr-42-fix-uncaught-referenc-a7dbc2-almndbtr.vercel.app/

Points to ponder ๐Ÿ’ญ

[1] Which parts of the Docs site require the RPC provider? For each instance, is that dependency critical (required for the site to run) or is it a "nice-to-have"?

[2] Besides the error boundary, would it perhaps be better to handle the rendering differently in development so there's one less dependency involved in just getting the site up and running? I'm imagining a way to render the shader with some fictitious block number, but using the "latest" block number only in production.

I think perhaps defaulting to a public rpc provider such as cloudflare-rpc is a better way forward than hardcoding.

I think perhaps defaulting to a public rpc provider such as cloudflare-rpc is a better way forward than hardcoding.

That sounds great, @iainnash - I'll try that approach.

cc: https://developers.cloudflare.com/distributed-web/ethereum-gateway/interacting-with-the-eth-gateway#cloudflare-supported-api

Cut a draft PR: #43

I'll transition it to "ready" once I've processed codesandbox/sandpack#66 (comment). The presence of process in the ShaderComponent makes me wonder if it should even be there in the first place, or if we should be poly-filling it since process is specific to Node environments rather than the browser? ๐Ÿ’ญ

Update (01/26/2022): it is intentional to use process in this context, since the app relies on the docusaurus2-dotenv plugin, which exposes environment variables via process.env.{foo}. I have a few acceptance tests that I want to run before marking this ready.