toastr not showing when imported in a jsx file - reactjs

I have a react app that uses webpack to bundle JS and CSS into 1 file and output it into a destination folder. I've recently added toastr to 1 of my jsx file:
import toastr from "toastr";
import "toastr/build/toastr.min.css"
Running the app and viewing the source, i've verified in the browser (viewing the source files) that toastr.min.js is included in the JS bundle and toastr.min.css is included in the CSS bundle. However, the toastr notification doesn't show. There is no error and a scrollbar appears in the right-side for a few seconds so I suspected the toastr code is working, just that the CSS is not properly styling for some reason.
I removed this line:
import "toastr/build/toastr.min.css"
and then directly added this to html
<link rel="stylesheet" type="text/css" href="~/css/toastr.min.css" />
and now it works. But I want to make it work where toastr.min.css is included in the bundle. Is there anything I'm missing?
webpack config
const path = require("path");
const webpack = require("webpack");
const miniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: {
home: "./Scripts/Components/Home/main.js",
login: "./Scripts/Components/Login/main.js",
vendor: [
"jquery",
"react",
"react-dom",
"react-router-dom",
"react-css-modules",
]
},
mode: "development",
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "all",
name: "vendor",
test: "vendor",
enforce: true
}
}
}
},
output: {
publicPath: "/js/",
path: path.join(__dirname, "/wwwroot/js/"),
filename: "[name].bundle.js"
},
devtool: "source-map",
plugins: [
new miniCssExtractPlugin({
filename: "../css/[name].css"
}),
],
module: {
rules: [{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["env", "react"]
}
}
}, {
test: /\.css$/,
use: [{
loader: miniCssExtractPlugin.loader,
}, {
loader: "css-loader",
query: {
modules: true,
localIdentName: "[name]__[local]___[hash:base64:5]"
}
}]
}]
}
};

Related

Webpack 4 configuration for react-toolbox

I try to upgrade my app from webpack 2 to webpack 4.16.5.
Because I want not again end up in a hard to understand some hundreds line config, I start with a minimal config. This is my current:
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const context = path.resolve(__dirname, "app");
module.exports = {
entry: {
home: "./index.js"
},
context,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader"
},
{
loader: "postcss-loader"
},
{
loader: "sass-loader"
}
]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
resolve: {
extensions: [".js", ".jsx", ".css", "json"],
modules: [path.resolve(__dirname, "node_modules"), context]
}
};
But I run in problems importing the CSS files from react-toolbox i.e.:
import Dialog from 'react-toolbox/lib/dialog';
in a js file and also
#import "react-toolbox/lib/button/theme.css";
causes errors like this:
ERROR in ../node_modules/react-toolbox/lib/switch/theme.css (../node_modules/css-loader!../node_modules/postcss-loader/src!../node_modules/sass-loader/lib/loader.js!../node_modules/react-toolbox/lib/switch/theme.css)
Module build failed (from ../node_modules/css-loader/index.js):
Error: composition is only allowed when the selector is single: local class name not in ".disabled", ".disabled" is weird
Does anyone have a working application with wbpack4 and react-toolbox? Also, any hints on what may cause these errors are welcome!
I'm learning react.js with the js stack from scratch tutorial and try to using react-toolbox components.
Finnaly, i have a working demo with webpack 4 and the react-toolbox, it's based on the react-toolbox-example.
This is my settings:
add css-modules related packages
$ npm install postcss postcss-cssnext postcss-import postcss-loader css-loader style-loader
add a postcss.config.js
module.exports = {
plugins: {
'postcss-import': {
root: __dirname,
},
'postcss-cssnext': {}
},
};
add a webpack rule
...
{ test: /\.css$/, use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]--[local]--[hash:base64:8]'
}
},
'postcss-loader'
]},
...
add cmrh.conf.js - Using the css-modules-require-hook for SSR(Optional)
module.exports = {
generateScopedName: '[name]--[local]--[hash:base64:8]'
}
You can see all the settings in here, hope it will work for you.

React app looking for bundle.js in component folder not project root

The errors I get below are shown in the console after I refresh on a nested route (register/email-confirmation). Whereas non-nested routes do not get this error.
I think the main problem is that it's searching for bundle.js and the image in the nested route path, as opposed to the root path.
The errors in my console:
GET http://localhost:3002/register/bundle.js net::ERR_ABORTED
Refused to execute script from 'http://localhost:3002/register/bundle.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
GET http://localhost:3002/register/a5e694be93a1c3d22b85658bdc30008b.png 404 (Not Found)
My webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BUILD_PATH = path.resolve( __dirname, "./client/build" );
const SOURCE_PATH = path.resolve( __dirname, "./client/src" );
const PUBLIC_PATH = "/";
...
module.exports = {
devtool: 'eval-source-map',
context: SOURCE_PATH,
entry: ['babel-polyfill', SOURCE_PATH + '/index.jsx'],
module: {
rules: [
{
test: /\.jsx?$/,
exclude: [/node_modules/, /server/],
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'react', 'stage-1', 'stage-0', 'stage-2'],
plugins: [
'transform-decorators-legacy',
'transform-es2015-destructuring',
'transform-es2015-parameters',
'transform-object-rest-spread'
]
}
}
},
{
test: /\.scss$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
],
},
output: {
path: BUILD_PATH,
filename: "bundle.js",
},
devServer: {
compress: true,
port: 3002,
historyApiFallback: true,
contentBase: BUILD_PATH,
publicPath: PUBLIC_PATH,
},
plugins: [
new webpack.DefinePlugin(appConstants),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, 'client/src/index.html'),
inject: true
}),
],
watch: true,
}
I don't know about this bug, but I highly recommend using fuse-box
fuse-box is the future of the build systems, within few minutes you will be running your project with high speed hot reload and many others utitilites...
check this react example seed, it's incredibly amazing..

WebPack loads all semantic-ui components

I'm currently working on a project and i need to configure WebPack. In the project, we are also using ReactJS and Semantic-UI. Here is webpack.config.js :
var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
context: __dirname,
entry: {
react: ["react", "react-dom"],
home: './assets/js/index.jsx',
},
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name].js",
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.optimize.CommonsChunkPlugin({
names: ["react"],
}),
new webpack.optimize.CommonsChunkPlugin({
name: "home",
chunks: ['home'],
filename: "[name]-[hash].js",
}),
new BundleAnalyzer(),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: { presets: ["es2015", "react"] }
},
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['*', '.js', '.jsx']
},
};
In assets/js/index.jsx file, we just have these import statements :
import React from "react";
import ReactDOM from 'react-dom';
import { Button } from 'semantic-ui-react';
By running webpack command, it outputs two files:
react.js: 779 KB
home-[some_hash_number].js: 1.5 MB
Using webpack-bundle-analyzer plugin, we get this:
As you see the red rectangle in the picture, all of the semantic-ui react components are bundled into home.js file although i just imported Button component from in assets/js/index.js file and that's why the output file gets too big.
Is there any way to just bundle needed components?
UPDATE
Reading #Alexander Fedyashov answer, i installed babel-plugin-lodash and updated webpack.config.js accordingly:
var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
context: __dirname,
entry: {
react: ["react", "react-dom"],
home: './assets/js/index.jsx',
},
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name].js",
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.optimize.CommonsChunkPlugin({
name: "react",
}),
new webpack.optimize.CommonsChunkPlugin({
name: "home",
chunks: ['home'],
filename: "[name]-[hash].js",
}),
new BundleAnalyzer(),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: ["lodash", { "id": ["lodash", "semantic-ui-react"] }],
presets: ["es2015", "react"],
}
},
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['*', '.js', '.jsx']
},
};
Now everything is working and only needed components are loaded.
It should be splitted by Webpack, but in fact tree shaking doesn't work. You can use babel-plugin-lodash as described in SUIR docs.
You should keep in mind, that some of SUIR's components are dependent from each other, i.e.:
Button requires Icon and Label
Label requires Icon and Image
Image requires Dimmer
Dimmer requires Portal.
However, plugin will allow to strip such components as Rail, Reveal and Advertisement if you don't use them.
There is a new feature on Webpack 2 to solve this issue, read this article
https://medium.com/#adamrackis/vendor-and-code-splitting-in-webpack-2-6376358f1923

React bootstrap not rendering style

Bootstrap styles not rendering when everything is setup fine. I have install react-bootstrap and imported bootstrap css, but i cannot get the style to render. I can make it work through a create-react-app boilerplate. I suspect that it has something to do with my bootstrap. this is my webpack.config file:
var path = require('path');
var webpack = require('webpack');
module.exports = {
devServer: {
inline: true,
contentBase: './src',
port: 3000
},
devtool: 'cheap-module-eval-source-map',
entry: './dev/js/index.js',
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
query: {
presets: ['es2015', 'react', 'stage-0']
},
exclude: /node_modules/
},
{
test: /\.css$/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
]
},
{
test: /\.(png|jpg)$/,
loader: 'url?limit=25000'
}
]
},
output: {
path: 'src',
filename: 'js/bundle.min.js'
},
plugins: [
new webpack.optimize.OccurrenceOrderPlugin()
]
};

Styles not working in isomorphic React implementation using webpack

Server rendered html does not contain any css. Only when react runs on client side, the css gets applied. What am i doing wrong?
Webpack config server + client: (shortened for brevity)
module.exports = [
{
name: "simple-server",
entry: [path.join(__dirname, "..", "src", "server.js")],
output: {
path: path.join(__dirname, "..", "build"),
filename: "server.js",
libraryTarget: "commonjs2",
},
target: "node",
externals: [nodeExternals()],
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["css", "sass"],
},
{
test: /\.css$/,
loader: ["css"],
}
],
},
resolve: {
extensions: ["", ".js", ".jsx", ".scss"],
modulesDirectories: [ "src", "node_modules"],
},
},
{
name: "simple-client",
context: path.join(__dirname, "..", "src"),
entry: {
app: ["handlers/App", "webpack-hot-middleware/client?path=__webpack_hmr"],
},
devtool: "cheap-module-inline-source-map",
output: {
path: path.join(__dirname, "..", "build", "assets"),
filename: "[name].js",
publicPath: "assets/",
},
target: "web",
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["style-loader","css-loader?sourceMap","postcss-loader","sass-loader?sourceMap"],
},
{
test: /\.css$/,
loaders: ["style-loader","css-loader?sourceMap","postcss-loader"],
}
],
},
postcss: () => [autoprefixer({ browsers: ["last 5 versions", "> 5%"] })],
resolve: {
extensions: ["", ".js", ".jsx", ".scss"],
modulesDirectories: [
"src",
"node_modules",
],
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new HtmlWebpackPlugin({
filename: "app.html",
template: "templates/main.html",
})
new webpack.HotModuleReplacementPlugin(),
],
},
];
Sample component :
import React from "react";
import "Styles.scss";
export default Component extends .... {}
You can tell webpack to create separate bundle for css when it creates js bundle. And use them in html head
<link rel="stylesheet" type="text/css" href="/static/style.css">
(There are many articles which suggest that it is better to have css in the head of html).
How to instruct webpack to separate css:
https://webpack.github.io/docs/stylesheets.html#separate-css-bundle
In short:
You have to install :
npm install extract-text-webpack-plugin --save
Add this plugin to plugin list:
plugins: [
new ExtractTextPlugin("style.css")
]
And in loaders:
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.sass$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader")
}
Im not sure if this works correctly with hmr (reloading css) because when I work with hmr Im not need server side rendering.
I have two webpack configs : dev and production. dev config use hmr and doesn't separate css (one bundle) and doesn't render server side. And production doesn't use hmr, have separated css and js and server side rendering.
You could check my configuration:
https://github.com/uhlryk/my-express-react-seed

Resources