Please I need some help as I'm having a hard time trying to use bootstrap and react-bootstrap in my new project created from a react-starter-kit template (https://github.com/kriasoft/react-starter-kit).
I'm pretty new to webpack so I'm not pretty sure what I need to do to get this working.
The steps I did so far:
1) I included react-bootstrap, bootstrap and jquery in package.json
2) I imported a react-bootstrap button in home file and tried to rendered. It renders with no style at all.
What else needs to be done?
This is the webpack.config:
/**
* React Starter Kit (https://www.reactstarterkit.com/)
*
* Copyright © 2014-present Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/
import path from 'path';
import webpack from 'webpack';
import AssetsPlugin from 'assets-webpack-plugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import pkg from '../package.json';
const isDebug = !process.argv.includes('--release');
const isVerbose = process.argv.includes('--verbose');
const isAnalyze = process.argv.includes('--analyze') || process.argv.includes('--analyse');
//
// Common configuration chunk to be used for both
// client-side (client.js) and server-side (server.js) bundles
// -----------------------------------------------------------------------------
const config = {
context: path.resolve(__dirname, '..'),
output: {
path: path.resolve(__dirname, '../build/public/assets'),
publicPath: '/assets/',
pathinfo: isVerbose,
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: [
path.resolve(__dirname, '../src'),
],
query: {
// https://github.com/babel/babel-loader#options
cacheDirectory: isDebug,
// https://babeljs.io/docs/usage/options/
babelrc: false,
presets: [
// A Babel preset that can automatically determine the Babel plugins and polyfills
// https://github.com/babel/babel-preset-env
['env', {
targets: {
browsers: pkg.browserslist,
},
modules: false,
useBuiltIns: false,
debug: false,
}],
// Experimental ECMAScript proposals
// https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-
'stage-2',
// JSX, Flow
// https://github.com/babel/babel/tree/master/packages/babel-preset-react
'react',
// Optimize React code for the production build
// https://github.com/thejameskyle/babel-react-optimize
...isDebug ? [] : ['react-optimize'],
],
plugins: [
// Adds component stack to warning messages
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-source
...isDebug ? ['transform-react-jsx-source'] : [],
// Adds __self attribute to JSX which React will use for some warnings
// https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx-self
...isDebug ? ['transform-react-jsx-self'] : [],
],
},
},
{
test: /\.css/,
use: [
{
loader: 'isomorphic-style-loader',
},
{
loader: 'css-loader',
options: {
// CSS Loader https://github.com/webpack/css-loader
importLoaders: 1,
sourceMap: isDebug,
// CSS Modules https://github.com/css-modules/css-modules
modules: true,
localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]',
// CSS Nano http://cssnano.co/options/
minimize: !isDebug,
discardComments: { removeAll: true },
},
},
{
loader: 'postcss-loader',
options: {
config: './tools/postcss.config.js',
},
},
],
},
{
test: /\.md$/,
loader: path.resolve(__dirname, './lib/markdown-loader.js'),
},
{
test: /\.txt$/,
loader: 'raw-loader',
},
{
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader',
query: {
name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]',
},
},
{
test: /\.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.*)?$/,
loader: 'url-loader',
query: {
name: isDebug ? '[path][name].[ext]?[hash:8]' : '[hash:8].[ext]',
limit: 10000,
},
},
],
},
// Don't attempt to continue if there are any errors.
bail: !isDebug,
cache: isDebug,
stats: {
colors: true,
reasons: isDebug,
hash: isVerbose,
version: isVerbose,
timings: true,
chunks: isVerbose,
chunkModules: isVerbose,
cached: isVerbose,
cachedAssets: isVerbose,
},
};
//
// Configuration for the client-side bundle (client.js)
// -----------------------------------------------------------------------------
const clientConfig = {
...config,
name: 'client',
target: 'web',
entry: {
client: ['babel-polyfill', './src/client.js'],
},
output: {
...config.output,
filename: isDebug ? '[name].js' : '[name].[chunkhash:8].js',
chunkFilename: isDebug ? '[name].chunk.js' : '[name].[chunkhash:8].chunk.js',
},
plugins: [
// Define free variables
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
'process.env.BROWSER': true,
__DEV__: isDebug,
}),
// Emit a file with assets paths
// https://github.com/sporto/assets-webpack-plugin#options
new AssetsPlugin({
path: path.resolve(__dirname, '../build'),
filename: 'assets.json',
prettyPrint: true,
}),
// Move modules that occur in multiple entry chunks to a new entry chunk (the commons chunk).
// http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: module => /node_modules/.test(module.resource),
}),
...isDebug ? [] : [
// Minimize all JavaScript output of chunks
// https://github.com/mishoo/UglifyJS2#compressor-options
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
screw_ie8: true, // React doesn't support IE8
warnings: isVerbose,
unused: true,
dead_code: true,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
}),
],
// Webpack Bundle Analyzer
// https://github.com/th0r/webpack-bundle-analyzer
...isAnalyze ? [new BundleAnalyzerPlugin()] : [],
],
// Choose a developer tool to enhance debugging
// http://webpack.github.io/docs/configuration.html#devtool
devtool: isDebug ? 'cheap-module-source-map' : false,
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
// https://webpack.github.io/docs/configuration.html#node
// https://github.com/webpack/node-libs-browser/tree/master/mock
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
},
};
//
// Configuration for the server-side bundle (server.js)
// -----------------------------------------------------------------------------
const serverConfig = {
...config,
name: 'server',
target: 'node',
entry: {
server: ['babel-polyfill', './src/server.js'],
},
output: {
...config.output,
filename: '../../server.js',
libraryTarget: 'commonjs2',
},
module: {
...config.module,
// Override babel-preset-env configuration for Node.js
rules: config.module.rules.map(rule => (rule.loader !== 'babel-loader' ? rule : {
...rule,
query: {
...rule.query,
presets: rule.query.presets.map(preset => (preset[0] !== 'env' ? preset : ['env', {
targets: {
node: parseFloat(pkg.engines.node.replace(/^\D+/g, '')),
},
modules: false,
useBuiltIns: false,
debug: false,
}])),
},
})),
},
externals: [
/^\.\/assets\.json$/,
(context, request, callback) => {
const isExternal =
request.match(/^[#a-z][a-z/.\-0-9]*$/i) &&
!request.match(/\.(css|less|scss|sss)$/i);
callback(null, Boolean(isExternal));
},
],
plugins: [
// Define free variables
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
'process.env.BROWSER': false,
__DEV__: isDebug,
}),
// Do not create separate chunks of the server bundle
// https://webpack.github.io/docs/list-of-plugins.html#limitchunkcountplugin
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
// Adds a banner to the top of each generated chunk
// https://webpack.github.io/docs/list-of-plugins.html#bannerplugin
new webpack.BannerPlugin({
banner: 'require("source-map-support").install();',
raw: true,
entryOnly: false,
}),
],
node: {
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false,
},
devtool: isDebug ? 'cheap-module-source-map' : 'source-map',
};
export default [clientConfig, serverConfig];
Then the package.json:
{
"name": "web",
"version": "0.0.0",
"private": true,
"engines": {
"node": ">=6.5",
"npm": ">=3.10"
},
"browserslist": [
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 9"
],
"dependencies": {
"babel-polyfill": "^6.23.0",
"bluebird": "^3.5.0",
"body-parser": "^1.17.1",
"classnames": "^2.2.5",
"cookie-parser": "^1.4.3",
"core-js": "^2.4.1",
"express": "^4.15.2",
"express-graphql": "^0.6.4",
"express-jwt": "^5.3.0",
"fastclick": "^1.0.6",
"graphql": "^0.9.3",
"history": "^4.6.1",
"isomorphic-fetch": "^2.2.1",
"isomorphic-style-loader": "^2.0.0",
"jsonwebtoken": "^7.3.0",
"normalize.css": "^6.0.0",
"passport": "^0.3.2",
"passport-facebook": "^2.1.1",
"pretty-error": "^2.1.0",
"prop-types": "^15.5.8",
"query-string": "^4.3.4",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"serialize-javascript": "^1.3.0",
"source-map-support": "^0.4.14",
"universal-router": "^3.1.0",
"bootstrap": "^3.3.7",
"react-bootstrap": "^0.30.0",
"jquery": "^2.2.1",
"bootstrap-webpack": "0.0.3"
},
"devDependencies": {
"assets-webpack-plugin": "^3.5.1",
"autoprefixer": "^6.7.7",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.0.0",
"babel-plugin-rewire": "^1.1.0",
"babel-preset-env": "^1.4.0",
"babel-preset-react": "^6.24.1",
"babel-preset-react-optimize": "^1.0.1",
"babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.24.1",
"babel-template": "^6.24.1",
"babel-types": "^6.24.1",
"browser-sync": "^2.18.8",
"chai": "^3.5.0",
"chokidar": "^1.6.1",
"css-loader": "^0.28.0",
"editorconfig-tools": "^0.1.1",
"enzyme": "^2.8.2",
"eslint": "^3.19.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-css-modules": "^2.7.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.10.3",
"file-loader": "^0.11.1",
"front-matter": "^2.1.2",
"glob": "^7.1.1",
"json-loader": "^0.5.4",
"lint-staged": "^3.4.0",
"markdown-it": "^8.3.1",
"mkdirp": "^0.5.1",
"mocha": "^3.3.0",
"pixrem": "^3.0.2",
"pleeease-filters": "^3.0.1",
"postcss": "^5.2.17",
"postcss-calc": "^5.3.1",
"postcss-color-function": "^3.0.0",
"postcss-custom-media": "^5.0.1",
"postcss-custom-properties": "^5.0.2",
"postcss-custom-selectors": "^3.0.0",
"postcss-flexbugs-fixes": "^2.1.1",
"postcss-global-import": "^1.0.0",
"postcss-import": "^9.1.0",
"postcss-loader": "^1.3.3",
"postcss-media-minmax": "^2.1.2",
"postcss-nested": "^1.0.1",
"postcss-nesting": "^2.3.1",
"postcss-pseudoelements": "^4.0.0",
"postcss-selector-matches": "^2.0.5",
"postcss-selector-not": "^2.0.0",
"pre-commit": "^1.2.2",
"raw-loader": "^0.5.1",
"react-addons-test-utils": "^15.5.1",
"react-deep-force-update": "^2.0.1",
"react-hot-loader": "^3.0.0-beta.6",
"redbox-react": "^1.3.6",
"rimraf": "^2.6.1",
"sinon": "^2.1.0",
"stylefmt": "^5.3.2",
"stylelint": "^7.10.1",
"stylelint-config-standard": "^16.0.0",
"url-loader": "^0.5.8",
"webpack": "^2.4.1",
"webpack-bundle-analyzer": "^2.4.0",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.18.0",
"write-file-webpack-plugin": "^4.0.2"
},
"babel": {
"presets": [
[
"env",
{
"targets": {
"node": "current"
}
}
],
"stage-2",
"react"
],
"env": {
"test": {
"plugins": [
"rewire"
]
}
}
},
"stylelint": {
"extends": "stylelint-config-standard",
"rules": {
"string-quotes": "single",
"property-no-unknown": [
true,
{
"ignoreProperties": [
"composes"
]
}
],
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": [
"global"
]
}
]
}
},
"lint-staged": {
"*.{cmd,html,json,md,sh,txt,xml,yml}": [
"editorconfig-tools fix",
"git add"
],
"*.{js,jsx}": [
"eslint --fix",
"git add"
],
"*.{css,less,scss,sss}": [
"stylefmt",
"stylelint",
"git add"
]
},
"scripts": {
"lint:fix": "eslint --fix src tools",
"lint:js": "eslint src tools",
"lint:css": "stylelint \"src/**/*.{css,less,scss,sss}\"",
"lint:staged": "lint-staged",
"lint": "yarn run lint:js && yarn run lint:css",
"test": "mocha \"src/**/*.test.js\" --require babel-register --require test/setup.js",
"test:watch": "yarn run test -- --reporter min --watch",
"clean": "babel-node tools/run clean",
"copy": "babel-node tools/run copy",
"bundle": "babel-node tools/run bundle",
"build": "babel-node tools/run build",
"build:stats": "yarn run build -- --release --analyse",
"deploy": "babel-node tools/run deploy",
"render": "babel-node tools/run render",
"serve": "babel-node tools/run runServer",
"start:brk": "babel-node --debug-brk tools/run start",
"start:dev": "babel-node tools/run start",
"start": "node build/server.js"
}
}
And finally my Home.js
/**
* React Starter Kit (https://www.reactstarterkit.com/)
*
* Copyright © 2014-present Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './Home.css';
import {Button} from 'react-bootstrap';
class Home extends React.Component {
static propTypes = {
news: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string.isRequired,
link: PropTypes.string.isRequired,
content: PropTypes.string,
})).isRequired,
};
render() {
return (
<div className={s.root}>
<div className={s.container}>
<h1>React.js News</h1>
<Button bsStyle="primary">Primary</Button>
</div>
</div>
);
}
}
export default withStyles(s)(Home);
You need to add the bootstrap CSS manually:
Because React-Bootstrap doesn't depend on a very precise version of Bootstrap, we don't ship with any included css.
More info here
Add the bootstrap stylesheet inside src/components/Html.js
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap-theme.min.css">
Usage (e.g: Home.js)
<Button bsStyle="primary">Default</Button>
<h1>React.js News</h1>
<Alert bsStyle="warning"> Hello </Alert>
Please take a look there:
https://github.com/kriasoft/react-starter-kit/pull/782
https://github.com/kriasoft/react-starter-kit/issues/950
Related
I was trying to update my vue 2 to vue 3 project. i upgraded my project with the use vue plugin. and it update my project but when i run my project.it gives me error of Uncaught ReferenceError: vue is not defined.and after so many tries i am not able to solve it.and i dont have too much knowledge about webpack.so please check it and let me know how to fix it.
here is my package.json file
{
"name": "shopify-theme-lab",
"version": "2.6.2",
"description": "Customizable modular development environment for blazing-fast Shopify theme creation",
"author": "Sergej Samsonenko <contact#sergej.codes>",
"scripts": {
"build": "cross-env NODE_ENV=production BROWSERSLIST_ENV=production BROWSERSLIST_CONFIG=.config/.browserslistrc node_modules/.bin/webpack --config .config/webpack/webpack.prod.js",
"lint": "npm-run-all lint:*",
"deploy:dev": "shopify-themekit deploy --env=dev --config .config/shopify/shopify.dev.yml --allow-live",
"deploy:live": "shopify-themekit deploy --env=live --config .config/shopify/shopify.live.yml",
"dev": "cross-env NODE_ENV=development BROWSERSLIST_ENV=development BROWSERSLIST_CONFIG=.config/.browserslistrc node_modules/.bin/webpack --config .config/webpack/webpack.dev.js --watch",
"lint-fix": "node_modules/.bin/eslint --fix src/**/*.{js,vue} --config .config/.eslintrc.js",
"lint:css": "node_modules/.bin/stylelint src/**/*.{vue,css,sass,scss} --config .config/.stylelintrc.js",
"lint:js": "node_modules/.bin/eslint src/**/*.{js,vue} --config .config/.eslintrc.js",
"open:dev": "shopify-themekit open --env=dev --config .config/shopify/shopify.dev.yml",
"open:live": "shopify-themekit open --env=live --config .config/shopify/shopify.live.yml",
"reloader": "node node_modules/shopify-theme-lab-reloader",
"settings:dev": "shopify-themekit --env=dev download config/settings_data.json --config .config/shopify/shopify.dev.yml",
"settings:live": "shopify-themekit --env=live download config/settings_data.json --config .config/shopify/shopify.live.yml",
"shopify:init": "npx themelab shopify:init",
"shopify:themes": "shopify-themekit get --list",
"shopify:watch": "cross-env-shell shopify-themekit watch --env=dev --allow-live --config .config/shopify/shopify.dev.yml --notify=http://localhost:$npm_package_config_reloader_serverPort/reload",
"start": "npm-run-all --parallel --silent --race dev reloader shopify:watch"
},
"dependencies": {
"axios": "^0.21.1",
"bootstrap": "4.5.3",
"bootstrap-vue": "^2.21.2",
"dotenv": "^10.0.0",
"lazysizes": "^5.3.2",
"shopify-buy": "^2.11.0",
"universal-cookie": "^4.0.4",
"v-calendar": "^2.3.2",
"vue": "^3.2.20",
"vue-carousel": "^0.18.0",
"vue-moment": "^4.1.0",
"vuex": "^4.0.2"
},
"devDependencies": {
"#babel/core": "^7.13.16",
"#babel/plugin-transform-runtime": "^7.13.15",
"#babel/preset-env": "^7.13.15",
"#shopify/themekit": "^1.1.7",
"#vue/compiler-sfc": "^3.2.20",
"autoprefixer": "^10.2.5",
"babel-loader": "^8.2.2",
"clean-webpack-plugin": "^3.0.0",
"cross-env": "^7.0.3",
"css-loader": "^5.2.4",
"css-minimizer-webpack-plugin": "^2.0.0",
"eslint": "^7.25.0",
"eslint-plugin-vue": "^7.9.0",
"eslint-webpack-plugin": "^2.5.4",
"file-loader": "^6.2.0",
"glob-all": "^3.2.1",
"html-webpack-plugin": "^5.3.2",
"mini-css-extract-plugin": "^1.5.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"postcss-loader": "^5.2.0",
"postcss-preset-env": "^6.7.0",
"progress-webpack-plugin": "^1.0.12",
"purgecss-webpack-plugin": "^4.0.3",
"sass": "^1.32.12",
"sass-loader": "^11.0.1",
"shopify-theme-lab-reloader": "^2.1.3",
"style-loader": "^2.0.0",
"stylelint": "^13.13.0",
"stylelint-config-recommended": "^5.0.0",
"stylelint-webpack-plugin": "^2.1.1",
"url-loader": "^4.1.1",
"vue-cli-plugin-vue-next": "~0.1.4",
"vue-loader": "^16.8.2",
"vue-template-compiler": "^2.6.14",
"webpack": "^5.35.1",
"webpack-cli": "^4.6.0",
"webpack-merge": "^5.7.3"
},
"config": {
"reloader": {
"serverPort": 5000,
"webSocketPort": 5050,
"delay": 2000,
"indicator": true
}
},
"license": "MIT"
}
and here is my webpack file
const { cacheTimestamp } = require("./cacheBuster");
const webpack = require("webpack");
const path = require("path");
const glob = require("glob");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ProgressPlugin = require("progress-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { VueLoaderPlugin } = require("vue-loader");
const dotenv = require("dotenv").config({
path: path.join(__dirname, "../.env"),
});
const entries = glob
.sync(path.resolve(__dirname, "../../src/layout/*"))
.reduce((entries, entry) => {
const entryName = path.parse(entry).name;
entries[`layout-${entryName}`] = path.resolve(__dirname, entry);
return entries;
}, {});
module.exports = {
stats: "minimal",
entry: entries,
output: {
path: path.resolve(__dirname, "../../shopify/assets/"),
filename: `[name].${cacheTimestamp}.js`,
clean: {
dry: true,
},
},
optimization: {
moduleIds: "named",
mergeDuplicateChunks: false,
splitChunks: {
cacheGroups: {
default: false,
commons: {
test: /[\\/]node_modules[\\/]((?!(moment)).*)[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
resolve: {
extensions: ["*", ".js", ".vue", ".json"],
alias: {
"#": path.resolve(__dirname, "../../src/"),
$: path.resolve(__dirname, "../../shopify/"),
},
},
module: {
rules: [
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192,
},
},
],
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "/",
},
},
],
},
],
},
external: {
vue: "Vue",
},
plugins: [
new VueLoaderPlugin(),
new ProgressPlugin(),
/**
* don't clean files with the 'static' keyword in their filename
* docs: https://github.com/johnagan/clean-webpack-plugin
*/
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["**/*", "!*static*"],
}),
new HtmlWebpackPlugin({
excludeChunks: ["static"],
template: path.resolve(__dirname, "./script-tags.html"),
filename: path.resolve(
__dirname,
"../../shopify/snippets/script-tags.liquid"
),
inject: false,
minify: {
removeComments: true,
removeAttributeQuotes: false,
collapseWhitespace: true,
},
meta: {
cacheTimestamp,
},
}),
new HtmlWebpackPlugin({
excludeChunks: ["static"],
template: path.resolve(__dirname, "./style-tags.html"),
filename: path.resolve(
__dirname,
"../../shopify/snippets/style-tags.liquid"
),
inject: false,
minify: {
removeComments: true,
removeAttributeQuotes: false,
collapseWhitespace: true,
},
meta: {
cacheTimestamp,
},
}),
new webpack.DefinePlugin({
"process.env": JSON.stringify(dotenv.parsed),
}),
],
};
please check it let me know if we can change anything to fix it.
Been trying to make my React app work with IE11 with not luck so far.
Getting the error:
Basically this error points to arrow function during bundle
I already tried adding react-app-polyfill in my index.js file and then in my package the advised config from this article and other posts .
I downgraded query-string to 5.1.1 like advised here.
And also tried importing core-js/stable and regenerator like advised here.
Also deleted node_modules and or only cache via rm -rf node_modules/.cache/.
And probably checked all similar issues as mine here in SO.
Sadly none of these options have helped me at all.
Anybody sees something in my config?
My package.json config:
{
"scripts": {
"postinstall": "patch-package",
"start": "cross-env NODE_ENV=development node ./server.js",
"start:debug": "cross-env NODE_ENV=development node --inspect ./server.js",
"start:prod": "cross-env NODE_ENV=production node ./server.js",
"lint": "eslint --fix ./src ./server",
"build": "cross-env NODE_ENV=production webpack",
"prestart": "npm run lint",
"prebuild": "npm run lint"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all",
"ie 11"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
"ie 11"
]
},
"author": "elios264",
"license": "ISC",
"devDependencies": {
"#babel/core": "^7.12.9",
"#babel/plugin-proposal-class-properties": "^7.12.1",
"#babel/preset-env": "^7.12.7",
"#babel/preset-react": "^7.12.7",
"#hot-loader/react-dom": "^17.0.1",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"babel-preset-env": "^1.7.0",
"classnames": "^2.2.6",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.3.2",
"core-js": "^3.8.0",
"cross-env": "^7.0.3",
"crypto-browserify": "^3.12.0",
"css-loader": "^5.0.1",
"css-minimizer-webpack-plugin": "^1.1.5",
"downscale": "^1.0.6",
"eslint": "^7.14.0",
"eslint-import-resolver-node": "^0.3.4",
"eslint-import-resolver-webpack": "^0.13.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"file-dialog": "0.0.8",
"file-loader": "^6.2.0",
"jwt-decode": "^3.1.2",
"less": "^3.12.2",
"less-loader": "^7.1.0",
"mini-css-extract-plugin": "^1.3.1",
"moment-duration-format": "^2.3.2",
"moment-locales-webpack-plugin": "^1.2.0",
"patch-package": "^6.2.2",
"path-browserify": "^1.0.1",
"process": "^0.11.10",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-day-picker": "^7.4.8",
"react-dom": "^17.0.1",
"react-helmet": "^6.1.0",
"react-hot-loader": "^4.13.0",
"react-rangeslider": "^2.2.0",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-virtualized": "^9.22.2",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"search-parser": "^0.1.19",
"semantic-ui-less": "^2.4.1",
"semantic-ui-react": "^2.0.1",
"stream-browserify": "^3.0.0",
"sweetalert": "^2.1.2",
"tachyons": "^4.12.0",
"terser-webpack-plugin": "^5.0.3",
"webpack": "^5.9.0",
"webpack-assets-manifest": "^3.1.1",
"webpack-cli": "^4.2.0",
"webpack-dev-middleware": "^4.0.2",
"webpack-hot-middleware": "^2.25.0",
"xlsx": "^0.16.9"
},
"dependencies": {
"#azure/storage-blob": "^12.3.0",
"#supercharge/promise-pool": "^1.6.0",
"applicationinsights": "^1.8.10",
"compression": "^1.7.4",
"cors": "^2.8.5",
"env2": "^2.2.2",
"express": "^4.17.1",
"fast-xml-parser": "^3.17.5",
"joi": "^17.3.0",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.4",
"knex": "^0.21.12",
"locutus": "^2.0.14",
"lodash": "^4.17.20",
"mjml": "^4.7.1",
"moment": "^2.29.1",
"moment-timezone": "^0.5.32",
"mssql": "^6.2.3",
"nanoid": "^3.1.20",
"node-cache": "^5.1.2",
"node-fetch": "^2.6.1",
"nodemailer": "^6.4.16",
"parse": "^2.17.0",
"parse-dashboard": "^2.1.0",
"parse-server": "^4.4.0",
"query-string": "^5.1.1",
"react-app-polyfill": "^2.0.0",
"react-sortable-hoc": "^1.11.0",
"saslprep": "^1.0.3",
"sharp": "^0.26.3",
"uuid": "^8.3.1"
}
}
My babel.config.js
module.exports = {
sourceType: process.env.NODE_ENV === 'production' ? 'unambiguous' : 'module',
presets: [
['#babel/preset-react', { 'runtime': 'automatic' }],
['#babel/preset-env', {
loose: true,
useBuiltIns: 'usage',
corejs: { version: 3, proposals: true },
modules: false,
targets: { browsers: process.env.NODE_ENV === 'production' ? 'chrome 53' : 'chrome 86' },
}],
],
plugins: [
['#babel/plugin-proposal-class-properties', { loose: true }],
'react-hot-loader/babel',
],
};
And my appLoader which is equivalent to index.js
/* eslint-disable import/first */
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
// also tried with
// import core-js/stable;
// import regenerator-runtime/runtime
import 'tachyons';
import ReactDOM from 'react-dom';
import { MemoryRouter, Route } from 'react-router-dom';
import { App } from './components/app';
ReactDOM.render(
<MemoryRouter>
<Route component={App} />
</MemoryRouter>,
document.getElementById('root')
);
Finally my webpack.config.js
require('env2')('./.env');
const _ = require('lodash');
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const WebpackAssetsManifest = require('webpack-assets-manifest');
const ClosurePlugin = require('closure-webpack-plugin');
const isDev = process.env.NODE_ENV !== 'production';
const ifDev = (then) => (isDev ? then : null);
const ifProd = (then) => (!isDev ? then : null);
module.exports = {
target: isDev ? 'web' : ['web', 'es5'],
profile: true,
mode: isDev ? 'development' : 'production',
entry: {
admin: [ifDev('webpack-hot-middleware/client'), ifDev('react-hot-loader/patch'), './admin/appLoader'].filter(_.identity),
sso: ['./sso/publicPath', ifDev('webpack-hot-middleware/client?dynamicPublicPath=true'), ifDev('react-hot-loader/patch'), './sso/appLoader'].filter(_.identity),
},
optimization: {
runtimeChunk: isDev,
minimizer: [
new TerserPlugin({ extractComments: false, terserOptions: { toplevel: true, output: { comments: false } } }),
new CssMinimizerPlugin(),
new ClosurePlugin({mode: 'STANDARD'}, {
debug: true,
languageOut: 'ECMASCRIPT5',
renaming: false
})
],
},
performance: { hints: false },
context: path.resolve(__dirname, './src'),
devtool: false,
output: {
publicPath: '/',
path: path.resolve(__dirname, './dist'),
filename: isDev ? '[name].bundle.js' : '[name].bundle.[contenthash].js',
},
resolve: {
fallback: {
'crypto': require.resolve('crypto-browserify'),
'path': require.resolve('path-browserify'),
'stream': require.resolve('stream-browserify'),
},
modules: [path.resolve(__dirname, './src'), path.resolve(__dirname, './assets'), 'node_modules'],
alias: {
'#': path.resolve(__dirname, './src'), // include your file like this in less files: ~#/yourFile.less
'../../theme.config$': path.join(__dirname, './src/theme/semantic/theme.config.less'), // semantic requirement
'react-dom': isDev ? '#hot-loader/react-dom' : 'react-dom',
},
},
plugins: [
new webpack.ProvidePlugin({ process: 'process/browser' }),
ifDev(new webpack.SourceMapDevToolPlugin({ filename: '[file].map', exclude: /node_modules/ })),
ifProd(new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['**/*', path.join(process.cwd(), 'logs/**/*')], verbose: true })),
ifProd(new webpack.LoaderOptionsPlugin({ minimize: true, debug: false })),
new MomentLocalesPlugin(),
ifDev(new webpack.HotModuleReplacementPlugin()),
new WebpackAssetsManifest({ publicPath: true, writeToDisk: true, entrypoints: true, output: '../rendering-manifest.json' }),
new MiniCssExtractPlugin({ filename: isDev ? '[name].css' : '[name].bundle.[contenthash].css' }),
ifProd(new CopyWebpackPlugin({ patterns: [{ from: path.resolve(__dirname, './assets/static') }] })),
].filter(_.identity),
module: {
rules: [{
test: /\.js$/,
include: [path.resolve(__dirname, './src'), ifProd(path.resolve(__dirname, './node_modules/joi'))].filter(_.identity),
use: 'babel-loader',
}, {
test: /\.(css|less)$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-loader', options: { importLoaders: 1, sourceMap: isDev } },
{ loader: 'less-loader', options: { sourceMap: isDev } },
],
}, {
test: /\.jpe?g$|\.gif$|\.png$|\.ico$|\.ttf$|\.eot$|\.svg$|\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [{ loader: 'file-loader', options: { esModule: false, name: isDev ? '[name].[ext]' : '[name].[contentHash].[ext]' } }],
}],
},
};
I am a newbie with node.js. Below is what I get when I run "npm run build-web" (that runs "webpack --progress" and copy the results). Any help will be appreciated.
Child centerPin:
Hash: 92640a144e27eefff6af
Time: 1663ms
Built at: 02/28/2019 5:07:50 PM
1 asset
Entrypoint centerPin = centerPin.bundle.js
[0] ./src/screens/resources/web/lib/centerPin.js 5.83 KiB {0} [built] [failed] [1 error]
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or
'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
ERROR in ./src/screens/resources/web/lib/centerPin.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Unknown substitution "BODY" given
at Object.keys.forEach.key (/home/accent/code/treecheckerapp/app/treeChecker/node_modules/#babel/template/lib/populate.js:35:15)
at Array.forEach (<anonymous>)
at populatePlaceholders (/home/accent/code/treecheckerapp/app/treeChecker/node_modules/#babel/template/lib/populate.js:33:31)
This is my package.json :
{ "name": "treeChecker", "version": "0.0.1", "private": true, "scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest",
"build": "webpack",
"build-web": "webpack --progress && cp -r \"./src/screens/resources/web\" \"./android/app/src/main/assets\"",
"android-linux": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle-out put android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run-and roid",
"bundle": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output and roid/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
"android-linux-rel": "react-native bundle --platform android --dev false --entry-file index.android.js --bundle
-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run
-android --variant=release" }, "dependencies": {
"axios": "^0.18.0",
"lodash": "^4.17.4",
"npm-check-updates": "^2.15.0",
"react": "16.8.3",
"react-native": "0.58.5",
"react-native-autocomplete-input": "^3.4.0",
"react-native-button-component": "^0.2.28",
"react-native-elements": "^1.1.0",
"react-native-fs": "^2.8.1",
"react-native-image-picker": "^0.28.0",
"react-native-localization": "^2.1.0",
"react-native-offline": "^4.3.0",
"react-native-progress": "^3.4.0",
"react-native-router-flux": "^4.0.0-beta.21",
"react-native-simple-compass": "^1.0.0",
"react-native-simple-dialogs": "^1.1.0",
"react-native-spinkit": "^1.1.1",
"react-native-static-server": "^0.4.1",
"react-native-toast-native": "^1.2.1",
"react-native-vector-icons": "^6.3.0",
"react-native-viewpager": "^0.2.13",
"react-native-webview-messaging": "^1.1.0",
"react-navigation": "^3.3.2",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-persist": "^5.10.0",
"redux-thunk": "^2.2.0" }, "devDependencies": {
"async": "^2.6.2",
"babel-core": "^6.26.3",
"babel-jest": "24.1.0",
"babel-loader": "^8.0.5",
"babel-preset-env": "^1.6.0",
"babel-preset-react-native": "4.0.1",
"eslint-config-rallycoding": "^3.2.0",
"html-webpack-inline-source-plugin": "0.0.10",
"html-webpack-plugin": "^3.2.0",
"jest": "24.1.0",
"path": "^0.12.7",
"react-test-renderer": "16.8.3",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3" }, "jest": {
"preset": "react-native" } }
This is my webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
module.exports = [
{
name: "createAOI",
entry: {
createAOI: './src/screens/resources/web/lib/createAOI.js',
},
output: {
path: path.join(__dirname, 'src/screens/resources/web/'),
filename: 'createAOI.bundle.js',
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
targets: {
browsers: ['last 2 versions', 'safari >= 9.3']
}
}]
]
}
}
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/screens/resources/web/createAOI.tpl.html',
inlineSource: 'createAOI.bundle.js',
filename: 'createAOI.html',
cache: false,
}),
new HtmlWebpackInlineSourcePlugin(),
]
},
{
name: "baseMap",
entry: {
baseMap: './src/screens/resources/web/lib/baseMap.js',
},
output: {
path: path.join(__dirname, 'src/screens/resources/web/'),
filename: 'baseMap.bundle.js',
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
targets: {
browsers: ['last 2 versions', 'safari >= 9.3']
}
}]
]
}
}
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/screens/resources/web/baseMap.tpl.html',
inlineSource: 'baseMap.bundle.js',
filename: 'baseMap.html',
cache: false,
}),
new HtmlWebpackInlineSourcePlugin(),
]
},
{
name: "centerPin",
entry: {
centerPin: './src/screens/resources/web/lib/centerPin.js',
},
output: {
path: path.join(__dirname, 'src/screens/resources/web/'),
filename: 'centerPin.bundle.js',
},
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
targets: {
browsers: ['last 2 versions', 'safari >= 9.3']
}
}]
]
}
}
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/screens/resources/web/centerPin.tpl.html',
inlineSource: 'centerPin.bundle.js',
filename: 'centerPin.html',
cache: false,
}),
new HtmlWebpackInlineSourcePlugin(),
]
},
]
Usually you get this error when some babel plugin or preset has different version than babel core. Try updating it to the same version.
https://github.com/babel/babel/issues/7801
I've updated my webpack file. Now it's won't apply my custom style to the main style bundle. No errors, classes with custom style just missing in bundle.
When I'm running build with development mode - everything is ok and my styles are exist in the bundle. Such happens only with production build.
I tried extract-text-webpack-plugin instead mini-css-extract-plugin but result is same - in prod build my styles are missing.
I'll be very apriciated for any kind of help.
Here is files:
webpack.config.js
const path = require('path');
const fs = require('fs');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const autoprefixer = require('autoprefixer');
const lessToJs = require('less-vars-to-js');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const publicPath = 'public';
const themeVariables = lessToJs(
fs.readFileSync(path.join(__dirname, './assets/style/ant-theme-vars.less'), 'utf8'),
);
module.exports = (env, options) => {
const mode = env ? env.mode : options.mode;
return {
entry: './assets/app.jsx',
output: {
path: path.resolve(__dirname, publicPath),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
plugins: [
autoprefixer({
browsers: 'last 2 version',
}),
],
},
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true,
modifyVars: themeVariables,
},
},
],
},
{
test: /\.s?css$/,
exclude: [/node_modules/],
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
plugins: [
autoprefixer({
browsers: 'last 2 version',
}),
],
},
},
{
loader: 'sass-loader',
},
],
},
{
test: /\.jsx?$/,
exclude: [/node_modules/],
loaders: ['babel-loader'],
resolve: { extensions: ['.js', '.jsx'] },
},
{
test: /\.(png|jpg|jpeg|gif|svg|ico)$/,
exclude: [/node_modules/],
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[ext',
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 70,
},
},
},
],
},
{
test: /\.(otf|ttf|woff|woff2)$/,
exclude: [/node_modules/],
loader: 'file-loader',
options: {
name: 'fonts/[name].[ext]',
},
},
],
},
plugins: [
new CleanWebpackPlugin(publicPath, {}),
new MiniCssExtractPlugin({
filename: 'bundle.css',
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './assets/www/index.html',
}),
],
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: true,
mangle: true,
warnings: false,
drop_console: true,
unsafe: true,
},
sourceMap: true,
}),
],
},
devServer: {
contentBase: path.join(__dirname),
compress: true,
port: 9000,
publicPath: '/',
historyApiFallback: true,
},
devtool: mode === 'development' ? 'cheap-inline-module-source-map' : '',
};
};
package.json
{
"name": "react-templates",
"version": "1.0.0",
"description": "",
"main": "bundle.js",
"sideEffects": false,
"scripts": {
"build": "webpack --progress --mode production",
"build-dev": "webpack -p --progress --mode development",
"start": "webpack-dev-server --mode production --open",
"eslint": "eslint . --ext .js --ext .jsx",
"stylelint": "stylelint assets/scss",
"deploy-current-branch-dev": "npm run build-dev && firebase deploy",
"deploy-dev": "git checkout -- . && git clean -fd && git checkout develop && git remote update && git pull && npm run build-dev && firebase deploy"
},
"author": "",
"license": "ISC",
"dependencies": {
"antd": "3.8.2",
"autoprefixer": "9.0.1",
"brace": "0.11.1",
"clean-webpack-plugin": "0.1.19",
"extract-text-webpack-plugin": "4.0.0-beta.0",
"fast-async": "^6.3.8",
"file-system": "2.2.2",
"firebase": "5.3.0",
"history": "4.7.2",
"html-webpack-plugin": "^3.2.0",
"less-vars-to-js": "1.3.0",
"lodash": "^4.17.11",
"mini-css-extract-plugin": "^0.4.3",
"moment": "2.22.2",
"optimize-css-assets-webpack-plugin": "5.0.0",
"prop-types": "15.6.2",
"react": "15.6.1",
"react-ace": "6.1.4",
"react-copy-to-clipboard": "5.0.1",
"react-dom": "15.6.1",
"react-favicon": "0.0.14",
"react-redux": "5.0.7",
"react-router": "4.3.1",
"react-router-dom": "4.3.1",
"react-sticky": "^6.0.3",
"redux": "4.0.0",
"redux-devtools-extension": "2.13.5",
"redux-logger": "3.0.6",
"redux-thunk": "2.3.0",
"uglifyjs-webpack-plugin": "^2.0.1",
"webpack": "^4.16.1",
"webpack-merge": "^4.1.4"
},
"devDependencies": {
"#babel/core": "^7.1.2",
"#babel/plugin-proposal-class-properties": "^7.1.0",
"#babel/preset-env": "^7.1.0",
"#babel/preset-react": "^7.0.0",
"babel-eslint": "8.2.6",
"babel-loader": "^8.0.4",
"babel-plugin-import": "^1.9.1",
"css-loader": "1.0.0",
"eslint": "4.19.1",
"eslint-config-airbnb": "17.0.0",
"eslint-plugin-import": "2.12.0",
"eslint-plugin-jsx-a11y": "6.0.3",
"eslint-plugin-react": "7.9.1",
"file-loader": "^2.0.0",
"husky": "1.0.0-rc.13",
"image-webpack-loader": "^4.3.1",
"less": "3.8.1",
"less-loader": "4.1.0",
"node-sass": "4.9.2",
"postcss-loader": "2.1.6",
"sass-loader": "7.0.3",
"style-loader": "0.21.0",
"stylelint": "9.4.0",
"stylelint-config-recommended": "2.1.0",
"webpack-bundle-analyzer": "^3.0.2",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5"
},
"husky": {
"hooks": {
"pre-commit": "npm run eslint && npm run stylelint"
}
}
}
.babelrc
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
[
"import",
{
"libraryName": "antd",
"style": true
}
]
]
}
The probplem is sideEffects: false in my package.json file.
I found an issue on Github and there are some issues related to it.
Main reason I did it - I wanted to make a tree shank in my development mode. It worked as I expected but in production mode all my custom styles are missing. To solve this problem I just removed sideEffects: false. So I lost tree shank in dev mode (think it's not good solution to make it in development mode but however).
Not sure what's going on, when I do a prod build ("cross-env NODE_ENV=production API_V=production npm run build") I get this error from from react-player:
ERROR in ./node_modules/react-player/lib/ReactPlayer.js Module build
failed: ReferenceError: Unknown plugin
"transform-es3-member-expression-literals" specified in
"C:\work\website\node_modules\react-player\package.json.env.production"
at 0, attempted to resolve relative to
"C:\work\website\node_modules\react-player"
I'm already excluding node_modules from babel:
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with Babel
exclude: /node_modules\/(?!(react-redux-toastr)\/).*/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
As per request,
webpack.base.babel.js:
/**
* COMMON WEBPACK CONFIGURATION
*/
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = options => ({
mode: options.mode,
entry: options.entry,
output: Object.assign(
{
// Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: '/',
},
options.output
), // Merge with env dependent settings
optimization: options.optimization,
node: {
fs: 'empty',
net: 'empty',
},
module: {
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with Babel
exclude: /node_modules\/(?!(react-redux-toastr)\/).*/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.(scss|css)$/,
use: [
{
loader:
options.mode === 'development'
? 'style-loader'
: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
sourceMap: process.env.NODE_ENV === 'development',
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: process.env.NODE_ENV === 'development',
},
},
{
loader: 'sass-loader',
options: {
sourceMap: process.env.NODE_ENV === 'development',
},
},
],
},
{
test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
exclude: /images/,
use: 'file-loader',
},
{
test: /\.(jpg|png|gif)$/,
use: [
{
loader: 'file-loader',
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
},
optipng: {
optimizationLevel: 7,
},
gifsicle: {
interlaced: false,
},
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.svg$/,
include: /sprite/,
use: 'svg-sprite-loader',
},
{
test: /\.svg$/,
use: 'url-loader',
exclude: /sprite/,
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
// Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV`
// inside your code for any environment checks; UglifyJS will automatically
// drop any unreachable code.
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
API_V: JSON.stringify(process.env.API_V),
CONTENT_PREVIEW: JSON.stringify(process.env.CONTENT_PREVIEW),
},
}),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: ['.js', '.jsx', '.react.js'],
mainFields: ['browser', 'main', 'jsnext:main'],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
});
webpack.projd.babel.js:
// Important modules this config uses
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { HashedModuleIdsPlugin } = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = require('./webpack.base.babel')({
mode: 'production',
// In production, we skip all hot-reloading stuff
entry: [path.join(process.cwd(), 'app/app.js')],
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
optimization: {
minimize: true,
nodeEnv: 'production',
sideEffects: true,
concatenateModules: true,
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.(scss|css)$/,
chunks: 'all',
enforce: true,
},
},
},
runtimeChunk: true,
},
plugins: [
// Minify and optimize the index.html
new HtmlWebpackPlugin({
template: 'app/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
inject: true,
}),
new WebpackPwaManifest({
name: 'LEDA',
short_name: 'LEDA',
description: '',
background_color: '#ffffff',
theme_color: '#00bae4',
icons: [
{
src: path.resolve('app/images/favicon.png'),
sizes: [72, 96, 120, 128, 144, 152, 167, 180, 192],
},
],
}),
new HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 20,
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
new UglifyJsPlugin({
parallel: true,
uglifyOptions: {
ecma: 6,
},
cache: path.join(__dirname, 'webpack-cache/uglify-cache'),
}),
],
performance: {
assetFilter: assetFilename =>
!/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename),
},
});
webpack.dev.babel.js:
/**
* DEVELOPMENT WEBPACK CONFIGURATION
*/
const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const logger = require('../../server/logger');
const cheerio = require('cheerio');
const pkg = require(path.resolve(process.cwd(), 'package.json'));
const dllPlugin = pkg.dllPlugin;
const plugins = [
new webpack.ContextReplacementPlugin(
/\.\/locale$/,
'empty-module',
false,
/js$/
),
new webpack.HotModuleReplacementPlugin(), // Tell webpack we want hot reloading
new webpack.ContextReplacementPlugin(
/\.\/locale$/,
'empty-module',
false,
/js$/
),
new HtmlWebpackPlugin({
inject: true, // Inject all files that are generated by webpack, e.g. bundle.js
templateContent: templateContent(), // eslint-disable-line no-use-before-define
}),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules|components\/Routes/, // exclude node_modules
failOnError: false, // show a warning when there is a circular dependency
}),
];
module.exports = require('./webpack.base.babel')({
mode: 'development',
// Add hot reloading in development
entry: [
'eventsource-polyfill', // Necessary for hot reloading with IE
'webpack-hot-middleware/client?reload=true',
path.join(process.cwd(), 'internals/dev-preamble.js'),
path.join(process.cwd(), 'app/app.js'), // Start with js/app.js
],
// Don't use hashes in dev mode for better performance
output: {
filename: '[name].js',
chunkFilename: '[name].chunk.js',
},
optimization: {
minimize: false,
},
// Add development plugins
plugins: dependencyHandlers().concat(plugins), // eslint-disable-line no-use-before-define
// Tell babel that we want to hot-reload
babelQuery: {
// require.resolve solves the issue of relative presets when dealing with
// locally linked packages. This is an issue with babel and webpack.
// See https://github.com/babel/babel-loader/issues/149 and
// https://github.com/webpack/webpack/issues/1866
presets: ['babel-preset-react-hmre'].map(require.resolve),
},
// Emit a source map for easier debugging
devtool: 'inline-source-map',
performance: {
hints: false,
},
});
/**
* Select which plugins to use to optimize the bundle's handling of
* third party dependencies.
*
* If there is a dllPlugin key on the project's package.json, the
* Webpack DLL Plugin will be used.
*
*/
function dependencyHandlers() {
// Don't do anything during the DLL Build step
if (process.env.BUILDING_DLL) {
return [];
}
// Don't do anything if package.json does not have a dllPlugin property
// Code splitting now included by default in Webpack 4
if (!dllPlugin) {
return [];
}
const dllPath = path.resolve(
process.cwd(),
dllPlugin.path || 'node_modules/react-boilerplate-dlls'
);
/**
* If DLLs aren't explicitly defined, we assume all production dependencies listed in package.json
* Reminder: You need to exclude any server side dependencies by listing them in dllConfig.exclude
*/
if (!dllPlugin.dlls) {
const manifestPath = path.resolve(dllPath, 'reactBoilerplateDeps.json');
if (!fs.existsSync(manifestPath)) {
logger.error(
'The DLL manifest is missing. Please run `npm run build:dll`'
);
process.exit(0);
}
return [
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(manifestPath), // eslint-disable-line global-require
}),
];
}
// If DLLs are explicitly defined, we automatically create a DLLReferencePlugin for each of them.
const dllManifests = Object.keys(dllPlugin.dlls).map(name =>
path.join(dllPath, `/${name}.json`)
);
return dllManifests.map(manifestPath => {
if (!fs.existsSync(path)) {
if (!fs.existsSync(manifestPath)) {
logger.error(
`The following Webpack DLL manifest is missing: ${path.basename(
manifestPath
)}`
);
logger.error(`Expected to find it in ${dllPath}`);
logger.error('Please run: npm run build:dll');
process.exit(0);
}
}
return new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(manifestPath), // eslint-disable-line global-require
});
});
}
/**
* We dynamically generate the HTML content in development so that the different
* DLL Javascript files are loaded in script tags and available to our application.
*/
function templateContent() {
const html = fs
.readFileSync(path.resolve(process.cwd(), 'app/index.html'))
.toString();
if (!dllPlugin) {
return html;
}
const doc = cheerio(html);
const body = doc.find('body');
const dllNames = !dllPlugin.dlls
? ['reactBoilerplateDeps']
: Object.keys(dllPlugin.dlls);
dllNames.forEach(dllName =>
body.append(`<script data-dll='true' src='/${dllName}.dll.js'></script>`)
);
return doc.toString();
}
Finally webpack.dll.babel.js:
/**
* WEBPACK DLL GENERATOR
*
* This profile is used to cache webpack's module
* contexts for external library and framework type
* dependencies which will usually not change often enough
* to warrant building them from scratch every time we use
* the webpack process.
*/
const { join } = require('path');
const defaults = require('lodash/defaultsDeep');
const webpack = require('webpack');
const pkg = require(join(process.cwd(), 'package.json'));
const dllPlugin = require('../config').dllPlugin;
if (!pkg.dllPlugin) {
process.exit(0);
}
const dllConfig = defaults(pkg.dllPlugin, dllPlugin.defaults);
const outputPath = join(process.cwd(), dllConfig.path);
module.exports = require('./webpack.base.babel')({
mode: 'development',
context: process.cwd(),
entry: dllConfig.dlls ? dllConfig.dlls : dllPlugin.entry(pkg),
optimization: {
minimize: false,
},
devtool: 'eval',
output: {
filename: '[name].dll.js',
path: outputPath,
library: '[name]',
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: join(outputPath, '[name].json'),
}),
],
performance: {
hints: false,
},
});
package.json:
{
"name": "react-boilerplate",
"version": "3.4.0",
"description": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices",
"repository": {
"type": "git",
"url": "git://github.com/react-boilerplate/react-boilerplate.git"
},
"engines": {
"npm": ">=3",
"node": ">=5"
},
"author": "Max Stoiber",
"license": "MIT",
"scripts": {
"analyze:clean": "rimraf stats.json",
"preanalyze": "npm run analyze:clean",
"analyze": "node ./internals/scripts/analyze.js",
"checkversion": "node ./internals/scripts/checkversion.js",
"preinstall": "npm run checkversion",
"postinstall": "npm run build:dll",
"prebuild": "npm run build:clean",
"build": "webpack --config internals/webpack/webpack.prod.babel.js --color --progress",
"build:prod": "cross-env NODE_ENV=production API_V=production npm run build",
"build:staging": "cross-env NODE_ENV=production API_V=staging npm run build",
"build:clean": "npm run test:clean",
"build:dll": "node ./internals/scripts/dependencies.js",
"start": "cross-env NODE_ENV=development node server",
"start:preview": "cross-env NODE_ENV=development CONTENT_PREVIEW=true node server",
"start:tunnel": "cross-env NODE_ENV=development ENABLE_TUNNEL=true node server",
"start:production": "npm run test && npm run build:prod && npm run start:prod",
"start:staging": "npm run test && npm run build:staging && npm run start:prod",
"start:prod": "cross-env NODE_ENV=production node server",
"presetup": "npm i chalk shelljs",
"setup": "node ./internals/scripts/setup.js",
"postsetup": "npm run build:dll",
"clean:all": "npm run analyze:clean && npm run test:clean && npm run build:clean",
"lint": "npm run lint:js",
"lint:eslint": "eslint",
"lint:js": "npm run lint:eslint -- . ",
"lint:fix": "npm run lint:eslint -- . --fix",
"lint:staged": "lint-staged",
"pretest:coverage": "npm run test:clean",
"test:clean": "rimraf ./coverage",
"test": "cross-env NODE_ENV=test jest",
"test:update": "cross-env NODE_ENV=test jest --updateSnapshot",
"test:coverage": "cross-env NODE_ENV=test jest --coverage",
"test:watch": "cross-env NODE_ENV=test jest --watch",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"flow": "flow; test $? -eq 0 -o $? -eq 2"
},
"lint-staged": {
"*.js": "lint:eslint",
"*.{js,scss}": [
"prettier --write",
"git add"
]
},
"pre-commit": [
"lint:staged",
"test"
],
"dllPlugin": {
"path": "node_modules/react-boilerplate-dlls",
"exclude": [
"chalk",
"compression",
"cross-env",
"express",
"ip",
"minimist"
],
"include": [
"core-js",
"lodash",
"eventsource-polyfill"
]
},
"jest": {
"collectCoverageFrom": [
"app/**/*.{js,jsx}",
"!app/**/*.test.{js,jsx}",
"!app/containers/**/*.{js,jsx}",
"!app/*/RbGenerated*/*.{js,jsx}",
"!app/app.js",
"!app/routes.js"
],
"moduleDirectories": [
"node_modules",
"app"
],
"moduleNameMapper": {
".*\\.(css|less|styl|scss|sass)$": "<rootDir>/internals/mocks/cssModule.js",
".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/internals/mocks/image.js"
},
"setupTestFrameworkScriptFile": "<rootDir>/internals/testing/test-bundler.js",
"testRegex": "tests/.*\\.test\\.js$",
"setupFiles": [
"<rootDir>/internals/testing/test-setup.js"
]
},
"dependencies": {
"axios": "^0.15.3",
"babel-polyfill": "6.20.0",
"bluebird": "^3.5.0",
"chalk": "1.1.3",
"classnames": "^2.2.5",
"compression": "1.6.2",
"cross-env": "3.1.3",
"express": "4.14.0",
"fontfaceobserver": "2.0.7",
"history": "4.6.3",
"immutable": "3.8.2",
"ip": "1.1.4",
"leaflet": "^1.0.3",
"lodash": "4.17.2",
"marked": "^0.3.6",
"mime-types": "^2.1.16",
"minimist": "1.2.0",
"moment": "^2.18.1",
"moment-timezone": "^0.5.13",
"numeral": "^2.0.6",
"pace": "0.0.4",
"pace-js": "^1.0.2",
"prerender-node": "^2.7.2",
"qs": "^6.4.0",
"react": "15.4.1",
"react-dom": "15.4.1",
"react-foundation-components": "^0.12.0",
"react-helmet": "5.0.0",
"react-hot-loader": "^4.0.0",
"react-loadable": "^5.3.1",
"react-modal": "^1.7.7",
"react-player": "^1.5.0",
"react-progressbar.js": "^0.2.0",
"react-redux": "4.4.6",
"react-redux-toastr": "^7.0.0",
"react-router": "4.2.0",
"react-router-dom": "^4.2.2",
"react-router-redux": "5.0.0-alpha.6",
"react-router-scroll-memory": "^1.0.1",
"redux": "3.6.0",
"redux-immutable": "3.0.8",
"redux-saga": "0.16.0",
"redux-segment": "^1.6.2",
"request-promise": "^4.2.1",
"shortid": "^2.2.8",
"sitemap": "^1.13.0",
"store": "^2.0.4",
"tls": "0.0.1",
"tunnel-agent": "^0.6.0"
},
"devDependencies": {
"axios-mock-adapter": "^1.8.1",
"babel-cli": "6.18.0",
"babel-core": "6.21.0",
"babel-eslint": "7.1.1",
"babel-loader": "^7.1.4",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-dynamic-import-node": "1.0.0",
"babel-plugin-react-transform": "2.0.2",
"babel-plugin-root-import": "^5.1.0",
"babel-plugin-transform-es2015-modules-commonjs": "6.18.0",
"babel-plugin-transform-react-constant-elements": "6.9.1",
"babel-plugin-transform-react-inline-elements": "6.8.0",
"babel-plugin-transform-react-jsx-source": "^6.22.0",
"babel-plugin-transform-react-remove-prop-types": "0.2.11",
"babel-preset-env": "^1.6.1",
"babel-preset-latest": "6.16.0",
"babel-preset-react": "6.16.0",
"babel-preset-react-hmre": "1.1.1",
"babel-preset-stage-0": "6.16.0",
"cheerio": "0.22.0",
"circular-dependency-plugin": "^5.0.1",
"coveralls": "2.11.15",
"css-loader": "^0.28.11",
"empty-module": "0.0.2",
"enzyme": "2.6.0",
"eslint": "^3.19.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-config-airbnb-base": "^11.1.3",
"eslint-config-prettier": "^2.6.0",
"eslint-import-resolver-webpack": "0.8.3",
"eslint-plugin-flowtype": "^2.30.4",
"eslint-plugin-import": "2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-prettier": "^2.3.1",
"eslint-plugin-react": "7.5.1",
"eslint-plugin-redux-saga": "0.1.5",
"eventsource-polyfill": "0.9.6",
"exports-loader": "^0.7.0",
"file-loader": "^1.1.11",
"flow-bin": "^0.57.3",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"husky": "^0.14.3",
"image-webpack-loader": "^4.2.0",
"imports-loader": "^0.8.0",
"jest": "^22.4.3",
"jest-cli": "^22.4.3",
"lint-staged": "^3.2.1",
"mini-css-extract-plugin": "^0.4.0",
"ngrok": "2.2.4",
"node-plop": "0.5.4",
"node-sass": "^4.5.3",
"null-loader": "0.1.1",
"plop": "1.7.3",
"postcss-loader": "^2.1.3",
"pre-commit": "1.1.3",
"prettier": "^1.7.4",
"react-addons-test-utils": "15.4.1",
"redux-logger": "^2.10.2",
"rimraf": "2.5.4",
"sass-loader": "^6.0.7",
"shelljs": "0.7.5",
"sinon": "2.0.0-pre",
"style-loader": "^0.20.3",
"svg-sprite-loader": "^3.7.3",
"uglifyjs-webpack-plugin": "^1.2.4",
"url-loader": "^1.0.1",
"webpack": "^4.5.0",
"webpack-cli": "^2.0.14",
"webpack-dev-middleware": "^3.1.2",
"webpack-hot-middleware": "^2.22.0",
"webpack-pwa-manifest": "^3.6.2"
}
}
You need to install the plugin that is being asked:
npm install --save-dev babel-plugin-transform-es3-member-expression-literals
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
}),
you can try it.
Turns out the issue was to do with macos/windows back slashing and forward slashing differences, switching the exclude pattern to this:
exclude: /(node_modules|bower_components!react-redux-toastr)/
Fixed it.