facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.49k stars 26.77k forks source link

.env files is not working with CRA 5 #11951

Open rgb2hsl opened 2 years ago

rgb2hsl commented 2 years ago

Describe the bug

I created totally fresh CRA5 project (TypeScript), except .env added in the project root and src/App.tsx is modified with attempt to access process.env variables. I got crash with unhandled exception process is undefined. I think it's somehow related to Webpack 5 upgrade.

Did you try recovering your dependencies?

No, because project is fresh create-react-app v5 bootstrap.

Which terms did you search for in User Guide?

https://create-react-app.dev/docs/adding-custom-environment-variables/ said everything is supposed to work fine.

Environment

Environment Info:

  current version of create-react-app: 5.0.0
  running from /Users/evgenijvladimirovic/.npm/_npx/33863/lib/node_modules/create-react-app

  System:
    OS: macOS 12.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 14.16.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.11 - /usr/local/bin/npm
  Browsers:
    Chrome: 97.0.4692.71
    Edge: Not Found
    Firefox: 94.0.2
    Safari: 15.2
  npmPackages:
    react: ^17.0.2 => 17.0.2 
    react-dom: ^17.0.2 => 17.0.2 
    react-scripts: 5.0.0 => 5.0.0 
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

  1. npx create-react-app my-app --template typescript
  2. Add .env file in the project root with the line REACT_APP_FOO=foo
  3. Try to access process.env.REACT_APP_FOO (or just process itself) somehow. I, for ex, added console.log("process is ", process); and {process.env.REACT_APP_FOO} ini JSX.

Expected behavior

I got the REACT_APP_FOO value from .env file, just like in CRA Docs: image image

Actual behavior

I got Unhandled Exception, process is undefined: image

Reproducible demo

https://github.com/ru-web-designer/cra5-process-env-issue

pganster commented 2 years ago

With CRA 5, webpack was upgraded to v5, where node built-ins (such as process) have been removed.

You either need to eject your app which isn't desirable or use something like craco to configure webpack with an unejected create-react-app.

There is an open pull request that should address this issue.

kitsunekyo commented 2 years ago

we also found that CRA5 is almost unusable without ejecting at the moment.

we ejected, installed process and added this line to the webpack config:

resolve: {
      // ...
      alias: {
        // ...
        process: 'process/browser',
      },
rgb2hsl commented 2 years ago

We're also considering an ejection, unless https://github.com/facebook/create-react-app/pull/11764 will be merged. But at the moment it has conflicts.

UPD: we've ejected :D

dieseldjango commented 2 years ago

Same problem, backing down to 4.0.3 for now. I just started working with CRA and a bug this basic is a bit unsettling. Are there no tests that run against a test webpack bundle to check for things like this?

venkat-spendflo commented 2 years ago

This may be eslint issue

I had the same issue and I updated the .eslintrc with env with the below code and I was able to access the node api and windows apis link localstorage and process

You don't have to eject or add CRACO. Also not that craco still did not extent support to CRA 5

Tested that I was able to access the variables


env: {
    browser: true,
    node: true,
  },
zehawki commented 2 years ago

See if this helps: https://github.com/facebook/create-react-app/issues/12374#issuecomment-1136806073

ethan-stone-gas commented 2 years ago

Saw this issue and it concerned me so I did some digging. Keep in mind that I am not well versed in wepback at all so there very well could be something I am missing.

In the example repo @ru-web-designer as soon as I removed console.log(process) the project loaded. This seemed weird to me so I looked into the webpack config and it looks like env variables are loaded using this in. https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/env.js

function getClientEnvironment(publicUrl) {
  const raw = Object.keys(process.env)
    .filter(key => REACT_APP.test(key))
    .reduce(
      (env, key) => {
        env[key] = process.env[key];
        return env;
      },
      {
        // Useful for determining whether we’re running in production mode.
        // Most importantly, it switches React into the correct mode.
        NODE_ENV: process.env.NODE_ENV || 'development',
        // Useful for resolving the correct path to static assets in `public`.
        // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
        // This should only be used as an escape hatch. Normally you would put
        // images into the `src` and `import` them in code to get their paths.
        PUBLIC_URL: publicUrl,
        // We support configuring the sockjs pathname during development.
        // These settings let a developer run multiple simultaneous projects.
        // They are used as the connection `hostname`, `pathname` and `port`
        // in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
        // and `sockPort` options in webpack-dev-server.
        WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
        WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
        WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
        // Whether or not react-refresh is enabled.
        // It is defined here so it is available in the webpackHotDevClient.
        FAST_REFRESH: process.env.FAST_REFRESH !== 'false',
      }
    );
  // Stringify all values so we can feed into webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };

  return { raw, stringified };
}

So it looks to me that they use the DefinePlugin to load env variables rather than relying on the node-builtins. This seems to explain why process is undefined but specifically process.env is. Hope this helps.