AJ_1310
AJ_1310

Reputation: 3443

Error using babel-relay-plugin

I stumbled upon an error while using babel-relay-plugin.

When I require babel-relay-plugin module and export the output with my graphql schema and call it in my webpack list of babel plugins as a path works.

// webpack/plugins/babel-relay-plugin.js
var babelRelayPlugin = require('babel-relay-plugin');
var schema = require('./../../cloud/data/schema.json');

module.exports = babelRelayPlugin(schema.data);


// webpack/pro.config.js
    module.exports = [
      {
        module: {
          loaders: [
            {
              test: /\.js$/,
              exclude: /node_modules/,
              loader: 'babel',
              query: {
                plugins: [
                  './webpack/plugins/babel-relay-plugin'
                ]
              }
            }
          ]
        }

    }
]

But when I create the plugin in the same file as this:

// webpack/pro.config.js
var BabelRelayPlugin = require('babel-relay-plugin');
var schema = require('./../cloud/data/schema.json').data;

module.exports = [
  {
    name: 'server',
    target: 'node',
    devtool: 'cheap-module-source-map',
    entry: cloudPath,
    output: {
      path: buildPath,
      filename: 'index.js'
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            plugins: [
              new BabelRelayPlugin(schema)
            ]
          }
        }
      ]
    }
  }
]

It throws this error stack:

ERROR in ./cloud/index.js
    Module build failed: TypeError: Cannot read property '__esModule' of null
        at Function.normalisePlugin (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:156:20)
        at /Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:197:30
        at Array.map (native)
        at Function.normalisePlugins (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:173:20)
        at OptionManager.mergeOptions (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:271:36)
        at OptionManager.init (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:416:10)
        at File.initOptions (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/index.js:191:75)
        at new File (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/file/index.js:122:22)
        at Pipeline.transform (/Users/AJ/Desktop/winebox/app/node_modules/babel-core/lib/transformation/pipeline.js:42:16)
        at transpile (/Users/AJ/Desktop/winebox/app/node_modules/babel-loader/index.js:14:22)
        at Object.module.exports (/Users/AJ/Desktop/winebox/app/node_modules/babel-loader/index.js:88:12)

Any pointers as to how fix this inside the same file would be awesome. Thanks in advance.

All my packages are up-to-date an I already asked and it's not a Relay-side problem.

Upvotes: 1

Views: 2972

Answers (3)

klugjo
klugjo

Reputation: 20885

For those who stumble into this and are getting this error:

/app/client/node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:53
    var Plugin = _ref.Plugin;
                     ^

TypeError: Cannot read property 'Plugin' of undefined
    at new <anonymous> (/app/client/node_modules/babel-relay-plugin/lib/getBabelRelayPlugin.js:53:22)

Here is how the config I used to fix it:

at the root of my client app: babelRelayPlugin.js

const getBabelRelayPlugin = require('babel-relay-plugin');

// Make sure the path is correct here
const schemaData = require('../data/schema.json');

module.exports = getBabelRelayPlugin(schemaData.data);

Then in my .babelrc

{
  "presets": ["es2015", "react", "stage-0"],
  "plugins": ["./babelRelayPlugin"]
}

Here are my dependencies in my package.json

  "dependencies": {
    "babel-preset-stage-0": "^6.24.1",
    "babel-relay-plugin": "0.10.0",
    "node-sass": "^4.3.0",
    "react": "15.4.2",
    "react-dom": "15.4.2",
    "react-relay": "0.10.0",
    "sass-loader": "^6.0.2",
    "semantic-ui-css": "^2.2.10",
    "semantic-ui-react": "^0.68.3"
  },
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-plugin-transform-class-properties": "^6.22.0",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-preset-es2015": "6.22.0",
    "babel-preset-react": "^6.23.0",
    "babel-runtime": "^6.22.0",
    "css-loader": "0.26.1",
    "extract-text-webpack-plugin": "^v2.0.0-rc.1",
    "file-loader": "^0.10.0",
    "html-webpack-plugin": "^2.26.0",
    "postcss-loader": "^1.2.2",
    "react-hot-loader": "^3.0.0-beta.6",
    "style-loader": "0.13.1",
    "url-loader": "0.5.7",
    "webpack": "^2.2.1",
    "webpack-cleanup-plugin": "^0.4.2",
    "webpack-dashboard": "^0.3.0",
    "webpack-dev-server": "^2.4.1"
  }

I believe the babel stage-0 preset is required as it is present in all configs that work but I can't say for sure

Upvotes: 0

mrkre
mrkre

Reputation: 1548

I faced the same issue that was faced by OP, the solution provided by @steveluscher raised TypeError: Cannot read property 'Plugin' of undefined.

There is a plugin babel-plugin-react-relay that solves this problem. It can take a json file, URL or graphql-js schema.

It relies on babel-relay-plugin so that you do not have to create your own plugin.

Usage is simple:

npm install --dev babel-plugin-react-relay

In your .babelrc file, add:

"plugins": [
  "react-relay"
],

In package.json, add the path to your schema:

"react-relay-schema": "./data/schema.json"

And if you're using webpack, specify the plugin under babel-loader for your loaders:

{
    test: /\.js?$/,
    loader: 'babel-loader',
    include: [
        path.join(__dirname, 'src')
    ],
    query: {
        plugins: ['react-relay'],
        presets: ['react', 'es2015']
    }
 }

Upvotes: 4

steveluscher
steveluscher

Reputation: 4228

require('babel-relay-plugin') returns a function that you can use to get a plugin given a schema. I think the usage that you're looking for is:

// webpack/pro.config.js
var babelRelayPlugin = require('babel-relay-plugin');
var schema = require('./../cloud/data/schema.json').data;

module.exports = [
  {
    /* ... */
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            plugins: [
              new (babelRelayPlugin(schema))()
            ]
          }
        }
      ]
    }
  }
]

The inner expression returns a plugin, while the outer expression creates an instance of that plugin using the new keyword.

Upvotes: 1

Related Questions