I am trying out ReactJS with Webpack, hot updating, and React-Router. Below is my
webpack.config.js code. For some reason there are a bunch of json files being created at the very top of the file tree. For example, fb43026df6c9e1823c07.hot-update.json
Files end with .hot-update.json
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:5000',
'webpack/hot/dev-server',
'./scripts/index'
],
output: {
path: __dirname,
filename: 'bundle.js',
publicPath: '/static/'
},
resolve: {
extensions: ['', '.js']
},
devtool: 'eval-source-map',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader']
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test: /\.jsx?$/,
loaders: ['babel'],
include: path.join(__dirname, 'scripts')
}
]
}
};
This is the file that Webpack's hotModuleReplacementPlugin is reading from every time you make a change and save it. It's making new bundles of your app for your front end to receive.
Related
I have a small React app that I'm minifying with Webpack, and I noticed that ~80% of my minified index.js file is just Bootstrap css that I'm not using, plus Webpack warns me that my entry file is too big (~900kb vs ~250kb recommended). I found a few answers here from a long time ago that said to remove parts of bootstrap.min.css file that I don't need, and I'm wondering if that's still the recommended solution for a React app using react-bootstrap?
This is my production webpack config:
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const FaviconsWebpackPlugin = require('favicons-webpack-plugin')
module.exports = {
entry: '/src/index.tsx',
output: {
path: path.resolve(__dirname, 'prod'),
},
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react'],
},
},
},
{
test: /\.css$/,
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules/react-toastify/dist'),
path.resolve(
__dirname,
'node_modules/bootstrap/dist/css/bootstrap.min.css'
),
path.resolve(
__dirname,
'node_modules/react-grid-layout/css/styles.css'
),
path.resolve(
__dirname,
'node_modules/react-resizable/css/styles.css'
),
],
use: ['style-loader', 'css-loader'],
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader',
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
}),
new FaviconsWebpackPlugin('./src/logo.png'),
],
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
}
And at the top of my App.tsx file I have
import 'bootstrap/dist/css/bootstrap.min.css'
Ok so I was able to (I think) accomplish what I was asking. I first tried to follow the instructions here:
https://medium.com/dwarves-foundation/remove-unused-css-styles-from-bootstrap-using-purgecss-88395a2c5772
So running purgecss --css [path to bootstrap css] ---content src/index.html --output public did create very minified CSS files, but either I did something wrong or purgecss removed too much, because the bootstrap styles didn't seem to be applied to anything.
Instead, I installed MiniCssExtractPlugin, and pointed webpack to the full bootstrap.min.css file. Running webpack with the below (updated) webpack.prod.js config file reduced the entry file size from ~900kb to ~360kb, which is still above the recommended limit but is about 1/3 the size of the entry before these changes.
Edit: and it also seems good that now the css styles are in their own actual main.css file, rather than for some reason being inside main.js, which is how it was before adding MiniCssExtractPlugin.
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const FaviconsWebpackPlugin = require('favicons-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: '/src/index.tsx',
output: {
path: path.resolve(__dirname, 'prod'),
},
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react'],
},
},
},
{
test: /\.css$/,
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'public')
],
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
use: 'ts-loader',
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
}),
new MiniCssExtractPlugin({filename: "[name].css", chunkFilename: "[id].css"}),
new FaviconsWebpackPlugin('./src/logo.png'),
],
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
}
at first i was getting error that scss files are not readable, when i tried to add options for sass loader to set its path to node_modules. But after that i could not solve this error. Is there anyother way to add multiple loaders and options for them?
this is my webpack.config.js"
var webpack = require('webpack');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
var BundleTracker = require('webpack-bundle-tracker');
var ExtractText = require('extract-text-webpack-plugin');
module.exports = {
entry: path.join(__dirname, 'assets/src/js/index'),
output: {
path: path.join(__dirname, 'assets/dist'),
filename: '[name]-[hash].js'
},
plugins: [
new BundleTracker({
path: __dirname,
filename: 'webpack-stats.json'
}),
new ExtractText({
filename: '[name]-[hash].css'
}),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
loader: ['style-loader', 'css-loader'],
},
{
test: /\.scss$/,
use:[{
loader: "sass-loader",
options: {
"includePaths": [
path.resolve(__dirname, 'node_modules')
]
}
},
{
loader: "style-loader"
},
{
loader: "css-loader"
}
]
},
],
},
};```[this is the error i am getting][1]
[1]: https://i.stack.imgur.com/6O8ct.png
I have been looking everywhere for a place to tell me how to add tsx compilers to an existing react project. This was not a create-react-app. Is it possible to use both TSX and JSX files in the same project? I don't want to do everything in TSX, but I definitely want to get some practice in and don't want to convert the whole thing. Do you guys have any places I can go look for this? Here is my webpack.config for reference (if you know a way I can add lmk)
Version: "react": "^16.8.1",
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: "./index.html"
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "/static/cs/styles.css",
chunkFilename: "styles.css"
})
],
entry: './src/index.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'static/js/bundle.js'
},
module: {
rules: [
{
test: /\.s?css$/,
use: [
"style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader"
]
},
{
use: { loader: 'babel-loader' },
test: /\.js$/,
exclude: /node_modules/
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: '',
},
}
]
},
]
},
devServer: {
contentBase: path.join(__dirname, 'build'),
},
}
I have implemented webpack config like
/* eslint-disable no-var */
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: [
'webpack-hot-middleware/client',
'./src/main'
],
devtool: 'eval-source-map',
output: {
path: __dirname,
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel'],
include: path.join(__dirname, 'src')
},
{
test: /\.css$/, // Only .css files
loader: 'style!css' // Run both loaders
}
]
}
};
and I have installed the css-loader style-loader for loding the css on my page and I am using the bootstrap.min.css as below
require('../../node_modules/bootstrap/dist/css/bootstrap.min.css');
it's throw error like
Bootstrap is using the Glyphicons font. You also need to have a loader for the font:
{
test: /\.woff$/,
loader: 'url?limit=100000'
}
Source: christianalfoni.github.io/react-webpack-cookbook/Inlining-fonts
Or:
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
loader: 'file-loader'
}
Source: stackoverflow.com/a/31183889/2378031
I'm totally new to webpack and I'm doing my first configuration for a new project.
I'm trying to load my jsx/scss file but I've this problem:
var path = require('path');
var webpack = require('webpack');
var autoprefixer = require('autoprefixer');
var node_modules_dir = path.resolve(__dirname, 'node_modules');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var cssExtractTextPlugin = new ExtractTextPlugin("css", "index.css");
var staticPrefix = path.join(__dirname, 'src')
var distPath = path.join(__dirname, 'dist')
module.exports = {
devtool: 'eval',
//context: path.join(__dirname, staticPrefix),
entry: {
'app': ['webpack-hot-middleware/client', path.join(__dirname, 'src/app.jsx')],
'vendor': [
'bootstrap/js/dropdown',
'bootstrap/js/tab',
'bootstrap/js/tooltip',
'bootstrap/js/alert',
'jquery',
'react-router',
'react-bootstrap'
],
'myapp': path.join(__dirname, 'src/stylesheets/base.scss') //'stylesheets/base.scss'
},
output: {
path: distPath,
filename: '[name].js',
libraryTarget: 'var',
library: 'exports',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'root.jQuery': 'jquery'
}),
new ExtractTextPlugin('[name].css')
],
module: {
loaders: [
{
test: /\.js$/,
loader: ['babel'],
include: path.join(__dirname, staticPrefix),
exclude: /(vendor|node_modules)/
},
{
test: /\.jsx$/,
loader: ['babel'],
include: path.join(__dirname, staticPrefix),
exclude: /(vendor|node_modules)/
},
{
test: /\.scss$/,
include: path.join(__dirname, staticPrefix),
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader-loader')
},
{
test: /\.(woff|woff2|ttf|eot|svg|png|gif|ico|jpg)($|\?)/,
loader: 'file-loader?name=' + '[name].[ext]'
}
]
},
postcss: function() {
return [autoprefixer];
},
resolve: {
modulesDirectories: [path.join(__dirname, staticPrefix), 'node_modules'],
extensions: ['', '.jsx', '.js']
},
};
The problem is that when I run: node_modules/.bin/webpack --config=webpack.config.dev it give me 2 errors:
ERROR in ./src/app.jsx
Module parse failed: /Users/work/Desktop/myapp-client/src/app.jsx Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import React from 'react';
| console.log('hello!’);
|
# multi app
ERROR in ./src/stylesheets/base.scss
Module parse failed: /Users/work/Desktop/myapp-client/src/stylesheets/base.scss Line 1: Unexpected token {
You may need an appropriate loader to handle this file type.
| body {
| background: black;
| }
Where I'm doing wrong ?
With babel 6 you need to include the babel react preset to transpile your .jsx files. You also need to add the babel es2015 preset to transpile ES2015, i.e. ES6, syntax:
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules)/,
loader: 'babel',
query: {
presets:[ 'react', 'es2015' ]
}
}
]
}
On a side note, if you tweak your regex in the test key, you don't need two loader entries (for the .js and .jsx files).
Make sure you install these presets separately:
npm i -D babel-preset-es2015 babel-preset-react
More info on the babel 6 changes can be found here