Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootstrap ReactJS and WebPack #57

Closed
justjacksonn opened this issue Jun 24, 2015 · 4 comments
Closed

Bootstrap ReactJS and WebPack #57

justjacksonn opened this issue Jun 24, 2015 · 4 comments

Comments

@justjacksonn
Copy link

You have a pretty good bit on CSS with your book, but Bootstrap in particular seems to be a pretty popular CSS framework with ReactJS. I found various bits of info on the net but could not get it to work with your configuration in the book and what I found. I installed the react-bootstrap plugin and can use the components, but the style stuff just keeps on giving me errors when including the various loaders and such. It would be great if you could add this one last section around reactjs bootstrap and webpack to your styling chapter. Or just point me to the right info to make it work. :)

@bebraw
Copy link
Member

bebraw commented Jun 24, 2015

I can cover these sort of things at the styling chapter, yes. Generally it seems safest to use some wrapper like react-bootstrap. I know at least Pure has one and it isn't difficult to wrap components using React. Looks like even Foundation has one. And then there are tons of others that are React specific.

I tried react-bootstrap against my boilerplate and it seemed just work. Would it be possible for you to setup a little project to study? I'm curious to see what kind of errors you are getting.

@justjacksonn
Copy link
Author

Hi Juho,

I am not entirely sure why I am getting an error right now. Whenever I
import css, or require css, it fails. Unless I mistyped something in the
config files, it should be identical. Early on the CSS was working. I could
load main.css and change it's color and the background changed. I think
when I added all the linting stuff and/or rules it broke. There is a
whopping lot to that chapter on the building of all this stuff. Far above
my knowledge right now, I mostly copy/pasted, but the webpack config file
is pretty robust and to be honest, I just want to have it working so I can
crank out two things.. the "dev" mode to quickly build/watch changes.. and
then a single bundle.js that I can include in my java/JEE application and
deploy in my JEE container. I am a little confused with regards to the
index.html that includes just bundle.js.. if that is all I need to do and
does that handle the inclusion of all the .css files, any external .js
files, etc. For example, I wanted to make my own AJAX request library
(using very plain javascript stuff), but when I try to use it in one of the
React components, the JS linting system throws errors due to a variable or
declared function not used.. and then my app breaks. I am sure there must
be a way to include some old school JS file full of function() calls that I
can then use in my React components, but as of yet I can't get past the
linting systems causing breaks. I do like the linting aspect of it.. it's
very cool to keep my code clean and consistent, but I am not knowledgeable
enough yet with webpack and how/why these things break.

So my issues are that including main.css breaks and no longer works and
including my own custom .js file breaks due to linting as well.

I tried to integrate the react-bootstrap with some code I found on the web
around webpack, react and bootstrap. Basically said to include the .css
file, which I tried via main.jsx with an import
../styleshetts/bootstrap.css and that fails miserably as well. I require
react-bootstrap and that works fine, but no style is applied to the
components due to the failure.

The Css shows CssSyntaxError, something like:

ERROR in ./~/css-loader!./app/stylesheets/main.css

My webpack.config.js file:

'use strict';

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var merge = require('./lib/merge');

var TARGET = process.env.TARGET;
var ROOT_PATH = path.resolve(__dirname);

var common = {
entry: [
path.join(ROOT_PATH, 'app/main.jsx')
],
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: path.resolve(ROOT_PATH, 'build'),
filename: 'bundle.js'
},
module: {
preLoaders: [
{
test: /.jsx$/,
// define an include so we check just the files we need
include: path.join(ROOT_PATH, 'app'),
loader: 'jshint',
}
],
loaders: [
{ test: /.css$/, loaders: ['style', 'css']},
{ test: /.(svg|ttf|eot|woff|woff2)$/, loader: 'url?limit=100000' },
{ test: /.(jpg|png)$/, loader: "file" }
]
}
};

var mergeConfig = merge.bind(null, common);

if (TARGET === 'build') {
module.exports = mergeConfig({
module: {
loaders: [
{
test: /.css$/,
loader: ExtractTextPlugin.extract('style', 'css')
}
]
},
plugins: [
new ExtractTextPlugin('style.css'),
new webpack.DefinePlugin({
'process.env': {
// This has effect on the react lib size
'NODE_ENV': JSON.stringify('production'),
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new HtmlWebpackPlugin({
title: "TEST"
})
]
});
}

if (TARGET === 'dev') {
var IP = '0.0.0.0';
var PORT = 8080;

module.exports = mergeConfig({
    ip: IP,
    port: PORT,
    entry: [
        'webpack-dev-server/client?http://' + IP + ':' + PORT,
        'webpack/hot/only-dev-server' // only-dev-server
    ],
    module: {
        preLoaders: [
            {
                test: /\.jsx?$/,
                // we are using `eslint-loader` explicitly since
                // we have ESLint module installed. This way we
                // can be certain that it uses the right loader
                loader: 'eslint-loader',
                include: path.join(ROOT_PATH, 'app'),
            },
        ],
        loaders: [
            {
                test: /\.jsx?$/,
                loaders: ['react-hot', 'babel'],
                include: path.join(ROOT_PATH, 'app')
            }
        ]
    },
    output: {
        path: __dirname,
        filename: 'bundle.js',
        publicPath: '/'
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin(),
        new HtmlWebpackPlugin()
    ]
});

}

package.json:

{
"name": "test-react-app",
"version": "1.0.0",
"description": "ReactJS Test App",
"main": "index.js",
"scripts": {
"test": "test",
"build": "TARGET=build webpack",
"start": "TARGET=dev node dev-server/server.js",
"lint": "eslint . --ext .js --ext .jsx || true",
"lint-css": "csslint app/stylesheets --quiet"
},
"author": "me",
"license": "ISC",
"devDependencies": {
"babel-core": "^5.6.4",
"babel-eslint": "^3.1.17",
"babel-loader": "^5.1.4",
"css-loader": "^0.15.1",
"csslint": "^0.10.0",
"csslint-loader": "^0.2.0",
"eslint": "^0.23.0",
"eslint-loader": "^0.14.0",
"eslint-plugin-react": "^2.5.2",
"extract-text-webpack-plugin": "^0.8.2",
"file-loader": "^0.8.4",
"html-webpack-plugin": "^1.5.2",
"jshint": "^2.8.0",
"jshint-loader": "^0.8.3",
"lodash": "^3.9.3",
"node-libs-browser": "^0.5.2",
"path": "^0.11.14",
"react-bootstrap": "^0.23.5",
"react-hot-loader": "^1.2.7",
"style-loader": "^0.12.3",
"url-loader": "^0.5.6",
"webpack": "^1.9.11",
"webpack-dev-server": "^1.9.0"
},
"dependencies": {
"bootstrap": "^3.3.5",
"bootstrap-webpack": "0.0.3",
"react": "^0.13.3",
"react-router": "^0.13.3",
"superagent": "^1.2.0"
}
}

main.jsx:

import React from 'react';
import App from './components/App';

//require('css!./stylesheets/main.css');

// below fails.. if I remove my app works..just no style

require('./stylesheets/main.css');

main();

function main() {
var app = document.createElement('div');
document.body.appendChild(app);
React.render(, app);
}

Not sure what else I can share that may help. Any thoughts on my
config and why css may be failing would be great.

@justjacksonn
Copy link
Author

For the life of me..I don't know what I did..but it works now. I absolutely
hate when this happens.. I suppose I should be happy bootstrap is working
now.. but I like to know why it works or doesn't work so I can repeat and
write about it. The only thing I changed was my React components.. I added
a separate Home link use react-router (was already using react-router).
Anyway.. fingers crossed it keeps on working!

On Wed, Jun 24, 2015 at 10:58 AM, Justin Jackson justjacksonn@gmail.com
wrote:

Hi Juho,

I am not entirely sure why I am getting an error right now. Whenever I
import css, or require css, it fails. Unless I mistyped something in the
config files, it should be identical. Early on the CSS was working. I could
load main.css and change it's color and the background changed. I think
when I added all the linting stuff and/or rules it broke. There is a
whopping lot to that chapter on the building of all this stuff. Far above
my knowledge right now, I mostly copy/pasted, but the webpack config file
is pretty robust and to be honest, I just want to have it working so I can
crank out two things.. the "dev" mode to quickly build/watch changes.. and
then a single bundle.js that I can include in my java/JEE application and
deploy in my JEE container. I am a little confused with regards to the
index.html that includes just bundle.js.. if that is all I need to do and
does that handle the inclusion of all the .css files, any external .js
files, etc. For example, I wanted to make my own AJAX request library
(using very plain javascript stuff), but when I try to use it in one of the
React components, the JS linting system throws errors due to a variable or
declared function not used.. and then my app breaks. I am sure there must
be a way to include some old school JS file full of function() calls that I
can then use in my React components, but as of yet I can't get past the
linting systems causing breaks. I do like the linting aspect of it.. it's
very cool to keep my code clean and consistent, but I am not knowledgeable
enough yet with webpack and how/why these things break.

So my issues are that including main.css breaks and no longer works and
including my own custom .js file breaks due to linting as well.

I tried to integrate the react-bootstrap with some code I found on the web
around webpack, react and bootstrap. Basically said to include the .css
file, which I tried via main.jsx with an import
../styleshetts/bootstrap.css and that fails miserably as well. I require
react-bootstrap and that works fine, but no style is applied to the
components due to the failure.

The Css shows CssSyntaxError, something like:

ERROR in ./~/css-loader!./app/stylesheets/main.css

My webpack.config.js file:

'use strict';

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var merge = require('./lib/merge');

var TARGET = process.env.TARGET;
var ROOT_PATH = path.resolve(__dirname);

var common = {
entry: [
path.join(ROOT_PATH, 'app/main.jsx')
],
resolve: {
extensions: ['', '.js', '.jsx']
},
output: {
path: path.resolve(ROOT_PATH, 'build'),
filename: 'bundle.js'
},
module: {
preLoaders: [
{
test: /.jsx$/,
// define an include so we check just the files we need
include: path.join(ROOT_PATH, 'app'),
loader: 'jshint',
}
],
loaders: [
{ test: /.css$/, loaders: ['style', 'css']},
{ test: /.(svg|ttf|eot|woff|woff2)$/, loader: 'url?limit=100000' },
{ test: /.(jpg|png)$/, loader: "file" }
]
}
};

var mergeConfig = merge.bind(null, common);

if (TARGET === 'build') {
module.exports = mergeConfig({
module: {
loaders: [
{
test: /.css$/,
loader: ExtractTextPlugin.extract('style', 'css')
}
]
},
plugins: [
new ExtractTextPlugin('style.css'),
new webpack.DefinePlugin({
'process.env': {
// This has effect on the react lib size
'NODE_ENV': JSON.stringify('production'),
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new HtmlWebpackPlugin({
title: "TEST"
})
]
});
}

if (TARGET === 'dev') {
var IP = '0.0.0.0';
var PORT = 8080;

module.exports = mergeConfig({
    ip: IP,
    port: PORT,
    entry: [
        'webpack-dev-server/client?http://' + IP + ':' + PORT,
        'webpack/hot/only-dev-server' // only-dev-server
    ],
    module: {
        preLoaders: [
            {
                test: /\.jsx?$/,
                // we are using `eslint-loader` explicitly since
                // we have ESLint module installed. This way we
                // can be certain that it uses the right loader
                loader: 'eslint-loader',
                include: path.join(ROOT_PATH, 'app'),
            },
        ],
        loaders: [
            {
                test: /\.jsx?$/,
                loaders: ['react-hot', 'babel'],
                include: path.join(ROOT_PATH, 'app')
            }
        ]
    },
    output: {
        path: __dirname,
        filename: 'bundle.js',
        publicPath: '/'
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NoErrorsPlugin(),
        new HtmlWebpackPlugin()
    ]
});

}

package.json:

{
"name": "test-react-app",
"version": "1.0.0",
"description": "ReactJS Test App",
"main": "index.js",
"scripts": {
"test": "test",
"build": "TARGET=build webpack",
"start": "TARGET=dev node dev-server/server.js",
"lint": "eslint . --ext .js --ext .jsx || true",
"lint-css": "csslint app/stylesheets --quiet"
},
"author": "me",
"license": "ISC",
"devDependencies": {
"babel-core": "^5.6.4",
"babel-eslint": "^3.1.17",
"babel-loader": "^5.1.4",
"css-loader": "^0.15.1",
"csslint": "^0.10.0",
"csslint-loader": "^0.2.0",
"eslint": "^0.23.0",
"eslint-loader": "^0.14.0",
"eslint-plugin-react": "^2.5.2",
"extract-text-webpack-plugin": "^0.8.2",
"file-loader": "^0.8.4",
"html-webpack-plugin": "^1.5.2",
"jshint": "^2.8.0",
"jshint-loader": "^0.8.3",
"lodash": "^3.9.3",
"node-libs-browser": "^0.5.2",
"path": "^0.11.14",
"react-bootstrap": "^0.23.5",
"react-hot-loader": "^1.2.7",
"style-loader": "^0.12.3",
"url-loader": "^0.5.6",
"webpack": "^1.9.11",
"webpack-dev-server": "^1.9.0"
},
"dependencies": {
"bootstrap": "^3.3.5",
"bootstrap-webpack": "0.0.3",
"react": "^0.13.3",
"react-router": "^0.13.3",
"superagent": "^1.2.0"
}
}

main.jsx:

import React from 'react';
import App from './components/App';

//require('css!./stylesheets/main.css');

// below fails.. if I remove my app works..just no style

require('./stylesheets/main.css');

main();

function main() {
var app = document.createElement('div');
document.body.appendChild(app);
React.render(, app);
}

Not sure what else I can share that may help. Any thoughts on my config and why css may be failing would be great.

@bebraw
Copy link
Member

bebraw commented Jun 25, 2015

I set up a project based on your code. I can confirm the issue. It looks like it has something to do with the newest version of css-loader. Once I locked its version ("css-loader": "0.14.5",), got rid of the old one (rm -rf node_modules/css-loader) and reinstalled it (npm i) the CSS import started working again.

Looks like other people are having some problems with the new version too. See webpack-contrib/css-loader#84 .

Sometimes dependencies get broken like this and it's definitely nasty. Just yesterday I encountered something similar with Babel as a dependency of it (acorn) had gotten broken...

I'm closing this. Thanks for the report, though. It probably would be a good idea to add something about this to possible debugging chapter. I set up an issue for that.

@bebraw bebraw closed this as completed Jun 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants