Webpack throws syntax error for JSX - javascript

When I attempted to use webpack to compile my react jsx code, I received the following error:
ERROR in ./client/index.js
Module parse failed: C:\Users\Gum-Joe\Documents\Projects\bedel/client\index.js Unexpected token (6:11)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (6:11)
at Parser.pp.raise (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:920:13)
at Parser.pp.unexpected (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:1483:8)
at Parser.pp.parseExprAtom (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:330:12)
at Parser.pp.parseExprSubscripts (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:225:19)
at Parser.pp.parseMaybeUnary (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:204:17)
at Parser.pp.parseExprOps (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:151:19)
at Parser.pp.parseMaybeConditional (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:133:19)
at Parser.pp.parseMaybeAssign (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:110:19)
at Parser.pp.parseExpression (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:86:19)
at Parser.pp.parseReturnStatement (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:1854:26)
at Parser.pp.parseStatement (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:1719:19)
at Parser.pp.parseBlock (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:1991:21)
at Parser.pp.parseFunctionBody (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:607:22)
at Parser.pp.parseMethod (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:576:8)
at Parser.pp.parseClassMethod (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:2137:23)
at Parser.pp.parseClass (C:\Users\Gum-Joe\Documents\Projects\bedel\node_modules\acorn\dist\acorn.js:2122:10)
# ./client/index.js 1:0-20
.babelrc:
{
"presets": ["es2015", "react"]
}
webpack.config.js:
// Webpack config
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// Use client as our root
context: __dirname + "/client",
// Entry file
entry: "./index.js",
// Resolve
resolve: {
extensions: ['', '.js', '.jsx']
},
// Output to /build
output: {
path: path.join(__dirname, "build", "js"),
filename: "bundle.js"
},
loaders: [
{ test: /\.jsx$/, exclude: /node_modules/, loader: "babel-loader" }
],
// Plugins
plugins: [
// HTML
new HtmlWebpackPlugin({
title: 'Bedel',
filename: path.join(__dirname, 'views', 'index.ejs'),
template: path.join(__dirname, 'client', 'templates', 'index.ejs')
})
]
};
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render () {
return <p> Hello React</p>;
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
I have installed all the babel presets required, as well as babel-core.
I have looked at the following answers already:
babel-loader jsx SyntaxError: Unexpected token
React, babel, webpack not parsing jsx code
Edit: After commenting out my jsx syntax, the outputting bundle.js does not appear to have been transformed by babel (i.e. I can see ES6 code in it)
Edit: Sorry for the inconvenience, but app.jsx was a solution that I tried that involved putting the logic that should be in index.js into a separate file.
Edit: Here is a list of the solutions I tried that did not work:
Copy .babelrc to client/.babelrc
Change test to test for .js instead of .js
Separate app logic into separate file (app.js)
Put presets to use in webpack config
Also, I have pushed my code to my GitHub repo (https://github.com/Gum-Joe/bedel). Feel free to have a look at it.

You configured the loader to only pass .jsx files through Babel:
test: /\.jsx$/
However, your file has the extension .js. Either rename the file or update the test expression to /\.jsx?$/.
In addition to updating the test, you need to rename .babel.rc to .babelrc (no . before rc). Otherwise Babel thinks that there is no configuration file and won't load any presets.

The loaders property must exist within the module property. Webpack Loaders
module.exports = {
// ...
// Output to /build
output: {
path: path.join(__dirname, "build", "js"),
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.jsx$/, exclude: /node_modules/, loader: "babel-loader" }
]
},
//...
};

You need to use react-preset with babel, like here:
loaders: [{
test: /\.(js|jsx)$/,
loader: 'babel',
query: {
presets: [
'es2015',
'react'
]
}
}]

I'm having this issue as well, and if you're using Windows and Node 6.x, the only workaround I've found for now seems to be to use Node 4 LTS or 5 instead. Without knowing the root cause, the problem seems to stem from some combination of using JSX, Webpack, Babel, Acorn JS, Node 6, and Windows.
https://github.com/coryhouse/pluralsight-redux-starter/issues/2
https://github.com/danmartinez101/babel-preset-react-hmre/issues/32

Can you try wrapping the entire element in brackets "()"?
return (<p>...</p>)

Related

ES6 Webpack Relative imports - Module not found: Error: Cannot resolve module

I'm trying to find some information about Webpack and relative imports when working with ES6 and Babel.
I have an import line in a simple entry point in my app:
// app.es6
import * as sayHello from 'sayHello';
console.log(sayHello());
sayHello.es6 is the same directory as app.es6. (The contents of sayHello.es6 is not significant).
When I run the Webpack compiler via the command line:
$ webpack
I get the following error:
ERROR in ./app/app.es6
Module not found: Error: Cannot resolve module 'sayHello' in /Users/username/Code/projectname/app
This is solved by setting the path to relative:
// app.es6 - note the ./ in the import
import * as sayHello from './sayHello';
console.log(sayHello());
This is a bit of a pain because it's different to the example es6 code on Babel website under the Modules section.
Here is my Webpack config:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: [
'babel-polyfill',
'./app/app.es6'
],
output: {
publicPath: '/',
filename: './dist/app.js'
},
debug: true,
devtool: 'source-map',
module: {
loaders: [
{
test: /\.js|\.es6$/,
exclude: /node_modules/,
loader: 'babel-loader',
query:
{
presets:['es2015']
}
}
]
},
resolve: {
extensions: ['', '.js', '.es6'],
},
};
Question: Does any one know why there is this difference? Or where the relevant information regarding ES6 module imports is in the Webpack documentation?
This is by design, without prefixing it indicates the module should be loaded from node_modules directory. You can set up an alias in your webpack config which would remove the need for relative module imports
resolve: {
alias: {
sayHello: '/absolute/path/to/sayHello'
},
extensions: ['', '.js', '.es6']
}
Then Webpack would fill in the gaps in your import statements and allow you to omit the relative path and import * as sayHello from 'sayHello'; would work throughout your project

Webpack missing loader for bootstrap

I'm trying to use bootstrap through webpack and have installed it using npm. I want to use it in my react project so I've done the below settings but I keep getting the below error:
main.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
const Main = () => (
<div className="container">yo</div>
)
Webpack config
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client',
'./client/pokeapp'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
// js
{
test: /\.js$/,
loaders: ['babel'],
include: path.join(__dirname, 'client')
},
// CSS
{
test: /\.css$/,
include: path.join(__dirname, 'client'),
loader: 'style-loader!css-loader'
},
{ test: /\.(woff|woff2|eot|ttf|svg)$/, loader: 'url'}
]
}
};
Console Error
Module parse failed: /Users/jlei/Desktop/pokeapp/node_modules/bootstrap/dist/css/bootstrap.css Unexpected token (7:5)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (7:5)
at Parser.pp$4.raise (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:2221:15)
at Parser.pp.unexpected (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:603:10)
at Parser.pp.semicolon (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:581:61)
at Parser.pp$1.parseExpressionStatement (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:966:10)
at Parser.pp$1.parseStatement (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:730:24)
at Parser.pp$1.parseTopLevel (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:638:25)
at Parser.parse (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:516:17)
at Object.parse (/Users/jlei/Desktop/pokeapp/node_modules/acorn/dist/acorn.js:3098:39)
at Parser.parse (/Users/jlei/Desktop/pokeapp/node_modules/webpack/lib/Parser.js:902:15)
at DependenciesBlock.<anonymous> (/Users/jlei/Desktop/pokeapp/node_modules/webpack/lib/NormalModule.js:104:16)
# ./client/components/Main.js 27:0-43
What's the unexpected token? Is that due to my loader not working?
I tested your code and there is nothing wrong with the loader However this line include: path.join(__dirname, 'client') is causing the issue if you remove it you can see bootstrap bundling just fine with webpack.
For getting more from webpack you may want to get a separate css file then you can use ExtractTextPlugin to achieve it.
How it work ?
Installation
npm i extract-text-webpack-plugin
Configure it in webpack
{test: /\.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader' })}
and add it in plugin
new ExtractTextPlugin('yourStyle.css')
Now you should have a separate css file in browser instead of every css in style tag
How does it work
It moves every require("style.css") in entry chunks into a separate css output file. So your styles are no longer inlined into the javascript, but separate in a css bundle file (styles.css). If your total stylesheet volume is big, it will be faster because the stylesheet bundle is loaded in parallel to the javascript bundle.
Hope it help you.
you don't have to include bootstrap as an npm module. You can download or use CDN to include bootstrap on your html template. You can then apply it on your component by using 'className' attribute instead of 'class'. Try it.
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css'));
and in your html file:
<link rel="stylesheet" href="/css/bootstrap.min.css">
This method is the same as downloading the bootstrap files to improve latency.

Making a library importable using webpack and babel

I am trying to publish a package on npm (this one) that I am developing using webpack and babel. My code is written in ES6. I have a file in my sources, index.js, that (for the moment) exports one of my library's core components, it simply goes like this:
import TheGamesDb from './scrapers/thegamesdb';
export { TheGamesDb };
I am using webpack and babel to create a dist index.js that is my package's main file. My webpack.config.js goes like this:
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = {
entry: {
index: ['babel-polyfill', './src/index.js'],
development: ['babel-polyfill', './src/development.js']
},
output: {
path: '.',
filename: '[name].js',
library: 'rom-scraper',
libraryTarget: 'umd',
umdNamedDefine: true
},
devtool: 'source-map',
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
]
},
target: 'node',
externals: [nodeExternals()]
};
Now when I load my package in another project and try to import my export TheGamesDb simply like this
import { TheGamesDb } from 'rom-scraper';
I get the error
Uncaught TypeError: Path must be a string. Received undefined
It is to be noted that I am importing my library in electron.
Update: Electron seems to be the main problem here and it is not even my library but a dependency that throws this error (only in Electron)
The problem wasn't any of the things in my question but node-expat not working in electron. I switched to an alternative library and it's all right now.

Error using ES7 async/await with node, webpack and babel-loader

I'm trying to use javascript ES7 syntax on the server using node.js with webpack and babel-loader (es2015 + stage-0 presets). I've gotten it to work with babel-node but when I run webpack I get the following error at the async keyword (9:22 is after the async keyword):
ERROR in ./src/server.js Module parse failed: C:\dev\node-async-sample\src\server.js
Unexpected token (9:22) You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (9:22)
I've put the code on github at https://github.com/qubitron/node-async-sample, any ideas on how to get this to work?
Here is the relevant snippet from src/server.js:
import express from 'express';
import http from 'request-promise';
let server = express();
server.get('/', async function(request, response) {
let result = await http('http://www.google.com');
response.send(result);
});
.babelrc:
{
"presets": [
"es2015",
"node5",
"stage-0"
],
"plugins": [
"transform-runtime"
]
}
and webpack.config.js:
module.exports = {
entry: [
'babel-polyfill',
'./src/server.js'
],
output: {
path: __dirname + '/dist',
filename: 'server_bundle.js'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: __dirname + '/src',
loader: 'babel-loader'
}
]
}
};
I saw a similar issue here but it has a different error message and was fixed in babel:master:
ES7 async await functions with babel-loader not working
Your src path was incorrect. You should never (like never :)) join pathes using string concatenation there is path.join for that.
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
loader: 'babel-loader'
}
BTW, this will fix parsing issue but you still gonna need to handle .json file loading by adding corresponding extension to resolve section and using json-loader
{ test: /\.json$/, loader: 'json-loader' }
Also you'll need to handle missing modules warning. For example fs and net.
So I do recommend you to use babel-cli to precompile server code.
babel src --out-dir dist

Webpack: node_modules/css/index.js didn't return a function

I'm trying out webpack for the first time and used this tutorial to get started and include react.js.
After finishing the steps and installing the style and css module I keep getting an error that the css module didn't return a function.
This is my index.jsx:
/** #jsx React.DOM */
'use strict';
require('../css/normalize.css');
var React = require('react');
var Hello = require('./Test/Hello');
React.render(<Hello />, document.getElementById('content'));
And my webpack config file:
module.exports = {
entry: './ui/src/index.jsx',
output: {
path: __dirname + '/build-ui',
filename: 'app.js', //this is the default name, so you can skip it
//at this directory our bundle file will be available
//make sure port 8090 is used when launching webpack-dev-server
publicPath: 'http://localhost:8090/assets'
},
module: {
loaders: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
{
test: /\.css$/,
loader: "style!css"
},
{
test: /\.scss$/,
loader: "style!css!sass"
}
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
};
When webpack tries to bundle the project it always states the following error:
ERROR in Loader /Users/Johannes/Documents/Development/holmes/node_modules/css/index.js didn't return a function
# ./ui/src/index.jsx 5:0-31
I don't know what to do about that. Has anyone encountered that issue? And how can I solve it?
EDIT: My directory looks as follows:
holmes/
ui/
css/
normalize.css
src/
Test/
Hello.jsx
index.jsx
index.html
package.json
webpack.config.js
This error is caused by a css module inside node_modules. Since you've specified the css-loader in your config, webpack tries to lookup that loader inside node_modules and finds another module called css which doesn't look like a loader (hence the error message).
To avoid confusion you should simply add the -loader postfix to each loader. Omitting the -loader postfix is just a convenience feature by webpack, but unfortunately it's the culprit of that error in your case.
loaders: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.jsx$/,
loader: 'jsx-loader?insertPragma=React.DOM&harmony'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.scss$/,
loader: "style-loader!css-loader!sass-loader"
}
Update: Starting with webpack 2, you can't omit the -loader postfix anymore. We decided to do this to prevent errors like this.
I had a similar issue with react-flexbox-grid. In my case, the solution was installing css-loader and style-loader npm modules:
npm install css-loader style-loader --save-dev
I also came across a similar issue using node-noop.
Fortunately, using null as a replacement worked when I added enzyme and react-addons-test-utils to a project.

Categories