forwardRef is not a function at buildReactRelayContainer when using babel7 - reactjs

I am attempting to upgrade to Babel 7, on a front end application using React 15.6.2 and Relay 1.6.2
The webpack bundle builds successfully.
However I get the following console error in the browser.
webpack_require(...).forwardRef is not a function
at buildReactRelayContainer
I am using webpack 3.12.0
And have the babel-plugin-relay in dev dependencies, and set at the top of the plugins in .babelrc, and set at the top of the plugins list in webpack.
Note at this stage I cannot upgrade to React 16 due to a library that uses the deprecated propTypes from React 15
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"sourceMaps": true,
"plugins": [
"relay",
"babel-plugin-ramda",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-syntax-import-meta",
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-json-strings",
[
"#babel/plugin-proposal-decorators",
{
"legacy": true
}
],
"#babel/plugin-proposal-function-sent",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-numeric-separator",
"#babel/plugin-proposal-throw-expressions",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-logical-assignment-operators",
"#babel/plugin-proposal-optional-chaining",
[
"#babel/plugin-proposal-pipeline-operator",
{
"proposal": "minimal"
}
],
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-proposal-do-expressions",
"#babel/plugin-proposal-function-bind"
]
}
webpack
...
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
"#babel/preset-env",
"#babel/preset-react",
{
"plugins": [
["relay", {"schema": "./graphql_schema_builds/private/venue/schema.graphql"}],
"ramda"
]
}
]
}
}
},
...

you are trying to mix things together which don't play well together. You are best off upgrading to the latest version of React (16.6~) and the latest version of webpack (4.3.0). They will play well with Babel 7. It will be a drastic change, but worth the updates! I am currently updating a React Workflow I had created last year which originally used webpack 3.6, Babel 6+, and React < 16.6, but when I created a new React Application in which React 16.6~ was added as well as webpack 4, and I tried to implement Babel with old package naming, it did not work. My webpack config did not work either. I had to make some major changes. Here is the link to my updated React workflow repo presentation/dlocumentation: https://github.com/interglobalmedia/react-workflow-updated-2018 The update is not complete yet, but you can follow my progress if you like! It should be completed very soon!

Related

Syntax Error: Support for the experimental syntax 'jsx' isn't currently enabled in react js

i am trying run my react application using npm start commamnd and installed both #babel/preset-react and #babel/plugin-syntax-jsx. but i am running this react application getting following error.
Support for the experimental syntax 'jsx' isn't currently enabled (7:9):
6 | const PostCodeLookup = props => {
> 7 | return <PostcodeLookup {...props} />
| ^
8 |
9 | };
Add #babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.
If you want to leave it as-is, add #babel/plugin-syntax-jsx (https://git.io/vb4yA) to the 'plugins' section to enable parsing.
It's hard to tell with no knowledge on how you bootstrapped your app, as jaybhatt said before.
If you used react-create-app probably you messed with packages and ended up in a inconsistent state. Try to reset your app. Creating a app on another folder and migrating your code there is an option (I did that a couple of times :) !).
If you created the app structure "by hand", check if you have "#babel/preset-react" set also on webpack config:
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
options: { presets: ['#babel/env', '#babel/preset-react'] },
},
Can you tell where you bootstrapped your application from? (Create React App or something like that?)
Also, you need to have a .babelrc or babel.config.js(on) file with these contents, just installing the packages won't work.
Putting an example below for how your babel.config.json should look like. Please remove any extra plugins from below example in case you use it.
{
"presets": [
[
"#babel/preset-env",
{
"modules": false,
"targets": {
"node": "current"
}
}
],
"#babel/preset-react"
],
"env": {
"test": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
[
"#babel/plugin-proposal-class-properties",
{
"spec": true
}
]
]
}
},
"plugins": [
[
"#babel/plugin-proposal-class-properties",
{
"spec": true
}
],
"#babel/plugin-proposal-object-rest-spread"
]
}

Should I Configure Babel Through .babelrc or WebPack?

In my react project, webpack.config.js brings in proposal-class properties like so:
...
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
query: {
presets: ['#babel/react', '#babel/preset-env'],
plugins: ['#babel/proposal-class-properties']
}
},
}
...
By including #babel/proposal-class-properties I'm able to remove the constructors from my React components, etc.
However, the documentation shows plugin-proposal-class-properties in .babelrc as follows (and doesn't mention webpack.config.js at all):
{
"plugins": ["#babel/plugin-proposal-class-properties"]
}
whereas my .babelrc does not include any plugins at all:
{
"presets": [
["#babel/env", {
"modules": false
},
"#babel/preset-env"]
]
}
Is there any effective difference between including the plugins (such as proposal-class-properties) in webpack.config.js as compared to putting them in .babelrc?
You can configure babel through .babelrc or through the babel-loader configuration in webpack. They both work exactly the same.
However, I recommend only using .babelrc for configuring babel.
That way it can also work when you run your tests, which usually don't go through webpack and will therefore not have the webpack configuration for babel.
.babelrc:
{
"presets": ["#babel/preset-env"]
"plugins": ['#babel/plugin-proposal-class-properties', {'loose': true}]
}

relay-compiler unable to extract and use graphql queries in Typescript

I tried using relay with the Typescript react starter, and am running into multiple issues.
Seems like babel-plugin-relay is not able to sense the graphql statements extracted by the relay-compiler. Here is my compiler script
"relay": "relay-compiler --src ./src --schema ./src/schema.graphql --extensions=tsx --watchman false".
.babelrc
{
"babel": {
"presets": [
"react-app"
],
"plugins": [
"relay"
]
}
This is my error which suggests an issue with babel transpilation
graphql: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as `graphql`.
Essentially the problem resolves around pulling out the GraphQL tags from typescript during transformations. I figured out the solution thanks to work in these PRs #1710 and #2293.
Here are the steps:
Modify the webpack config to include a babel loader (the typescript starter only has a ts-loader).
...
test: /\.(ts|tsx)$/,
include: paths.appSrc,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
{
loader: require.resolve('ts-loader'),
options: {
transpileOnly: true,
},
},
],
...
Change the target and module configuration in tsconfig to es2015
...
"target": "es2015",
"module": "es2015",
...
Add relay-compiler-language-typescript
yarn add relay-compiler-language-typescript -D
Also add babel-plugin-transform-es2015-modules-commonjs.
yarn add babel-plugin-transform-es2015-modules-commonjs -D
Since now we are targetting es2015, this plugin is needed to support ES module import and export statements.
And a script to compile graphql statements
"relay": "relay-compiler --src ./src --schema src/schema.graphql --language typescript --artifactDirectory ./src/__generated__ --watch"
Point the relay plugin to use the artifacts generated by the above command in .babelrc
"plugins": [
"transform-es2015-modules-commonjs",
["relay", { "artifactDirectory": "./src/__generated__" }],
],
My .babelrc looks like this
{
"plugins": [
[
// Please note that the "relay" plugin should run before other plugins or presets to ensure the graphql template literals are correctly transformed. See Babel's documentation on this topic.
"relay",
{
"artifactDirectory": "./src/__generated__"
}
],
[
"transform-es2015-modules-commonjs",
{
"allowTopLevelThis": true
}
]
]
}
Follow the configuration steps here https://github.com/relay-tools/relay-compiler-language-typescript#typescript
that will link you to babel docs https://babeljs.io/docs/en/babel-plugin-transform-es2015-modules-commonjs/
this seems to be working. my npm script is
"relay": "relay-compiler --src ./src --schema ./data/schema.graphql --language typescript --artifactDirectory ./src/__generated__"
and tsconfig.json contains this
"target": "es2015",
"module": "es2015",
Update
I had to install babel-plugin-relay as described here https://create-react-app.dev/docs/adding-relay/
and hack the typescript types for it https://github.com/DefinitelyTyped/DefinitelyTyped/issues/35707

Configuring antdesign using webpack

I am using this react redux starter. I want to use this starter with
ant design. But I am having a hard time to add ant design to this starter via webpack.
From the ant design doc I am suppose to use a .babelrc file to import the ant design babel library into my project. The starter doesn't use a .babelrc file to load babel plugins (as shown here), it uses the webpack configuration file.
How do I add the ant design library (the code below) into the webpack configuration file?
{
"plugins": [
["import", { libraryName: "antd", style: "css" }] // `style: true` for less]
}
NB: I already tried the approach in the ant design doc, but I get an error message: Unknown plugin "import" in *\.babelrc at 0. I also tried inserted a line ["import", { libraryName: "antd", style: "css" }] into row 76 the webpack config file of the starter, but error Unknonw plugin "import" specified in base at 4.
You have to install babel-plugin-import.
npm i babel-plugin-import --save-dev
yarn add babel-plugin-import --dev
An example of webpack config for "JSX" is shown below:
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: [nodeModulesDir],
options: {
cacheDirectory: true,
plugins: [
'transform-decorators-legacy',
'add-module-exports',
["import", { "libraryName": "antd", "style": true }],
["react-transform", {
transforms: [
{
transform: 'react-transform-hmr',
imports: ['react'],
locals: ['module']
}
]
}]
],
presets: ['es2015', 'stage-0', 'react']
}
},
The JSX files are loaded using babel-loader. babel-loader runs the plugins. One of the plugin is babel-plugin-import. This plugin ensures that antd is partially imported. import { Checkbox } from 'antd'; is converted to var Checkbox = require('antd/lib/checkbox'); by the plugin.

How do I configure Webpack to support ES7 Decorators [duplicate]

I've got a project written in ES6 with webpack as my bundler. Most of the transpiling works fine, but when I try to include decorators anywhere, I get this error:
Decorators are not supported yet in 6.x pending proposal update.
I've looked over the babel issue tracker, and haven't been able to find anything on it there, so I'm assuming I'm using it wrong. My webpack config (the relevant bits):
loaders: [
{
loader: 'babel',
exclude: /node_modules/,
include: path.join(__dirname, 'src'),
test: /\.jsx?$/,
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'stage-0', 'react']
}
}
]
I have no trouble with anything else, arrow functions, destructuring all work fine, this is the only thing that doesn't work.
I know I could always downgrade to babel 5.8 where I had it working a while ago, but if there's any way to get this working in the current version (v6.2.0), it would help.
This Babel plugin worked for me:
https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy
npm i --save-dev babel-plugin-transform-decorators-legacy
.babelrc
{
"presets": ["es2015", "stage-0", "react"],
"plugins": [
["transform-decorators-legacy"],
// ...
]
}
or
Webpack
{
test: /\.jsx?$/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: ['transform-decorators-legacy' ],
presets: ['es2015', 'stage-0', 'react']
}
}
React Native
With react-native you must use the babel-preset-react-native-stage-0 plugin instead.
npm i --save babel-preset-react-native-stage-0
.babelrc
{
"presets": ["react-native-stage-0/decorator-support"]
}
Please see this question and answer for a complete explanation.
After spending 5 minutes on the babeljs slack webchat, I found out that decorators are broken in the current version of babel (v6.2). The only solution seems to be to downgrade to 5.8 at this time.
It would also seem they moved their issue tracker from github to https://phabricator.babeljs.io
I write all this down, since after hours of searching I have found the current documentation very poor and lacking.
Installing only babel-plugin-transform-decorators-legacy didn't work for me (I have a configuration using enzyme along with karma). Turns out installing transform-class-properties: transform-class-properties and also making sure that the legacy plugin is before the transform class plugin as per the docs in transform-decorators-legacy finally made it work for me.
I'm also not using a .babelrc file, but adding this to my karma.conf.js file worked for me:
babelPreprocessor: {
options: {
presets: ['airbnb', 'es2015', 'stage-0', 'react'],
plugins: ["transform-decorators-legacy", "transform-class-properties"]
}
}
I also added it to my loaders:
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: path.resolve(__dirname, 'node_modules'),
query: {
presets: ['airbnb', 'es2015', 'stage-0', 'react'],
plugins: ["transform-decorators-legacy", "transform-class-properties"]
}
},
You just need a transform decorators plugin: http://babeljs.io/docs/plugins/transform-decorators/
If you upgraded your project from Babel 6 to Babel 7, then you want to install #babel/plugin-proposal-decorators.
If you want to support legacy decorators as used in Babel 5, you need to configure your .babelrc as follows:
plugins: [
['#babel/plugin-proposal-decorators', { legacy: true }],
['#babel/plugin-proposal-class-properties', { loose: true }],
]
Ensure #babel/plugin-proposal-decorators comes before #babel/plugin-proposal-class-properties in the case that you are making use of the latter.

Resources