jQuery needed for Bootstrap in React project - javascript

I am developing a React.js project where instead of using React-Bootstrap, I am loading the CSS of Bootstrap into my project. I am now needing to import the jQuery so that I can use dropdown menus etc.
Entry point file (index.js) - in the hope it would work
'use strict'
import React from 'react'
import { Route, Router, IndexRoute, browserHistory } from 'react-router'
import { render } from 'react-dom'
// Pages
import Main from './pages/main/main'
import Home from './pages/home/home'
import About from './pages/about/about'
window.jQuery = window.$ = require('jquery/dist/jquery.min')
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'
import '../node_modules/bootstrap/dist/js/bootstrap.min.js'
render((
<Router history={browserHistory}>
<Route name='home' path='/' component={Main}>
<IndexRoute component={Home} />
<Route name='about' path='about' component={About} />
</Route>
</Router>), document.getElementById('app'))
Webpack file
'use strict'
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: [
'./browser/index'
],
output: {
path: path.join(__dirname, 'public', 'js'),
filename: 'bundle.js',
publicPath: '/public/js/'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{ test: /\.js$/,
loader: 'babel-loader',
query: {
presets: [ 'es2015', 'react' ]
},
include: path.join(__dirname, 'browser')
},
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
{test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000'},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=application/octet-stream'},
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url?limit=10000&mimetype=image/svg+xml'},
{ test: require.resolve('jquery'), loader: 'imports?jQuery=jquery' }
]
}
}
The error appears in Chrome Dev tools: 'Bootstrap's Javascript requires jQuery'. I'm wondering whether perhaps I am missing something in terms on loaders in the webpack file, or need an import statement in the entry file?

Please make sure you have installed 'imports-loader', (npm install --save imports-loader). And in module.exports try this:
{ test: /bootstrap.+\.(jsx|js)$/, loader: 'imports?jQuery=jquery,$=jquery,this=>window' }
The really nice post regarding it I've found here: http://reactkungfu.com/2015/10/integrating-jquery-chosen-with-webpack-using-imports-loader/

Unfortunately provided solution doesn't work for me. In the case above Bootstrap and jQuery are both installed as npm dependencies under node_modules directory? I'm using WebPack 2, so I have converted the loader element as follows:
{
test: /bootstrap.+\.(jsx|js)$/,
use: 'imports-loader?jQuery=jquery,$=jquery,this=>window',
exclude: /node_modules/
}

Related

Cannot import react js component

I trying to import a react component to jsx file but it throws this exception:
This is my main code:
import React, { Component } from "react";
import Sidebar from "./Sidebar";
class App extends Component{
render(){
return (
<Sidebar/>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
and this is my Sidebar component:
import React, { Component } from "react";
export default class Sidebar extends Component{
render(){
return (
<h1>Hello Sidebar</h1>
);
}
}
My folders structure:
I post simpler version which I know does work:
./index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import Application from './components/Application'
ReactDOM.render(<Application />, document.getElementById('root'));
./components/Application :
import React from 'react';
class Application extends React.Component {
render() {
return (
<div className="App">
My Application!
</div>
);
}
}
export default Application;
This should be everything needed to make it work.
If you want to shorten the above even more, by removing the export line at the bottom, a less traditional approach would be defining the class like this...
export default class Application extends React.Component {...}
Looks like you haven't added rule for .jsx file in webpack.config.js.
Since you have both .js and .jsx files you need to tell webpack to load files with extension .js and .jsx. Add below config to webpack.config.js in rules section
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader"
}
And add extensions like
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
}
Below is the working webpack.config.js file for your ref
module.exports = {
target: "web",
entry: [
"whatwg-fetch",
'webpack-dev-server/client',
'webpack/hot/only-dev-server',
'babel-polyfill',
"./src/index.js"
],
output: {
path: __dirname + 'build',
publicPath: '/',
filename: "bundle.js"
},
plugins: [new HtmlWebpackPlugin({
template: "index.html"
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.jsx$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new webpack.HotModuleReplacementPlugin(),
// enable HMR globally
new webpack.NoEmitOnErrorsPlugin()
],
module: {
rules: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
{
test: /\.(eot|ttf)$/,
loader: "file-loader",
},
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
}
]
},
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
},
devServer: {
watchOptions: {
// Needed for Windows Subsystem for Linux dev environment:
poll: true
},
contentBase: './build'
},
devtool: "cheap-module-eval-source-map",
node: {
child_process : "empty",
fs: "empty"
}
};

React-router cannot get component when manually modifying url or page refresh [duplicate]

I have the following webpack config file:
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/client/public');
var APP_DIR = path.resolve(__dirname, 'src/client/app');
var config = {
entry: [
APP_DIR + '/config/routes.jsx',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080'
],
output: {
publicPath: 'http://localhost:8080/src/client/public/'
},
module : {
loaders : [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: APP_DIR,
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.scss$/,
loaders: [ 'style', 'css', 'sass' ]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
}
};
module.exports = config;
all I am trying to do is run my app on localhost, however when I hit: "http://localhost:8080/src/client/home" (as per my routes.jsx and after running webpack-dev-server)
import React from 'react';
import { Route, Router, browserHistory } from 'react-router';
import ReactDOM from 'react-dom';
import Wrapper from './../components/wrapper.jsx';
import Home from './../components/home.jsx';
import Projects from './../components/projects.jsx';
import SingleProject from './../components/projectContent/singleProject.jsx';
import About from './../components/aboutUs.jsx'
ReactDOM.render((
<Router history={browserHistory} >
<Route path="/" component={Wrapper} >
<Route path="home" component={Home} />
<Route path="projects" component={Projects} />
<Route path="projects/:id" component={SingleProject} />
<Route path="about" component={About} />
</Route>
</Router>
), document.getElementById('app'));
I get
"Cannot GET /src/client/home".
First thing you have mentioned in your routes as the home component to have path /home. So you need to visit http://localhost:8080/home. Also if you try to access this url directly, it will give you this error since you are using browserHistory. If you want you can use hashHistory or HashRouter in react-router v4, in which case you will need to visit http://localhost:8080/#/home. If you want to continue using browserHistory or BrowserRouter as in react-router v4, then you will need to add historyApiFallback: true in you webpack
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'src/client/public');
var APP_DIR = path.resolve(__dirname, 'src/client/app');
var config = {
entry: [
APP_DIR + '/config/routes.jsx',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080'
],
output: {
publicPath: 'http://localhost:8080/src/client/public/'
},
devServer: {
historyApiFallback: true
},
module : {
loaders : [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: APP_DIR,
exclude: /node_modules/,
query: {
presets: ['es2015']
}
},
{
test: /\.scss$/,
loaders: [ 'style', 'css', 'sass' ]
},
{
test: /\.json$/,
loader: "json-loader"
}
]
}
};
module.exports = config;
You need to add this in your webpack settings:
devServer: {
historyApiFallback: true,
},
And start your server like this:
webpack-dev-server --config webpack.config.js
Because you want React-Route to handle the route instead of your server. So no matter what the url is it should goes to index.html.

React router can't find page after page refresh [duplicate]

This question already has answers here:
React-router with BrowserRouter / browserHistory doesn't work on refresh
(2 answers)
Closed 5 years ago.
My App is displaying a list of books with links to a detail page about the book.
When I am on the home component where the book list is rendered and click on a link to get to a specific book, the page is loading correctly...
But when I refresh the page, there is a 404 - Page not found error
(I'm using react-router v4, Node v6.11.1, Express v4.15.2)
React Router setup:
import { BrowserRouter as Router } from 'react-router-dom'
import { Switch, Route } from 'react-router-dom'
class App extends Component {
render() {
return (
<div>
<MyNavbar/>
<div style={{paddingTop: "5rem"}}>
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/book/:id' component={BookPage}/>
</Switch>
</div>
</div>
)
}
}
ReactDOM.render((
<Router>
<App />
</Router>
), document.getElementById('root'))
This is my webpack config:
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
app: './src/app.js'
},
output: {
filename: 'public/dist/bundle.js',
sourceMapFilename: 'public/dist/bundle.map.js'
},
devtool: '#source-map',
module: {
loaders: [
{
loader: 'babel-loader',
test: /\.js?$/,
exclude: /(node_modules)/,
query: {
presets: ['react', 'es2015']
}
}, {
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
]
},
{
test: /\.(png|jpg|)$/,
loader: 'url-loader?limit=200000&name=./imgs/[hash].[ext]'
}
]
},
}
this is the doc~
if you are use webpack-dev-server
if you write the webpack-dev-server config on webpack.config.js
You should add this historyApiFallback: true to devServer on your webpack config.
This will return index.html when 404.
devServer: {
...
historyApiFallback: true
}
if you only use cli,do this
webpack-dev-server --history-api-fallback
if you use the node express server.js,see here
If production, you can edit the server config, make every request,return index.html, sure, exclude static files and api requst~
Sorry. I write this on mobile phone.

“You may need an appropriate loader to handle this file type” with Webpack and Babel

I'm upgrading from an arcane version of webpack to webpack 2 and I'm getting an error:
ERROR in ./scripts/app.js
Module parse failed: /Users/zackshapiro/dev/glimpse-electron/node_modules/eslint-loader/index.js!/Users/zackshapiro/dev/glimpse-electron/scripts/app.js Unexpected token (32:4)
You may need an appropriate loader to handle this file type.
|
| render((
| <Provider store={store}>
| <Home />
| </Provider>
# multi (webpack)-dev-server/client?http://localhost:8081 webpack/hot/dev-server ./scripts/app.js
My webpack.config.js looks like this:
const webpack = require('webpack');
const path = require('path');
console.log(path.resolve(__dirname, 'public/built'));
console.log("we here");
module.exports = {
entry: {
app: ['webpack/hot/dev-server', './scripts/app.js']
},
output: {
// path: './public/built',
path: path.resolve(__dirname, 'public/built'),
filename: 'bundle.js',
publicPath: 'http://localhost:8080/built/'
},
devServer: {
contentBase: './public',
publicPath: 'http://localhost:8080/built/'
},
module: {
rules: [
{
test: /\.jsx?$/,
enforce: "pre",
loader: "eslint-loader",
exclude: /node_modules/
},
],
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['react', 'es2015', 'stage-3']
}
},
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.scss$/, loader: 'style-loader!css-loader!sass-loader'},
{ test: /\.(ttf|eot|otf|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.IgnorePlugin(new RegExp("^(fs|ipc)$")),
new webpack.LoaderOptionsPlugin({
options: {
eslint: {
failOnWarning: false,
failOnError: true
}
}
})
]
}
And my app.js looks like this:
require('../styles/main.scss');
require('../styles/menubar.scss');
require('../styles/panel.scss');
require('../styles/sky.scss');
require('../styles/dock.scss');
require('../styles/sector.scss');
require('../styles/slot.scss');
require('../styles/element_builder.scss');
'use strict';
import 'babel-polyfill';
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {compose, createStore, applyMiddleware} from 'redux';
import createSagaMiddleware from 'redux-saga';
import reducer from './entities/reducers';
import sagas from './entities/sagas';
import Home from './containers/home';
const sagaMiddleware = createSagaMiddleware();
const composedCreateStore = compose(applyMiddleware(sagaMiddleware))(createStore);
const store = composedCreateStore(reducer, {});
sagaMiddleware.run(sagas);
render((
<Provider store={store}>
<Home />
</Provider>
), document.getElementById('content'));
I don't have a .babelrc file in my root directory because I have that object in my loaders in webpack.config.js
Any suggestions on how to fix this would be very welcome. Thanks!
module.rules replaces module.loaders in Webpack 2, so it's possible that by providing both Webpack isn't using module.loaders (which is there for backwards-compatibility) at all - try moving the rules you currently have in module.loaders into module.rules instead.
Edit: peeking inside the current version of Webpack's NormalModuleFactory, this is what it's doing:
this.ruleSet = new RuleSet(options.rules || options.loaders);

Webpack resolve extension "Module not found"

Warning: I'm pretty new to webpack, please be gentle
Okay so I'm trying to set up webpack, and I got everything working fine with es2015 and imports with webpack. I'm running into an issue where now I'm trying to add the extensions to resolve so that I don't have to declare the file extension, but it always says that it can't find the file or module. Any idea why this could be? Here's my index.jsx and my webpack.config.js
// index.jsx
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './components/App'
import configureStore from './store/configureStore.js'
const store = configureStore()
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app')
)
Here's the webpack.config:
// webpack.config
var path = require('path')
var webpack = require('webpack')
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./src/javascripts/index.jsx'
],
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/public/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
__DEV__: process.env.NODE_ENV !== 'production'
})
],
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: [ 'react-hot', 'babel-loader' ],
include: path.join(__dirname, '/src')
},
{
test: /\.scss$/,
loader: [ 'style', 'css', 'sass' ]
},
{
test: /\.json$/,
loader: 'json'
}
],
preLoaders: [
{ test: /\.js$/, loader: 'source-map-loader' }
],
resolve: {
root: [
path.resolve(path.join(__dirname, 'src', 'stylesheets')),
path.resolve(path.join(__dirname, 'src', 'javascripts'))
],
alias: {
'#style': path.resolve(path.join(__dirname, 'src', 'stylesheets')),
'#script': path.resolve(path.join(__dirname, 'src', 'javascripts'))
},
extensions: [
'',
'.webpack.js',
'.web.js',
'.jsx',
'.js',
'.scss'
]
}
}
};
As I said, if I change line 5 in index.jsx from import App from './components/App' to import App from './components/App.jsx', it works and I have no idea why. Any thoughts?
Your module is wrapping around your resolve, which is ruining the config file. If the resolve isn't there then Webpack can't resolve your extension, forcing you to add the extension. You should always indent uniformly to keep track of and prevent these types of errors.
When you import it without an extension, Webpack doesn't know how to resolve the extension so it can't correctly load it. You have to specify .jsx so then Babel comes in and imports it as a .jsx explicitly.

Categories

Resources