React Syntax Error: Unexpected Token at = - javascript

ERROR in ./src/js/HomeView.js
Module build failed: SyntaxError: Unexpected token (122:19)
120 | }
121 |
> 122 | handleDrawerOpen = () => {
| ^
123 | this.setState({ open: true });
124 | };
125 |
Got the above error when trying to compile react component using webpack.
Does anyone know what is the missing plugin here?

You'll probably need to install preset-stage-2.
This babel plugin allows you to use ES6+ features such as statics, property initializers, and even dynamic import support.
You could actually just install transform-class-properties for this particular case, but I usually prefer to install a babel plugin with stage-x because I find it comfortable to use multiple ES6+ features with a single install.
It might also be useful to future readers that this particular Babel plugin is already properly set up for you if you use create-react-app, as you can check here.

Difficult to guess from the code you have pasted above.
My guess is change it to
handleDrawerOpen() {
this.setState({ open: true });
}

Related

How to subscribe the observable? [duplicate]

When I run the linter it says:
subscribe is deprecated: Use an observer instead of an error callback
Code from this angular app:
this.userService.updateUser(data).pipe(
tap(() => {bla bla bla})
).subscribe(
this.handleUpdateResponse.bind(this),
this.handleError.bind(this)
);
Don't know exactly what should I use and how...
Thanks!
subscribe isn't deprecated, only the variant you're using is deprecated. In the future, subscribe will only take one argument: either the next handler (a function) or an observer object.
So in your case you should use:
.subscribe({
next: this.handleUpdateResponse.bind(this),
error: this.handleError.bind(this)
});
See these GitHub issues:
https://github.com/ReactiveX/rxjs/pull/4202
https://github.com/ReactiveX/rxjs/issues/4159
Maybe interesting to note that the observer Object can also (still) contain the complete() method and other, additional properties. Example:
.subscribe({
complete: () => { ... }, // completeHandler
error: () => { ... }, // errorHandler
next: () => { ... }, // nextHandler
someOtherProperty: 42
});
This way it is much easier to omit certain methods. With the old signature it was necessary to supply undefined and stick to the order of arguments. Now it's much clearer when for instance only supplying a next and complete handler.
For me, it was just the typescript version my VSCode was pointing to.
Got help from this GitHub comment.
I believe this is a typescript issue. Something in the newest versions of typescript is causing this warning to display in vs code. I was able to get it to go away by click the version of typescript in the bottom right corner of vs code and then choosing the select typescript version option. I set it to the node_modules version we have installed in our angular project which in our case happens to be 4.0.7. This caused the warnings to go away.
Find the details at official website
https://rxjs.dev/deprecations/subscribe-arguments
Notice the {} braces in second subscribe code below.
import { of } from 'rxjs';
// recommended
of([1,2,3]).subscribe((v) => console.info(v));
// also recommended
of([1,2,3]).subscribe({
next: (v) => console.log(v),
error: (e) => console.error(e),
complete: () => console.info('complete')
})
You can get this error if you have an object typed as Observable<T> | Observable<T2> - as opposed to Observable<T|T2>.
For example:
const obs = (new Date().getTime() % 2 == 0) ? of(123) : of('ABC');
The compiler does not make obs of type Observable<number | string>.
It may surprise you that the following will give you the error Use an observer instead of a complete callback and Expected 2-3 arguments, but got 1.
obs.subscribe(value => {
});
It's because it can be one of two different types and the compiler isn't smart enough to reconcile them.
You need to change your code to return Observable<number | string> instead of Observable<number> | Observable<string>. The subtleties of this will vary depending upon what you're doing.
I migrated my Angular project from TSLint to ESLint and it is now not showing the warning anymore!
I followed these steps. (End of each step I also recommend to commit the changes)
Add eslint:
ng add #angular-eslint/schematics
Convert tslint to eslint:
ng g #angular-eslint/schematics:convert-tslint-to-eslint
Remove tslint and codelyzer: npm uninstall -S tslint codelyzer
If you like to auto fix many of the Lint issues
ng lint --fix (It will also list the not fixed issues)
In VSCode uninstall the TSLint plugin, install ESLint plugin and Reload the VSCode.
Make sure it updated the package and package-lock files. Also the node_modules in your project.
If you have the tsconfig.json files under sub directory - you need to add/update the projects-root-directory/.vscode/settings.json with the sub directory where the tsconfig files are!
{
"eslint.workingDirectories": [
"sub-directory-where-tsconfig-files-are"
]
}
Information at VS Code official Page: Migrate from TSLint to ESLint (Thanks for pointing this out in the comment!)
Angular migrate from TSLint to ESLint Reference
I was getting the warning because I was passing this to subscribe:
myObs.subscribe(() => someFunction());
Since it returns a single value, it was incompatible with subscribe's function signature.
Switching to this made the warning go away (returns null/void);
myObs.subscribe(() => {
someFunction();
});
You should replace tslint with eslint.
As TSLint is being deprecated it does not support the #deprecated syntax of RXJS. ESLint is the correct linter to use, to do subscribe linting correctly.
The new Way of using RxJS is quit simple:
previous versions:
this.activatedRoute.queryParams.subscribe(queryParams => {
console.log("queryParams, queryParams)
}, error => {
})
New Version:
this.activatedRoute.queryParams.subscribe(
{
next: (queryParams) => {
console.log('queryParams', queryParams);
},
error: (err: any) => { },
complete: () => { }
}
);
Subscribe isn't deprecated.
So you should use:
import { of } from 'rxjs';
.subscribe({
next: (n) => console.log(n),
error: (e) => console.error(e),
complete: () => console.info('complete')
})

Migrating from Babel to SWC with React

TL;DR
How to translate a node script like this:
"test": "NODE_ENV=test riteway -r #babel/register 'src/**/*.test.js' | tap-nirvana",
to use SWC instead of Babel?
Context
We recently upgraded our Next.js version. Next.js now supports SWC instead of Babel.
The unit tests for React in our project are written with RITEway. The test command is:
"test": "NODE_ENV=test riteway -r #babel/register 'src/**/*.test.js' | tap-nirvana",
It transforms the files with Babel first because otherwise import statements and JSX would cause errors.
During our attempts to migrating to SWC, we had no luck with the CLI. However, we found the #swc-node/register package. It allowed us to transform our command like this:
"test": "riteway -r #swc-node/register src/**/*.test.js | tap-nirvana"
which fixes new syntax like the import statement and a test like this would run:
import { describe } from 'riteway';
describe('my test', async assert => {
assert({
given: 'true',
should: 'be true',
actual: true,
expected: true,
});
});
However, tests for React components like this
import { describe } from 'riteway';
import render from 'riteway/render-component';
import Authentication from './user-authentication-component';
describe('user authentication component', async assert => {
const $ = render(<Authentication />);
assert({
given: 'just rendering',
should: "render 'Authentication'",
actual: $('*:contains("Authentication")').text(),
expected: 'Authentication',
});
});
still throw the following error:
$ yarn test
yarn run v1.22.17
$ riteway -r #swc-node/register src/**/*.test.js | tap-nirvana
/Users/user/dev/learning-flow/node_modules/#swc/core/index.js:135
return bindings.transformSync(isModule ? JSON.stringify(src) : src, isModule, toBuffer(newOptions));
^
Error: error: Expression expected
|
7 | const $ = render(<Authentication />);
| ^
error: Expression expected
|
7 | const $ = render(<Authentication />);
| ^
error: Unexpected token `)`. Expected this, import, async, function, [ for array literal, { for object literal, # for decorator, function, class, null, true, false, number, bigint, string, regexp, ` for template literal, (, or an identifier
|
7 | const $ = render(<Authentication />);
| ^
Caused by:
0: failed to process js file
1: Syntax Error
at Compiler.transformSync
How can we create that command so that it runs with SWC?
After some experimentation I found out that it works if you import React from 'react'; in every file (both the component as well as the test) and change the file extensions to .jsx as described in the docs.
However, this is unsatisfying, as we'd like to use React 17's JSX transform feature to avoid having to import React in every file. Additionally, we'd like to keep all file endings .js.
We tried setting .swcrc without any luck so far.
I'm posting this answer here in case no way to configure .swcrc can be found.
I'll assume your question is only about jest and not about the webpack setup for swc.
I've never used swc myself in jest so this is just a shot in the dark, but I found a package for jest called #swc-node/jest which allows you to use a transformer like:
module.exports = {
transform: {
'^.+\\.(t|j)sx?$': ['#swc-node/jest'],
},
}
Which should allow you to transpile all [jt]sx? imports.
There's also a different one called #swc/jest which seems to do the same thing.
I'd start with trying those.
Your issue is that jest isn't able to parse your code, for example if you were using typescript you'd need something like ts-jest in order to parse your TS for you, I think in this case you need a swc/jest transpiler which should first compile your code and output it to memory, then funnel it to jest to run it.
The alternative is that you could compile the tests before hand using swc, then run jest on the compiled files as a separate step. At least with TS you can do that, first compile everything using tsc and then run jest on the .js output. I'm sure swc should work the same.
As to why the #swc-node/register package you're using isn't working, I have no idea.

Ignore return outside of function with babel 7

I recently updated to babel 7 and webpack 4 and am receiving this error when running our gulp build task:
gulp build
[00:26:04] Requiring external module #babel/register
[91m[BABEL] Note: The code generator has deoptimised the styling of /node_modules/lodash/lodash.js as it exceeds the max of 500KB.
[0m[91m/node_modules/#babel/core/lib/parser/index.js:95
throw err;
^
SyntaxError: /node_modules/dev-ip/lib/dev-ip.js: 'return' outside of function (41:8)
39 | var out = getIp();
40 | if (!out.length) {
> 41 | return console.log(messages.error);
| ^
42 | }
43 | console.log(getIp("cli"));
44 | }
at Parser.raise (/node_modules/#babel/parser/src/parser/location.js:41:63)
at Parser.parseReturnStatement (/node_modules/#babel/parser/src/parser/statement.js:577:12)
at Parser.parseStatementContent (/node_modules/#babel/parser/src/parser/statement.js:199:21)
at Parser.parseStatement (/node_modules/#babel/parser/src/parser/statement.js:146:17)
at Parser.parseBlockOrModuleBlockBody (/node_modules/#babel/parser/src/parser/statement.js:865:25)
at Parser.parseBlockBody (/node_modules/#babel/parser/src/parser/statement.js:841:10)
at Parser.parseBlock (/node_modules/#babel/parser/src/parser/statement.js:818:10)
at Parser.parseStatementContent (/node_modules/#babel/parser/src/parser/statement.js:223:21)
at Parser.parseStatement (/node_modules/#babel/parser/src/parser/statement.js:146:17)
at Parser.parseIfStatement (/node_modules/#babel/parser/src/parser/statement.js:570:28)
[0m[91merror Command failed with exit code 1.
This is caused by the return outside of a function in browser-syncs dev-ip dependency.
Is there a way to configure my .babelrc file to ignore this?
I've tried the following:
Installing only production dependencies, but because browser sync is imported in my gulp file it's still being compiled
Setting up workspaces with yarn, but similar issue as #1
Dynamically importing browser sync in my gulp file, I guess this is not yet supported yet?
Telling babel to ignore or exclude compiling the node_modules folder, but this doesn't seem to do anything?
Apparently babel-parser has an option allowReturnOutsideFunction: true, but I can't figure out how to set this in my .babelrc file.
Any thoughts on how to get around this?
With Babel7, you can provide all parser options (which include allowReturnOutsideFunction) via parserOpts, e.g.:
// .babelrc.js
module.exports = {
parserOpts: { allowReturnOutsideFunction: true }
};
Since I could not find a solution to this, I ended up just forking browser-sync and dev-ip.
I give you, browser-stink

React library that uses flow causes issues

I am relatively new to js & react so please bear with me!
I started a new project using create-react-app and react 16.12.0. I installed a library which I guess uses flow.
Trying to use this (npm install) library gives me the following SynatError:
./node_modules/react-resize-aware/src/useResizeAware.js
SyntaxError: [...]\node_modules\react-resize-aware\src\useResizeAware.js: Unexpected token, expected "," (5:31)
3 | import ResizeListener from './ResizeListener';
4 |
> 5 | const defaultReporter = (target: ?HTMLElement) => ({
| ^
6 | width: target != null ? target.offsetWidth : null,
7 | height: target != null ? target.offsetHeight : null,
8 | });
I feel like this is an issue on my side or at least an issue I could fix by doing some changes to the project's package.json.
If so, I would be happy if you could explain to me how.
//EDIT:
I tried adding flow to my project as described here but it gives me the same error.
What works is copying the source of the library into my project and importing it from this local version.
But I would really like to use the npm package, and not maintain a local version of the lib myself.
Thank you so much in advance!
Silly me, I simply imported from the wrong path. I used
import moduleName from "lib-name/src";
instead of
import moduleNamefrom "lib-name";

TypeScript definition for `gapi.client.storage` not taken into account

TypeScript tells me that "Property 'storage' does not exist on type 'typeof client'" when calling gapi.client.storage.buckets.list().
This is in the context of a Vue.js application (not sure it matters), I am using the GAPI library.
I have installed the #types/gapi, #types/gapi.auth2, #types/gapi.client and #types/gapi.client.storage packages, and TypeScript is correctly recognizing types on calls such as gapi.load(), gapi.client.init() or gapi.auth2.getAuthInstance().
However, no matter what I have tried, it always outputs an error on my gapi.client.storage.buckets.list() call:
ERROR in /Users/olance/Dev/project/src/views/Editor.vue(29,38):
29:38 Property 'storage' does not exist on type 'typeof client'.
27 |
28 | async mounted() {
> 29 | this.buckets = await gapi.client.storage.buckets.list({ project: "storage-cloud-editor" });
| ^
30 | }
31 |
Version: typescript 3.5.3
Right now, my tsconfig.json file contains the following in compilerOptions:
"typeRoots": [
"node_modules/#types"
],
"types": [
"webpack-env", "vuetify", "gapi", "gapi.auth2", "gapi.client.storage", "gapi.client"
],
By default it was configured with "types": ["webpack-env"], so this is the only way I've been able to make things work, even though the documentation seems to suggest typeRoots and types would be kind of exclusive.
Removing either or both options makes the compiler fail on other parts of the code (related to vuetify mainly, which does not declare types in #types).
What's missing to make TypeScript aware of the gapi.client.storage definitions?
While #types/gapi.client.storage is the package name, don't reference gapi.client.storage when callings its methods. Instead, use gapi.client.<method name>.
Using your example above, it would be:
gapi.client.buckets.list({ project: "storage-cloud-editor" })

Categories

Resources