Can't use JSX after npm run eject - node.js

I was following this tutorial and it's been a week I tried to resolve the issue:
SyntaxError: TestComponent.js: Unexpected token (5:6)
3 | render() {
4 | return (
> 5 | <div>
| ^
6 | { this.props.children }
7 | </div>
8 | )
Currently, we have #babel/preset-env, #babel/preset-react, #babel/cli in 2019 rather than the tutorial pointing to babel-preset-es2015 babel-preset-stage-0 babel-preset-react babel-cli.
So, using them in package.json doesn't solve the issue:
"babel": {
"presets": [
"#babel/env",
"#babel/react"
]
}
I have tried several ways but nothing stopping the error. I hope someone has resolved the issue and can provide a solution.
Greatly appreciated!

TLDR: Detailed step by step guide
A couple things have changed since the writing of the tutorial namely the following are the breaking changes, unless listed otherwise the other steps in the tutorial are the same:
You will need to download and use the babel-cli in order to get your custom "lib" script command to work:
npm install --save-dev #babel/cli
You will also need to download and use the #babel/plugin-transform-react-jsx plugin within your custom "lib" script command to compile and transform your React code since Babel 6 and up no longer have any native transforms for React. This is necessary for when you want to share your custom component with only native JavaScript on npmjs for others.
npm install --save-dev #babel/plugin-transform-react-jsx
Update your "lib" script command to use the babel's JSX transforming plugin listed in step 2:
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"lib": "babel --plugins #babel/transform-react-jsx src/node_modules --out-dir lib --copy-files",
"test": "node scripts/test.js"
},
Note: You also don't need the .babelrc file listed in the tutorial as we will edit the webpack.config.js file to properly transpile JSX later on.
Steps 1 - 3 will allow you to publish and share your component with others, but you will still have to make adjustments for your local development and I will describe those steps below:
For your custom component's package.json remove the .js extension for the "main" entry point as this will cause the following issue. For example, here is my custom component's package.json:
{
"private": true,
"name": "YourComponent",
"main": "./YourComponent"
}
Now if you try to compile and run your application locally, using your custom component, it will throw an error complaining about your custom component's JSX syntax:
SyntaxError: YourComponent.js: Unexpected token (6:6)
3 | render() {
4 | return (
> 5 | <div>
| ^
6 | { this.props.children }
7 | </div>
8 | )
This is because you need to edit your webpack.config.js file to use the #babel/preset-env and #babel/preset-react babel presets. So you want to add this line:
presets: ['#babel/preset-env', '#babel/preset-react'], to your babel loader for your application's code.
For reference, here is the relevant section of my code (starts on line 329):
...
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-svgo,+ref![path]',
},
},
},
],
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
cacheCompression: isEnvProduction,
compact: isEnvProduction,
},
},
...
Now if you run locally it should work: npm run start
Those were the major steps that helped fix my JSX complaint for running locally as well as sharing my custom component with others on npmjs. I created a public git repo with my code and a detailed step by step guide to help others, it can be found here.
Hopefully that helps!

Looking at the tutorial and noticing it's using both " and ” (different styles of quotations marks, I don't know the correct language to reference them both properly).
There is a very subtle difference in looks between the two but only one of them will be interpreted correctly, the other will cause an error. The .babelrc in the tutorial is using the wrong style of quotation marks.
If you copied and pasted from the article, check to ensure you are using the correct style of quotes which should be the one closest to the Enter key on your keyboard.

Related

ESLint Vue plugin showing false positives for vue/comment-directive

After migrating from VueCLI to Vite, I have to do the linting "manually" as far as I understand; correct me if I'm wrong.
As I only want to lint my .ts and .html files (I separate them even for components), I have this script in my package json:
"lint": "eslint --ext .ts --ext .html src/"
It found some issues like missing :key in loops, but it also shows me this error for each template:
error clear vue/comment-directive
And this is always the closing tag of any root elements within my template.html
If there is only one root element I get one warning for the file, if there are multiple root elements I get a warning for each closing tag.
I don't understand what this rule complains as, according its documentation, it is there for the eslint-disable comments, which I don't have in my templates.
I had the same issue but in nuxt with eslint, i just needed to update eslint-config and eslint-module:
"#nuxtjs/eslint-config": "^5.0.0",
"#nuxtjs/eslint-module": "^3.0.1",
source: https://github.com/nuxt/eslint-plugin-nuxt/issues/121
I've just updated my npm dependencies and I have the same error.
I was reading the eslint documentation and finally I've realized that you can remove the false error if you setup the rule in the .eslintrc.js config file.
this is my .eslintrc.js config file:
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'#nuxtjs',
'prettier',
'prettier/vue',
'plugin:prettier/recommended',
'plugin:nuxt/recommended'
],
plugins: [
'prettier'
],
// add your custom rules here
rules: {
"vue/comment-directive": 0
}
}
add the rule "vue/comment-directive": 0 and that is!, the error message is removed!.
the possible values are:
0 means disabled
1 means warning
2 means error
Try to change it in your IDE to how it works
(In my case I've had to stop the server and re-run it every time that I've changed a value in this config file.)
I have the same error.
I was taught how to fix this error.
https://qiita.com/tashinoso/items/a72741ca8e2fd928ca77#comment-3e6cd674353056ecbb3a
module.exports = {
...
overrides: [
{
files: ["*.vue"],
processor: "vue/.vue"
}
]
}
Set this snippet on .eslintrc.js
"vue/comment-directive": ["error", {
"reportUnusedDisableDirectives": false
}]
Solve my issue, i wonder why. Solution from documentation
Node v12.20.0
This is a kind of a temporary fix that worked for me and I think it will work for you as well.
vue/comment-directive
This rule is included in all of "plugin:vue/base", "plugin:vue/essential", "plugin:vue/vue3-essential", "plugin:vue/strongly-recommended", "plugin:vue/vue3-strongly-recommended", "plugin:vue/recommended" and "plugin:vue/vue3-recommended".
ESLint doesn't provide any API to enhance eslint-disable functionality and ESLint rules cannot affect other rules. But ESLint provides processors API.
This rule sends all eslint-disable-like comments as errors to the post-process of the .vue file processor, then the post-process removes all vue/comment-directive errors and the reported errors in disabled areas.
All you need to do is add
eslint-disable-next-line vue/component-tags-order
this line as comment above anywhere you using comments within tags in each block you need to specify if comments are added.
For more information please visit:- https://eslint.vuejs.org/rules/comment-directive.html

Eslint does not recognize private field declaration using nodejs 12

Eslint will not recognize private fields marked with # in class declarations, even though I'm using NodeJS version 12 (which supports them).
I am running NodeJS v12.7.0. I have searched all DuckDuckGo and Google and I cannot find a plugin or option in eslint which will tell it to accept the private field notation (#). I have emca set to version 10.
class MyClass {
#foo = 'bar';
#bar = 'foo';
constructor(foo, bar) {
this.#foo = foo;
this.#bar = bar;
}
...
};
When I run eslint on the above code, I get:
2:3 error Parsing error: Unexpected character '#'
The project I'm working on does not use Babel, and I don't want to have to include it just to make private fields work. Any ideas how to make this work without having to resort to using Babel?
(Nothing against Babel of course, it's just on this particular project I don't want it).
2021 Update: You do not need babel for this anymore!
You can simply update eslint to v8.0.0 and above.
See eslint release notes: https://eslint.org/blog/2021/10/eslint-v8.0.0-released#highlights
Make sure this is in your .eslintrc file or similar:
{
"parserOptions": {
"ecmaVersion": 13
}
}
You can also just use latest instead of specifically version 13.
The upvoted answer is a little out of date, the babel-eslint package has changed, also, you need to make sure you have Babel configured too, in my case I was on a server, so it wasn't.
I blogged about the solution here:
https://dev.to/griffadev/setting-up-eslint-to-work-with-new-or-proposed-javascript-features-such-as-private-class-fields-5fm7
TL;DR:
npm i eslint #babel/core #babel/eslint-parser #babel/preset-env -D
Example .eslintrc
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parser": "#babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
}
}
Configure .babelrc
{
"presets": [
["#babel/preset-env",
{
"shippedProposals": true
}]
]
}
If you are using Jest and you don't have a .babelrc configured already, it will start picking up this new file, this may be a problem.
You can workaround this by renaming the .babelrc file to something else, and updating eslint config file:
"babelOptions": {
"configFile": "./.babel-eslintrc"
}
I think that you might have to bite the bullet and use babel-eslint: https://github.com/babel/babel-eslint, which requires that you install babel/core#>=7.2.0
Even though the private class fields are included in node 12, it's still a Stage 3 experimental feature according to the spec (as of August 2019)
npm install eslint babel-eslint --save-dev
# or
yarn add eslint babel-eslint -D
and add
"parser": "babel-eslint",
to your .eslintrc.js file
In regards to Visual Studio 2019, I found that the #babel/eslint-parser doesn't work with it but the older babel-eslint does. Other set up per #George's answer.
Visual Studio 2019 version as at time of answer: 16.9.5
Unless you really, really want that specific file linted I would avoid adding new dependencies just to make tests pass. My advice in this case would be to add
ignorePatterns: ["path/to/file(s).js"],
in your .eslintrc.js file. That will avoid linting that specific file. If you really want to lint it, do a substitution of # by __, lint, and change it back. I know, it's a hack, but it does not introduce any kind of dependency and it works.

Is there a way to ignore test files for eslint-plugin-security?

With a node.js project, I've added eslint-plugin-security and it is giving a lot of warnings for code in my test/spec files (using mochajs). Since the test code won't be running in production, these don't seem as useful as they do in the project's actual code. (A lot of Generic Object Injection Sink warnings )
Is there a way to have the security plugin ignore certain files other than putting /* eslint-disable */ at the top of every spec file?
The best way I found to deal with this case is based on this answer.
You can override parts of your eslint file in a subfolder. In my case I'm disabling problematic rules from a jest plugin inside my e2e tests folder. Example .eslintrc.js in /e2e-tests/ :
module.exports = {
overrides: [
{
files: ["*.spec.js"],
rules: {
"jest/valid-expect": 0
}
}
]
};
There is three way to ignore files or folders:
1. Creating a .eslintignore on your project root folder with the thing you want to ignore:
**/*.js
2. Using eslint cli & the --ignore-path to specify another file where your ignore rules will be located
eslint --ignore-path .jshintignore file.js
3. Using your package.json
{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
},
"eslintIgnore": ["*.spec.ts", "world.js"]
}
Official Documentation
On my side, I had issue with Intellij IDEA where eslint was checking files in a folder only dedicated to Typescript (+tslint) which was a pain, so I've picked solution 3.

External imports in Babel 7 do not get transpiled

I'm currently migrating a codebase from Babel 6 to 7. The code is made up of multiple individual projects with their own configs.
The main project imports files from external however the scripts being imported from external by main aren't being transpiled and fails on "Unexpected token import". Scripts located directly in main do transpile correctly.
I'm using the following command within the main project to transpile the scripts:
babel-node ./index.js
Another project uses Webpack to do the same thing and handles everything correctly.
This setup also worked fine with Babel 6.
.babelrc for main
{
"ignore": [
"node_modules"
],
"presets": [
["#babel/preset-env", {
"targets": {
"node": "current"
},
"useBuiltIns": "entry"
}]
],
"plugins": [
[
"module-resolver", {
"alias": {
"External": "../external"
}
}
],
"#babel/plugin-proposal-decorators",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-class-properties"
]}
.babelrc for external
{
"presets": [
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-transform-runtime"
]}
I've created an example to detail my problem at:
https://gitlab.com/nerdyman/babel-7-external-import-broken
TL;DR I'm trying to import scripts from outside of a project's root directory but they don't get transpiled by Babel, the scripts from within the project do transpile.
I've managed to fix this by following this comment.
The solution is:
Move .babelrc in the main project to babel.config.js and make it a CommonJS module
Add --ignore=node_modules when running babel-node from the main project
This still seems pretty hacky and Babel doesn't seem to acknowledge the ignore property within babel.config.js it must be specified as a flag.
Babel 7 appears to only allow imports within the directory the babel config is in, however explicitly setting the --ignore flag overrides this.
You can view my working demo and the diff of what I changed to get it working.
The issue is still open on GitHub so there may be a better solution in the future.
current directory's .babelrc won't be loaded while import files in external directory, you may place a .babelrc in that directory and set its presets by relative path(instead of short name):
{ "presets": ["..\pad\node_modules\babel-preset-env"],
"retainLines": true }

Unit Testing Syntax error, react, mocha

I'm attempting to set up some tests for my react app with enzyme, mocha and chai. (I'm also using webpack). I have Karma set up for my in-browser tests but i'd like to run these tests with just node.
I'm currently getting a syntax error when it tries to run the test. I'm not sure how to resolve it.
Update: I am running my tests with es6 mocha 'components/**/*.test.js' --recursive --compilers js:babel-register
The error I get is:
8 | describe('<button />', () => {
9 | it('renders something', () => {
> 10 | const wrapper = shallow(<button />)
11 | expect(wrapper).to.be.present
12 | })
You need to set up Babel before it can handle JSX syntax.
There are two options: add the configuration to your package.json, or create a file called .babelrc that contains the configuration.
First, install babel-preset-react:
$ npm i babel-preset-react --save
Next, add the following to your package.json:
"babel": {
"presets": [ "react" ]
}
(or add that object, without the "babel" key, to .babelrc)
Another preset that you may likely want to use is babel-preset-es2015, which you can add in a similar fashion (just add it to the presets array).
More documentation on Babel configuration here and here (specifically for es2015).

Resources