I'm using babel loader with webpack for combining multiple React components. Although I've installed webpack and babel-loader along with its dependencies. I'm getting two errors:
ERROR in ./components/layout.jsx
Module parse failed: /Users/myuser/Desktop/Projects/Demo/Scorecard/SPA/React/components/layout.jsx Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import React from 'react';
|
| class Layout extends React.Component {
# ./build/import.js 15:14-49
ERROR in ./components/topic-list.jsx
Module parse failed: /Users/myuser/Desktop/Projects/Demo/Scorecard/SPA/React/components/topic-list.jsx Line 17: Unexpected token <
You may need an appropriate loader to handle this file type.
| render: function () {
| return (
| <div>
| <div className="row topic-list">
| <SingleTopicBox
# ./build/import.js 11:17-56
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'build');
module.exports = {
entry: APP_DIR + '/import.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: APP_DIR,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
}
],
resolve: {
extensions: ['', '.js', '.jsx']
}
}
};
import.js
import React from 'react';
import ReactDOM from 'react-dom';
import TopicsList from '../components/topic-list.jsx';
import Layout from '../components/layout.jsx';
layout.jsx
import React from 'react';
class Layout extends React.Component {
render() {
return (
<div className="container">
<TopicsList />
</div>
);
}
};
ReactDOM.render(<Layout />, document.getElementById('app'));
Remove include options from your webpack.config.js file. Include folder should be the folder where webpack can find your loader in this case babel loader
I'm not clear about your file structure but it might be the include part in resolve section of your webpack.config.js that results the problem.
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'build');
module.exports = {
entry: APP_DIR + '/import.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: THIS_SHOULD_BE_YOUR_SOURCE_FOLDER,
loader: 'babel',
exclude: /node_modules/,
query: {
presets: ['es2015']
}
}
],
resolve: {
extensions: ['', '.js', '.jsx']
}
}
};
You seem to be missing the React preset for Babel: babel-preset-react
npm install --save-dev babel-preset-react
And add it to your babel-loader presets.
I had the same case and resolved it by removing the exclude part of the webpack rule (since the failing import was an import of an imported npm package that was in the node_modules directory).
So, applying to your example:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'build');
module.exports = {
entry: APP_DIR + '/import.js',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
include: APP_DIR,
loader: 'babel',
// we want the loader to search in node_modules,
// so we comment the line below
// exclude: /node_modules/,
query: {
presets: ['es2015']
}
}
],
resolve: {
extensions: ['', '.js', '.jsx']
}
}
};
Related
In my app.js file I have the following event inside a function where I import another module (same as in the docs) using the lazy-loading technique:
button.onclick = e => import(/* webpackChunkName: "print" */ './print').then(module => {
var print = module.default;
print();
});
And in my webpack config I set up this (besides Babel, SASS loaders, etc):
const path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
watch: true,
entry: {
main: ['babel-polyfill', './src/js/app.js','./src/sass/main.sass']
},
output: {
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, "dist"),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ["babel-preset-env", "babel-preset-stage-0"]
}
}
},
{
test: /\.sass$/,
exclude: /node_modules/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
{
loader: 'sass-loader',
query: {
sourceMap: false,
},
},
],
}),
},
]
}
}
The problem is the path "./print" is from my "src" folder and not from my "dist" folder, where webpack puts all the bundles, so I get a 404 error. If I change the path to "./dist/print" then the webpack build will crash.
Am I missing a webpack configuration?
Edit:
Folder structure:
src
js
app.js
print.js
dist
main.bundle.js
print.bundle.js
You don't have to treat with the modules path in dist folder, only in src folder.
There is two solutions I think :
1/ Specify src path in your import statement :
button.onclick = e => import(/* webpackChunkName: "print" */ './src/js/print').then(module => {
var print = module.default;
print();
});
2/ Personally, What I usually do is to add src folder to resolved paths in config file:
resolve: {
modules: [
path.resolve('./node_modules'),
path.resolve('./src/js')
],
extensions: ['.json', '.js']
},
Your code should then work without changing a line.
I am working on a project that integrates react, redux, and firebase. react-redux-firebase seems to be a convenient tool. However, the code is not being complied successfully. Below is the error, webpack.config.js, .babelrc, and index.js. Thanks for help in advance.
Error message:
ERROR in ./~/react-redux-firebase/src/connect.js
Module parse failed:
/Users/xiqianglin/ucsdflyers/node_modules/react-redux-firebase/src/connect.js
Unexpected token (43:24) You may need an appropriate loader to handle this file type.
| }
|
| static contextTypes = {
| store: PropTypes.object.isRequired
| };
# ./~/react-redux-firebase/src/index.js 1:0-31 # ./src/index.js # multi ./src/index.js
/****And there are other similar errors, all "...appropriate loader..." ***/
webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
});
module.exports = {
entry: [
'./src/index.js'
],
module: {
loaders: [
{test: /\.js$/,
exclude: /node_modules/,
loader:'babel-loader'}
]
},
resolve: {
extensions: [".js", ".jsx", ".es6"]
},
output: {
filename: "index_bundle.js",
path: __dirname + '/dist'
},
plugins: [HTMLWebpackPluginConfig]
};
.babelrc
{
"presets": ["react", "es2015"]
}
index.js
/*Other Imports...*/
import { firebaseStateReducer } from 'react-redux-firebase'; //This is the line causing error
ReactDOM.render(
<Provider>
<App/>
</Provider>,
documeng.getElementById('app')
)
Duble check that you npm install-ed all your dependencies.
Then if that doesn't work, try this:
npm install babel-preset-es2015
and add the a query for es2015 after your exclude
{
test: /\.js$/,
exclude: /node_modules/,
loader:'babel-loader',
query: {
presets: ['es2015']
}
}
If you need to include a specific node module, try including your source directory and that specific node module folder to be parsed by babel-loader.
So instead of the exclude: /node_modules/, try
include: [
path.resolve(__dirname, "src"),
path.resolve(__dirname, "node_modules/react-redux-firebase")
]
I'm newbie in webpack and react. hope you can help me.
I faced a problem and can't find any working solution in the internet.
When i trying to run webpack-dev-serverI geting "Module not found: Error: Cannot resolve module 'components/app'" error all the time.
Here my files structure.
root/ webpack.config.js
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: [
'webpack-dev-server/client?http://127.0.0.1:8080/',
'webpack/hot/only-dev-server',
'./src'
],
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js'
},
resolve: {
moduleDirectories: ['node_modules', 'src'],
extensions: ['', '.js']
},
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
root/ .babelrc
{
presets: ["react", "es2015"],
plugins: ["react-hot-loader/babel"]
}
root/src/index.js
import React from 'react';
import { render } from 'react-dom';
import App from 'components/app';
render(<App />, document.getElementById('app'));
root/src/components/app.js
import React from 'react';
export default class App extends React.component {
render() {
return (
<div>
<h1>Hello There</h1>
</div>
);
}
}
I agree with Robert Moskal answer, use Relative path to import, at the same time if you really want the absolute path to work you may have to add one more line in your webpack.config.js inside your resolve section of it add this below line
root: path.resolve('./src'),
this will help to resolve the root and you can easily import using absolute path from folders inside the src folder. I would show you my sample webpack.config.js below
'use strict';
const path = require('path');
const loaders = require('./webpack/loaders');
const plugins = require('./webpack/plugins');
const applicationEntries = process.env.NODE_ENV === 'development'
? ['webpack-hot-middleware/client?reload=true']
: [];
const mainEntry = process.env.NODE_ENV === 'development'
? './src/sample/index.tsx'
: './src/lib/index.tsx';
module.exports = {
entry: [mainEntry].concat(applicationEntries),
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
publicPath: '/',
sourceMapFilename: '[name].js.map',
chunkFilename: '[id].chunk.js',
},
devtool: process.env.NODE_ENV === 'production' ?
'source-map' :
'inline-source-map',
resolve: {
root: path.resolve('./src'),
extensions: [
'',
'.webpack.js',
'.web.js',
'.tsx',
'.ts',
'.js',
'.json',
],
},
plugins: plugins,
devServer: {
historyApiFallback: { index: '/' },
},
module: {
preLoaders: [
loaders.tslint,
],
loaders: [
loaders.tsx,
loaders.html,
loaders.css,
loaders.scss,
loaders.eot,
loaders.svg,
loaders.ttf,
loaders.woff,
loaders.json,
{
test: /\.png$/,
loader: 'url-loader',
query: { mimetype: 'image/png' },
},
],
},
externals: {
'react/lib/ReactContext': 'window',
'react/lib/ExecutionEnvironment': true,
'react/addons': true,
},
};
You need to specify a relative path to app in your index.js file. So
import App from './components/app'
Without the relative path notation, the module import system looks in the node_modules directory.
You're looking for module aliasing. The resolve section of your config should look something like:
const path = require('path');
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
extensions: ['', '.js'],
alias: {
components: path.resolve(__dirname, 'src/components/')
}
}
This is equivalent to the paths option in TypeScript config files.
If I add .jsx to require('./StringOption') it works but I thought the resolve section of my webpack.config.js is supposed to allow me to require with no extension. What am I doing wrong?
Also why do I need ./ infront when it resides in the same directory as index.jsx?
Error message after running webpack:
ERROR in ./src/index.jsx
Module not found: Error: Cannot resolve module 'StringOption' in /Users/Mike/packages/chrome-extension-options/src
# ./src/index.jsx 5:19-42
index.js:
'use strict'
var React = require('react')
var ReactDOM = require('react-dom')
var StringOption = require('./StringOption');
ReactDOM.render(<StringOption id="test" name="Test" />, document.getElementById('content'))
webpack.config.js file:
var path = require("path");
module.exports = {
entry: './src/index.jsx',
output: {
path: path.resolve(__dirname, "dist"),
filename: 'index.js'
},
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'jsx-loader',
exclude: /node_modules/
}
]
},
externals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
resolve: {
extensions: ['', '*.js', '*.jsx']
}
};
Directory structure:
- src/
- index.jsx
- StringOption.jsx
- dist/
- index.js
- react.js
- react-dom.js
First of all ./StringOption says that it should search in the same directory. Unlike other places we need to specify from where we need to import a file in react jsx.
Secondly,
In resolve you need not use resolve explicitly, just use babel-loader or else use resolve as
resolve: {
extensions: ['', '.js', '.jsx']
}
or
module: {
loaders: [
{
test: /\.jsx$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
include the following in your webpack.config.js so that you need not to worry about js and jsx extension.
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
// include: __dirname + '/src',
include: path.join(__dirname, '/src'),
loader: 'babel-loader',
query: {
presets: ['react','es2015']
}
}]
Webpack is slick... If only I could get it to work. I have two files.
App.js
App.scss
I want to import the styles from App.scss and use them in App.js
Here is my code.
// App.js
import React, {Component} from 'react';
import s from './App.scss';
class App extends Component {
render() {
return (
<div className={s.app}>
</div>
);
}
}
console.log('what is in s ' + JSON.stringify(s));
export default App;
And Sass file.
// App.scss
.app {
width: 100%;
height: 100%;
background-color: blue;
}
Console shows that s is an empty object. I would expect to see {app: ...}.
Weback is setup like this.
// webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: [
'./src/client',
'webpack-dev-server/client?http://localhost:8080',
'webpack/hot/dev-server'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
module: {
loaders: [
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
{
test: /\.js$/,
loader: 'babel-loader',
include: path.join(__dirname, 'src')
}]
},
devServer: {
contentBase: './dist',
hot: true
}
};
No errors from webpack. No errors in the console.
After much searching I found this Github issue. Solution is to change this line in webpack.config.js
loaders: ['style', 'css', 'sass']
to
loader: 'style!css?modules!sass'