React.js and webpack - why won't it allow var, let, const? - javascript

I have a bit of an issue here that I can't get to the bottom of.
Here's a snippet from my Graph.js file:
class Graph extends React.Component {
#observable newTodoTitle = "";
s = 40
There error in webpack is as follows:
ERROR in ./src/components/Graph.js
Module build failed: SyntaxError: Unexpected token (13:6)
2018-01-11T14:56:05.221073500Z
11 |
12 |
> 13 | let s = 40
| ^
If I remove the "let", it compiles fine!
I'd prefer to keep the var, let, consts, etc. as I want to copy and paste a lot of JavaScript into this file without these errors.
Here's my .babelrc
{
"presets": [
"react",
"es2015",
"stage-1"
],
"plugins": ["transform-decorators-legacy"]
}
And here's my webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [{
test: /\.jsx?$/,
use: ['babel-loader'],
include: path.join(__dirname, 'src')
}]
}
};
Any ideas?

You are trying to use the class-fields proposal (stage 3 currently) which you will need the Class properties transform plugin of babel to support this.
As you can see in the docs, your syntax is off.
There is no need for any variable declaration key word for class fields.
Example from the docs:
class Counter extends HTMLElement {
x = 0;
clicked() {
this.x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this.clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.x.toString();
}
}

Related

SyntaxError: react-table/src/publicUtils.js: Support for the experimental syntax 'jsx' isn't currently enabled

I'm having problems when building with webpack. This is the error that I see when I'm building...
ERROR in ./node_modules/react-table/src/publicUtils.js 10:35
Module parse failed: Unexpected token (10:35)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| export const defaultRenderer = ({ value = '' }) => value;
> export const emptyRenderer = () => <> </>;
|
| export const defaultColumn = {
# ./node_modules/react-table/src/plugin-hooks/useRowSelect.js 3:0-9:23 14:0-25 15:0-29 16:0-25 17:0-33 96:22-34 103:22-47 110:22-51 141:22-47 178:22-55 235:2-19 277:35-47 279:2-24 281:23-48 286:30-59 291:30-63 296:36-61 300:22-34 302:40-54 307:44-58 327:34-48
# ./src/pages/CustomTableContainer.jsx 34:20-72
# ./src/pages/TimeReport.jsx 18:51-88
# ./src/pages/MainNavigation.jsx 22:41-64
# ./src/App.js 18:45-78
# ./src/index.js 11:34-50
Before I added webpack and babel though I had the same problem (basically the problem was the thing that pushed me to start adding webpack and babel in the first place)... the error in that case was the following:
./node_modules/react-table/src/publicUtils.js
SyntaxError: /Users/badu/Workspaces/4D-Projects/time-report/node_modules/react-table/src/publicUtils.js: Support for the experimental syntax 'jsx' isn't currently enabled (10:36):
8 |
9 | export const defaultRenderer = ({ value = '' }) => value;
> 10 | export const emptyRenderer = () => <> </>;
| ^
11 |
12 | export const defaultColumn = {
13 | Cell: defaultRenderer,
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.
Anyways, I'm currently using React to build my app with babel and webpack. Here is my .babelrc file
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-transform-runtime",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-proposal-class-properties"
],
"env": {
"production": {
"only": ["src"],
"plugins": [
[
"transform-react-remove-prop-types",
{
"removeImport": true
}
],
"#babel/plugin-transform-react-inline-elements",
"#babel/plugin-transform-react-constant-elements"
]
}
}
}
And here is my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management',
}),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
mode: 'development',
devServer: {
contentBase: './dist',
open: true
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-react'],
include: [
path.resolve('node_modules/react-table/'),
],
exclude: /node_modules\/(?!react-table).+/
}
}
},
... other loaders
]
},
resolve: {
extensions: [".js", ".jsx"],
modules: [
'node_modules'
]
}
};
I followed quite a few guides but still couldn't find anything that could solve my problem.
The publicUtils.js is coming from an external module. However this module has the dist folder in it which should have the already compiled code(?)
I'm not an expert on webpack and babel yet so I might be missing something
Don't know whether to be pissed or what, but check the imports, Visual Studio imported me automatically
import {useRowSelect} from "react-table/src/plugin-hooks/useRowSelect";
while the correct import (working) is
import {useRowSelect} from "react-table";
The error was never on webpack or babel's side
Hope this saves a bunch of time to other people

cannot babel transform .marko files with webpack 4

i have a working marko setup for my widget. Im using webpack 4 and babel 7. When i add babel-loader to .marko files, the webpack compiler throws because it couldn't recognize marko's syntax as valid javascript. However the loader should work after the marko transpilation.
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Volumes/Workspace/product-curator-widget/src/index.marko: A class name is required (1:6)
> 1 | class {
| ^
2 | onCreate () {
index.marko
class {
onCreate () {
this.state = {
items: [ {label: 'foo'}, {label: 'bar'} ]
}
const pr = new Promise((resolve) => resolve()) //trying to transpile this arrow function
}
}
<paper>
<chip for (item in state.items) label="${item.label}" value="${item.value}" />
</paper>
webpack.config.js
'use strict'
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = () => ({
mode: 'development',
devtool: 'cheap-source-map',
entry: [
'core-js',
'./src/index.js'
],
resolve: {
extensions: ['.js', '.marko'],
},
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/, /\.test\.js$/],
use: ['babel-loader'],
},
{
test: /\.marko$/,
exclude: [/node_modules/, /\.test\.js$/],
use: ['#marko/webpack/loader', 'babel-loader'],
},
{
test: /\.scss$/,
exclude: [/node_modules/],
use: ['style-loader', 'css-loader', 'sass-loader'],
}
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: './src/index.html'
}),
new CleanWebpackPlugin()
],
})
babel.config.js
module.exports = function (api) {
api.cache(true)
return {
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-transform-async-to-generator",
"#babel/plugin-transform-regenerator",
],
"presets": [
[
"#babel/preset-env",
{
"targets": {
"ie": "10"
}
}
]
]
}
}
Loaders in webpack are evaluated from right to left. In this case, you'll want #marko/webpack/loader to be the first loader to run (put it last in the array), so by the time babel-loader is called, the .marko file has been compiled to JS.
Side note: if you're using Marko components that have been published to npm, you don't want to ignore node_modules. Marko recommends publishing the source .marko files because the compiler produces different output for the server vs the browser. Additionally, the compilation output can be different depending on the version of Marko your app is using.
{
test: /\.marko$/,
use: ['babel-loader', '#marko/webpack/loader'],
},

Webpack: Trying to expose a bundled object to be usable by other scripts, object is still undefined

I'm trying to get just the basics down, transpiling a jsx file to js. However, my transpiled code needs to be called by non-transpiled code. output.library is supposed to help with that.
In the resulting bundle I see a definition for var react. But just after stepping through the entire bundle, it's clear react still isn't getting set.
my webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: "./public/js/ui/react/dialog.jsx",
output: {
path: path.resolve(__dirname, "public/js/ui/react/"),
filename: "bundle.js",
libraryTarget: "var",
library: "react"
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: [
path.resolve(__dirname, "node_modules/")
],
query: {
presets: ['es2015', "react"]
}
}
]
},
node: {
fs: "empty"
}
}
and the jsx I am trying to transpile:
'use strict';
react.Dialog = class extends React.Component {
render() {
return (
<div class="bubble-speech">Hello World</div>
)
}
}
elsewhere in my code, AND BEFORE THE BUNDLE, I have this, so that the react.Dialog assignment is not a null reference error:
var react = {};
If I take that one line away, the bundle.js will throw an error trying to assign react.Dialog. But if I leave it in, var react remains set to the empty object. That seems like a contradiction! What am I missing here?
I think react should be set as an externally defined global var, like this:
{
output: {
// export itself to a global var
libraryTarget: "var",
// name of the global var: "Foo"
library: "Foo"
},
externals: {
// require("react") is external and available
// on the global var React
"react": "React"
}
}

Class variables in React with ES6

This question might have been answered somewhere else, but before marking as duplicate, please help me with it. I am referring to the following codepen using react and d3: https://codepen.io/swizec/pen/oYNvpQ
However, I am not able to figure out how can this codepen work with variables declared inside the class without any keywords:
class Colors extends Component {
colors = d3.schemeCategory20;
width = d3.scaleBand()
.domain(d3.range(20));
....
}
When I try to execute this code, I get the following error:
./app/components/D3IndentedTree/Chloreophath.js
Module build failed: SyntaxError: Unexpected token (13:11)
11 | // Draws an entire color scale
12 | class Colors extends Component {
> 13 | colors = d3.schemeCategory20;
| ^
14 | width = d3.scaleBand()
15 | .domain(d3.range(20));
16 |
I am not able to figure out why am I getting this error. I understand that you cant declare variables/properties of class directly inside the class. But how come then the code pen is working?
Thanks in advance!
Update: Adding the webpack.config.js file:
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './app/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js',
publicPath: '/'
},
module: {
rules: [
{ test: /\.(js)$/, use: 'babel-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader'] },
{
test: /\.png$/,
loader: "url-loader?limit=100000"
},
{
test: /\.jpg$/,
loader: "file-loader"
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader? limit=10000&mimetype=application/font-woff'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: 'file-loader'
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
}
]
},
plugins: [new HtmlWebpackPlugin({
template: 'app/index.html'
}),
new webpack.ProvidePlugin({
"React": "react",
}),],
devServer: {
historyApiFallback: true
}
};
But how come then the code pen is working?
Because it's using a transpiler (in that case, Babel) that supports that syntax (which is currently a Stage 3 proposal, not a specified feature [yet], but is commonly supported by transpilers used with React code).
You can see that it's transpiling with Babel because it says "(Babel)" next to "JS" in the JS pane's header:
...and if you click the gear icon next to it, you'll see Babel selected as the "Preprocessor".
In this particular case, Babel takes this:
class Colors extends Component {
colors = d3.schemeCategory20;
width = d3.scaleBand()
.domain(d3.range(20));
// ....
}
...and makes it as though it had been written like this:
class Colors extends Component {
constructor() {
this.colors = d3.schemeCategory20;
this.width = d3.scaleBand()
.domain(d3.range(20));
}
// ....
}
...(and then might well turn that into ES5-compliant code, depending on the transpiling settings).

ES6 'import' causing error with Babel

I am trying to make a Poker game using JavaScript es6, but even with babel, when the game is run, the following error is thrown:
Unexpected reserved word { import Hand from './hand';
I have the following in my node_modules:
babel
babel-core
babel-loader
babel-preset-es2015
webpack.config.js:
"use strict";
module.exports = {
context: __dirname,
entry: "./player.js",
output: {
path: "./bundle",
filename: "bundle.js"
},
module: {
loaders: [
{
test: [/\.jsx?$/, /\.js?$/],
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015']
}
}
]
},
devtool: 'source-maps',
resolve: {
extensions: ["", ".js", '.jsx']
}
};
I am trying to simply run player.js to test the constructor:
import Hand from './hand';
export default class Player {
constructor(name) {
this.name = name;
this.hand = dealHand();
}
dealHand() {
Hand.deal();
}
}
let me = new Player("sam");
console.log(`my name is ${me.name}`)
console.log(me.hand);

Categories

Resources