[ERROR] React: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.


이번에 한번 프로젝트를 create-react-app 으로 시작해서 진행해볼까.. 하고 시작하는데 갑자기 날 멘붕하게 한 이 에러 메시지.

Uncaught Invariant Violation: Minified React error #130; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=130&args[]=undefined&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

React: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

정말 이상했던게 development env 에서는 아무 문제도 없는데, production env 에서만 저 오류가 발생했다.

 

우선, 나의 프로젝트 구조는 다음 gist 링크에 나와있다:

gist 링크: https://gist.github.com/velopert/ab6e132d73a17930c90e3e38493c12ed

 

평상시에 React 프로젝트 작업 할 때 처럼, containers 디렉토리에 컨테이너 컴포넌트들 넣고,
index.js 로 내부에있는 모든 컴포넌트 불러와서 export { App, UserProfile } 이런식으로 내보내고,
나중에 다른곳에서 import { UserProfile } from 'containers' 이런식으로 불러왔는데,
우선, React 프로젝트의 entry 포인트인 index.js 에선 컴포넌트를 로딩하고 렌더링하는데에는 아무 문제가 없었으나,
그 디렉토리 내부에서 import UserProfile from './UserProfile' 이런식으로 불러오는건 오류가 없었지만,
import { UserProfile } from 'containers' 이런식으로 불러오면,
렌더링할때 오류가 발생했다.
그리고 또 이해가 가지 않았던 부분은 dev server 에서는 제대로 작동하는데, production 일때만 저 오류가 발생한다는점..

뭐 때문에 이런 오류가 발생하는건지 한참 삽질하다가 결국 webpack dev config 랑 prod config랑 일일히 비교해보니
플러그인이나 모듈부분엔 큰 문제가 없었고 babel 의 설정의 차이 때문에 그랬다. 차이는 한 줄.

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

module.exports = {
  // Don't try to find .babelrc because we want to force this configuration.
  babelrc: false,
  presets: [
    // Latest stable ECMAScript features
    require.resolve('babel-preset-latest'),
    // JSX, Flow
    require.resolve('babel-preset-react')
  ],
  plugins: [
    // class { handleClick = () => { } }
    require.resolve('babel-plugin-transform-class-properties'),
    // { ...todo, completed: true }
    require.resolve('babel-plugin-transform-object-rest-spread'),
    // function* () { yield 42; yield 43; }
    [require.resolve('babel-plugin-transform-regenerator'), {
      // Async functions are converted to generators by babel-preset-latest
      async: false
    }],
    // Polyfills the runtime needed for async/await and generators
    [require.resolve('babel-plugin-transform-runtime'), {
      helpers: false,
      polyfill: false,
      regenerator: true
    }],
    // Optimization: hoist JSX that never changes out of render()
    require.resolve('babel-plugin-transform-react-constant-elements')
  ]
};

36번 줄을 지워주면, 언제 그런 오류 있었냐는듯이 해결이 된다.

babel-plugin-transform-react-constant-elements가 문제가 되는건데.. 상수형태로된 element는 변할일이 없어서 나중에 비교하지 않음으로서 성능을 최적화를 한다는데….. 지금 내가 겪고있는 오류랑 무슨 상관이 있는걸까? 이게 없으면 제대로 작동하는데, 이게 있으면 오류가 발생하니, 이 플러그인만의 버그인 것 같다.

내가 직접 코드 수정해서 오픈소스 프로젝트에 기여를 해볼까.. 했지만, 어떻게 수정해야할지 몰라서, 난 그냥 이 플러그인을 비활성화하기로 했다.

일단은 create-react-app 에 issue를 넣었다 🙁 이거때문에 오늘 시간을 너무 많이 낭비했어 ㅋㅋ

 

결과: https://github.com/facebookincubator/create-react-app/issues/525

내가 고칠 줄 몰라서 이슈 넣었더니 gaearon 은 슬픈 이모티콘을 작성하며 해당 플러그인을 create-react-app 에서 뺐다.

나중에 고쳐지면 다시 추가될듯 하다.