Webpack intermittent react Jenkins build with javascript errors - javascript

My project environment is , React with redux and redux-saga , webpack
Jenkins is used for CI/CD
since a month , we are getting a strange issue, the Jenkins (webpack) build & deployment is successful however when I access the portal it shows a blank page because of below Javascript error
Uncaught ReferenceError: saga is not defined
at Module.1148 (main.44c97d10353333934fe5.bundle.js:1)
at __webpack_require__ (manifest.6a34ff8be70a737e5aa6.bundle.js:1)
at Object.646 (main.44c97d10353333934fe5.bundle.js:1)
at __webpack_require__ (manifest.6a34ff8be70a737e5aa6.bundle.js:1)
at checkDeferredModules (manifest.6a34ff8be70a737e5aa6.bundle.js:1)
at Array.webpackJsonpCallback [as push] (manifest.6a34ff8be70a737e5aa6.bundle.js:1)
at vendor.fef8d73f71dc764a97a1.bundle.js:1
when looked at the failing file in code base the sagas.js file has "export default sagas" , so the s in sagas is truncated during build process hence the javascript error
After re-running the same build in Jenkins then it is producing a clean build and application works normally without above error
and strangely this behaviour doesn't occur on every build it is intermittent
another error similar to this is
built version of utag.js with errors
actual version of utag.js from code base
The main issue is I couldn't replicate the issue locally , I have run the webpack build on the branch which resulted in javascript error - but no luck , everytime webpack produced a clean build locally
Here are my config files
Package.json
{
"name": "portal",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "webpack-dev-server --open --inline --progress --env development --config webpack/dev.config.js",
"build:prod": "webpack --env production --config webpack/prod.config.js",
"build:test": "webpack --env test --config webpack/prod.config.js",
"stylelint": "stylelint '**/*.scss', '**/*.css'",
"stylelint:silentexit": "stylelint '**/*.scss', '**/*.css'; exit 0",
"jslint": "eslint . --fix",
"jslint:silentexit": "eslint .; exit 0",
"test": "npm run jslint && npm run test:unit",
"test:unit": "jest --colors",
"test:watch": "jest --watch --passWithNoTests",
"test:coverage": "jest --coverage -u --colors",
"storybook": "start-storybook -p 9001 -c .storybook",
"generateSvgIconComponents": "styled-svg src/icons/*.svg --size=small:18x18 --size=medium:24x24 --size=large:36x36"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 10",
"not op_mini all"
],
"dependencies": {
"#babel/polyfill": "^7.4.4",
"#rebass/components": "^4.0.0-1",
"acorn": "^6.2.0",
"babel-plugin-react-css-modules": "^5.2.6",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.1.3",
"connected-react-router": "^6.5.2",
"fixed-data-table-2": "^0.8.26",
"glamor": "^2.20.40",
"history": "^4.9.0",
"html-webpack-plugin": "^3.2.0",
"javascript-excel": "^1.0.3",
"jspdf": "^1.5.3",
"jspdf-react": "^1.0.10",
"lodash": "^4.17.14",
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"qs": "^6.6.0",
"react": "^16.8.2",
"react-bootstrap": "^0.32.4",
"react-compound-slider": "^2.3.0",
"react-csv": "^1.1.1",
"react-data-export": "^0.5.0",
"react-draggable": "^4.0.3",
"react-list-drag-and-drop": "^0.9.1",
"react-markdown": "^4.2.2",
"react-pdf": "^4.1.0",
"react-redux": "^6.0.1",
"react-router-dom": "^5.0.1",
"react-tooltip": "^3.10.0",
"react-virtualized": "^9.21.1",
"redux": "^4.0.1",
"redux-actions": "^2.6.4",
"redux-saga": "^1.1.3",
"reselect": "^4.0.0",
"styled-components": "^4.3.1",
"styled-system": "^4.2.4",
"validate.js": "^0.13.1",
"webpack-merge": "^4.2.2",
"whatwg-fetch": "^3.0.0",
"xlsx": "^0.14.3"
},
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/plugin-proposal-class-properties": "^7.4.4",
"#babel/plugin-transform-react-jsx-source": "^7.5.0",
"#babel/preset-env": "^7.4.5",
"#babel/preset-react": "^7.0.0",
"#storybook/react": "^4.1.18",
"babel-eslint": "^10.0.2",
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.6",
"babel-plugin-lodash": "^3.3.4",
"babel-plugin-root-import": "^6.2.0",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-plugin-transform-runtime": "^6.23.0",
"clean-webpack-plugin": "^2.0.2",
"copy-webpack-plugin": "^5.0.4",
"css-loader": "^2.1.1",
"deep-freeze": "0.0.1",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"eslint": "^5.14.1",
"eslint-loader": "^2.1.2",
"eslint-plugin-react": "^7.13.0",
"faker": "^4.1.0",
"html-loader": "^0.5.5",
"jest": "^24.8.0",
"jest-enzyme": "^7.0.1",
"jest-react-hooks-mock": "^1.1.0",
"node-fetch": "^2.6.0",
"pdf2json": "^1.1.8",
"react-dom": "^16.7.0",
"redux-mock-store": "^1.5.3",
"redux-saga-testing": "^1.0.5",
"sinon": "^7.3.2",
"style-loader": "^0.23.1",
"styled-svg": "^2.4.7",
"stylelint": "^9.10.1",
"stylelint-config-standard": "^18.3.0",
"svg-url-loader": "^3.0.0",
"uglifyjs-webpack-plugin": "^2.1.3",
"webpack": "4.41.2",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-cli": "^3.3.4",
"webpack-dev-server": "^3.7.1"
}
}
webpack/base.config.js
'use strict'
const path = require('path')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const HtmlWebpackPlugin = require('html-webpack-plugin')
const dirName = __dirname.replace('webpack','');
const util = require('./util');
// cleans 'dist' folder everytime before a new build
const cleanPLugin = env => (new CleanWebpackPlugin({
root: path.join(dirName, util.getRootContext(env) ),
verbose: true,
dry: false
}));
const AnalyzerPlugin = new BundleAnalyzerPlugin(
{
analyzerMode: 'none'
}
);
const copyWebpackPlugin = env => ( new CopyPlugin([ {
from : path.join(dirName, 'src/assets/static'),
to : path.join(dirName, `dist/${util.getRootContext(env)}/assets`)
}, {
from : path.join(dirName, 'src/assets/pages'),
to : path.join(dirName, `dist/${util.getRootContext(env)}`)
}
]));
const HTMLPlugin = new HtmlWebpackPlugin({
template: path.join(dirName, 'src/scripts/index.html'),
chunksSortMode: 'none'
});
module.exports = (env) => {
// BUILDING WEBPACK
const config = {};
config.plugins = [cleanPLugin(env), AnalyzerPlugin, HTMLPlugin, copyWebpackPlugin(env)]
config.entry = ["whatwg-fetch", "babel-polyfill", path.join(dirName, '/src/scripts/index.js')]
config.output = {
path: path.join(dirName, '/dist'),
filename: '[name].build.js',
chunkFilename: '[name].bundle.js',
}
config.module = {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.(png|jpg|gif|woff|ttf|woff2)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {}
}
},
{
test: /\.(css|less)$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
config.resolve = {
extensions: [ '.js', '.jsx', '.json', '.css' ],
alias: {
DesignSystem: path.resolve(dirName, 'src/design-system/'),
Icons: path.resolve(dirName, 'src/icons/'),
Scripts: path.resolve(dirName, 'src/scripts/'),
CMS: path.resolve(dirName, 'cms/'),
}
}
config.node = { fs: 'empty' }
return config
}
webpack/prod.config.js
const merge = require('webpack-merge');
const baseConfig = require('./base.config.js');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const util = require('./util');
const dirName = __dirname.replace('webpack','');
module.exports = env => (merge(baseConfig(env),
{
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial'
}
}
},
runtimeChunk: {
name: 'manifest'
},
minimizer: [
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: {
ecma: 8,
mangle: false,
keep_classnames: true,
keep_fnames: true
}
})
]
},
output: {
path: path.join(dirName, `./dist/${util.getRootContext(env)}`),
publicPath: `/${util.getRootContext(env)}/`,
chunkFilename: '[name].[chunkhash].bundle.js',
filename: '[name].[chunkhash].bundle.js'
},
mode: 'production'
}
));
npm run build:prod is the command which runs this build
Any tips or help would be greatly appreciated.
Thanks!!

Related

Once there is error, webpack-dev-server will stop working and browser is not auto updated again even after error is fixed

I am using Webpack 5 to build a static HTML boilerplate. Everything works fine, Webpack is compiled successfully and browser is updated whenever I make change to HTML, SCSS/CSS or JS file in my source code.
The problem happens if there is error in the code, WDS will stop working and browser will display an error message in the console, for example:
Even after I fix the error and Webpack says that it is compiled successfully, WDS still does not work and the browser keeps stuck at the error. I have to reload the browser manually to make it work again.
Can anyone please help me? What should I do to make browser updated again after error is fixed?
I found the same question webpack-dev-server stops compiling after a syntax error, requires restart, but there is no proper answer to it so I have to ask another one.
This is my webpack.common.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const fs = require('fs');
// Prepare plugins
const plugins = [
new MiniCssExtractPlugin({
filename: './style/main.css?v=[contenthash]',
}),
new HtmlWebpackPlugin({
template: 'src/index.html',
inject: 'body',
filename: 'index.html',
minify: {
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
];
// Create more HtmlWebpackPlugin
const files = fs.readdirSync(path.resolve('.', 'src/pages'), 'utf8');
files.forEach((file) => {
const page = new HtmlWebpackPlugin({
template: `src/pages/${file}`,
inject: 'body',
filename: `pages/${file}`,
minify: {
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
});
plugins.push(page);
});
module.exports = {
entry: './src/scripts/index.js',
output: {
path: path.resolve('.', 'build'),
filename: './js/bundle.js?v=[contenthash]',
},
module: {
rules: [
{
test: /\.js$/,
use: ['babel-loader'],
exclude: [/node_modules/],
},
{
test: /\.(s?css)$/,
use: [
MiniCssExtractPlugin.loader,
'css-hot-loader',
'css-loader',
'sass-loader',
'import-glob-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true,
postcssOptions: {
plugins: () => [require('autoprefixer')],
},
},
},
],
},
{
test: /\.(gif|png|jpe?g|svg|woff|eot|ttf|woff2)$/,
// use: 'url-loader',
type: 'asset/resource',
},
{
test: /\.html$/i,
loader: 'html-loader', // export HTML as string. HTML is minimized when the compiler demands.
options: {
sources: false,
},
},
],
},
plugins,
};
This is my webpack.dev.js:
const path = require('path');
const { merge } = require('webpack-merge');
const WebpackNotifierPlugin = require('webpack-notifier');
const ESLintPlugin = require('eslint-webpack-plugin');
const StylelintPlugin = require('stylelint-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: path.resolve('.', 'src'), // source of static assets
port: 1802, // port to run dev-server
hot: true, // hot reload
watchContentBase: true,
// open: true, // immediately open browser to show localhost:1802 when start script
},
plugins: [
new ESLintPlugin({}),
new StylelintPlugin({ fix: true }),
new WebpackNotifierPlugin({ onlyOnError: true }),
],
});
This is my package.json
{
"name": "static-web-boilerplate",
"version": "1.0.0",
"description": "Simple boilerplate for developing static web projects",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "cross-env ENV=development webpack serve --config webpack/webpack.dev.js --progress",
"start:prod": "npm run build && serve build",
"build": "cross-env ENV=production webpack --config webpack/webpack.prod.js --progress --stats-error-details"
},
"author": "Hau Pham",
"license": "ISC",
"dependencies": {
"#babel/runtime": "^7.14.6",
"autoprefixer": "^10.2.6",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"copy-webpack-plugin": "^9.0.1",
"css-minimizer-webpack-plugin": "^3.0.2",
"eslint-webpack-plugin": "^2.5.4",
"html-webpack-plugin": "^5.3.2",
"mini-css-extract-plugin": "^1.6.1",
"serve": "^12.0.0",
"stylelint-webpack-plugin": "^2.2.2",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack-merge": "^5.8.0",
"webpack-notifier": "^1.13.0"
},
"devDependencies": {
"#babel/core": "^7.14.6",
"#babel/plugin-transform-runtime": "^7.14.5",
"#babel/preset-env": "^7.14.7",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"cross-env": "^7.0.3",
"css-hot-loader": "^1.4.4",
"css-loader": "^5.2.6",
"eslint": "^7.29.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-stylelint": "^13.1.1",
"eslint-import-resolver-webpack": "^0.13.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-html": "^6.1.2",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-prettier": "^3.4.0",
"file-loader": "^6.2.0",
"html-loader": "^2.1.2",
"import-glob-loader": "^1.1.0",
"node-sass": "^6.0.1",
"postcss-loader": "^6.1.0",
"prettier": "^2.3.2",
"sass-loader": "^12.1.0",
"stylelint": "^13.13.1",
"stylelint-config-prettier": "^8.0.2",
"stylelint-config-recommended": "^5.0.0",
"stylelint-config-standard": "^22.0.0",
"stylelint-config-standard-scss": "^1.1.0",
"stylelint-scss": "^3.19.0",
"terser-webpack-plugin": "^5.1.4",
"url-loader": "^4.1.1",
"webpack": "^5.41.1",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
}
}
After many hours of research, I have found the solution. According to comment on webpack-dev-server github page, updating webpack-dev-server to version 4 should fix this. I tried and it did fix the issue!
(At the time of this answer, the newest version 4 is 4.0.0-beta.3)

Published npm package does not apply styles

I'm currently working on creating an npm package. Which is basically a React component with added styles using SCSS. When I test it out, the class names are there, but no styles are being applied.
Here is the repo for the package. I use a separated webpack config for building the specific folder where the component is.
Here's the webpack configuration I'm using:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const EsLintFormatter = require('eslint-formatter-pretty');
const path = require('path');
const pkg = require('../../package.json');
const { SRC_PATH, BUILD_PATH } = require('./constants');
const setStyleLoaders = require('./style-loaders');
const alias = require('./alias');
const packageName = pkg.name;
module.exports = ({ NODE_ENV }) => ({
mode: 'production',
entry: `${SRC_PATH}/components/Carousel/Carousel.js`,
output: {
path: BUILD_PATH,
filename: 'index.js',
library: packageName,
libraryTarget: 'commonjs2',
umdNamedDefine: true,
publicPath: '/build/',
},
node: {
net: 'empty',
tls: 'empty',
dns: 'empty',
},
resolve: {
alias: {
...alias,
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
},
},
externals: {
react: 'react',
reactDom: 'react-dom',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: [
{ loader: 'babel-loader' },
{
loader: 'eslint-loader',
options: {
formatter: EsLintFormatter,
},
},
],
},
{
test: /\.(sa|sc|c)ss$/,
use: setStyleLoaders(NODE_ENV),
},
{
test: /\.(png|pje?g|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
},
},
],
},
{
test: /\.(woff|woff2|tff|otf|eot)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'fonts',
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({ filename: 'index.css' }),
],
});
...and here's my package.json
{
"name": "react-clear-carousel",
"version": "0.1.0-beta.1",
"description": "A test",
"main": "build/index.js",
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --env.NODE_ENV=development --config config/webpack/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --env.NODE_ENV=production --config config/webpack/webpack.config.publish.js",
"stylelint": "stylelint 'src/**/*.scss' --config stylelint.config.js; exit 0",
"eslint": "eslint 'src/**/*.js'; exit 0",
"es:fix": "eslint 'src/**/*.js' --fix",
"style:fix": "stylelint 'src/**/*.scss' --fix",
"lint": "npm run eslint && npm run stylelint",
"publish:beta": "npm publish --tag=beta",
"test": "jest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RobCC/web-playground.git"
},
"author": "robcc",
"license": "ISC",
"bugs": {
"url": "https://github.com/RobCC/web-playground/issues"
},
"files": [
"dist"
],
"jest": {
"setupFilesAfterEnv": [
"<rootDir>/config/jest/setup.js"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
"\\.(css|less|scss)$": "identity-obj-proxy",
"^~/(.*)": "<rootDir>/$1",
"^#/(.*)": "<rootDir>/src/$1"
}
},
"homepage": "https://github.com/RobCC/web-playground#readme",
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1",
"prop-types": "^15.7.2"
},
"devDependencies": {
"#babel/cli": "^7.8.4",
"#babel/core": "^7.9.0",
"#babel/plugin-proposal-class-properties": "^7.8.3",
"#babel/plugin-proposal-export-default-from": "^7.8.3",
"#babel/plugin-proposal-export-namespace-from": "^7.8.3",
"#babel/preset-env": "^7.9.0",
"#babel/preset-react": "^7.9.1",
"#types/jest": "^25.1.4",
"#types/node": "^13.9.2",
"#types/react": "^16.9.25",
"#types/react-dom": "^16.9.5",
"#welldone-software/why-did-you-render": "^4.0.5",
"autoprefixer": "^9.7.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"chalk": "^3.0.0",
"clean-webpack-plugin": "^3.0.0",
"core-js": "^3.6.4",
"cross-env": "^7.0.2",
"css-loader": "^3.4.2",
"cssnano": "^4.1.10",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.2",
"eslint": "^6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-formatter-pretty": "^3.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^2.5.1",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^3.2.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^25.1.0",
"log-symbols": "^3.0.0",
"mini-css-extract-plugin": "^0.9.0",
"postcss-loader": "^3.0.0",
"pr*op-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"regenerator-runtime": "^0.13.5",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.3",
"stylelint": "^13.2.1",
"stylelint-config-recommended": "^3.0.0",
"stylelint-formatter-pretty": "^2.0.0",
"stylelint-scss": "^3.16.0",
"stylelint-webpack-plugin": "^1.2.3",
"ts-loader": "^6.2.1",
"typescript": "^3.8.3",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"dependencies": {
"weak-key": "^1.0.2"
}
}
This is the result when testing the published package:
Edit 1:
There are no errors on the Network and Console tab in devtools. I also can't find the file loaded, even though it's there in the package. It seems like the js file is not using it, but it should.
Edit 2:
Thanks for pointing me on the right direction!
I added import 'react-clear-carousel/build/index.css'; to include the CSS file from my package. I can see the file now (on devtools), but the styles are not being applied since css-loader is modularizing it and adding additional suffix and prefix (even though it already had them), thus having different class names that the ones my component has.
eg. My component is rendered as <div class="carousel_swimlane--kXSjh">, but the styles in the DOM are named as index_carousel_swimlane--kXSjh--2C.
I guess the question is now, how do I tell Webpack to pass this CSS as is? And if there's a way for me to deliver the CSS file without other people having to change their Webpack configuration.
Looking at your repo I see that you are importing your scss but attributing it's properties to classNames.
className should be the name of the class, and you can either attribute your imported styles to style or you can load your compiled css into the DOM using <link rel="stylesheet" type="text/css" href="styles.min.css">
The reason you're not seeing a stylesheet in the network tab is because you've simply forgotten to declare a stylesheet.

Slow initial webpack build

I'm using React + Redux + Webpack but having an annoying development experience when every time I rerun the node server (using JetBrains WebStorm) it takes 2.5 minutes for webpack to bunde everything together.
I tried every possible technique to make webpack initial build faster but with no success. It takes 2.5 minutes to run this.
I tried:
Babel caching
Webpack module analyzer
excluding node_modules
Here is my webpack.config.js file:
let path = require('path')
let webpack = require('webpack')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
let entry = {
bundle: './src/index',
vendor: [
'react',
'react-dom',
'redux',
'react-redux',
'react-router',
'react-router-dom',
'react-router-redux',
'redux-thunk',
'd3',
'immutable',
'moment',
'axios',
'openlayers',
'react-table',
'react-select',
'reselect'
]
}
let plugins = [
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js' }),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(ENV === 'prod' ? 'production' : 'development'),
API_URL: JSON.stringify(API_URL),
BASIC: JSON.stringify(BASIC)
}
}),
new webpack.optimize.UglifyJsPlugin({
beautify: false,
comments: false,
compress: {
sequences : true,
booleans : true,
loops : true,
unused : true,
warnings : false,
drop_console: true,
unsafe : true
}
})
]
const config = {
entry: entry,
cache: true,
devtool: 'cheap-module-source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/dist/'
},
plugins: plugins,
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
query: {
plugins: ['transform-runtime']
},
include: [path.resolve(__dirname, "src")],
exclude: /node_modules/
},
{
test: /\.(css|less)$/,
use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
`image-webpack-loader?${JSON.stringify(query)}`
]
},
{
test: /\.(eot|woff|woff2|ttf)$/,
loader: 'url-loader?limit=30000&name=[name]-[hash].[ext]'
}
]
}
}
module.exports = config
and here is my package.json file:
{
"name": "Aloha",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"start-debug": "node $NODE_DEBUG_OPTION server.js",
"build": "webpack",
"test": "jest --verbose",
"test:watch": "npm test -- --watch",
"test-coverage": "jest --coverage",
"webpack-stats": "webpack --profile",
"startwatch": "nodemon server.js"
},
"author": "Aloha",
"license": "ISC",
"devDependencies": {
"#amcharts/amcharts3-react": "^3.0.0",
"babel-core": "^6.11.4",
"babel-eslint": "^8.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-0": "^6.5.0",
"css-loader": "^0.28.4",
"eslint": "^4.12.1",
"eslint-loader": "^1.4.1",
"eslint-plugin-react": "^7.0.1",
"file-loader": "^1.1.5",
"image-webpack-loader": "^3.3.1",
"less": "^2.7.1",
"less-loader": "^4.0.5",
"postcss-loader": "^2.0.9",
"redux-mock-store": "^1.2.1",
"style-loader": "^0.19.0",
"url-loader": "^0.6.2",
"webpack-bundle-analyzer": "^2.9.1",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.12.1"
},
"dependencies": {
"axios": "^0.17.1",
"babel-preset-es2017": "^6.24.1",
"body-parser": "^1.17.2",
"classnames": "^2.2.5",
"compression": "^1.6.2",
"connect-multiparty": "^2.0.0",
"cookie-parser": "^1.4.3",
"d3": "^4.3.0",
"dotenv": "^4.0.0",
"express": "^4.15.3",
"history": "^4.7.2",
"http-proxy-middleware": "^0.17.4",
"immutable": "^3.8.1",
"lodash": "^4.17.4",
"moment": "^2.14.1",
"moment-timezone": "^0.5.13",
"nodemon": "^1.12.1",
"openlayers": "^4.5.0",
"prop-types": "^15.5.10",
"querystring": "^0.2.0",
"rc-collapse": "^1.7.5",
"react": "^16.2.0",
"react-block-ui": "^1.1.1",
"react-datetime": "^2.8.6",
"react-dom": "^16.2.0",
"react-imageloader": "^2.1.0",
"react-notification-system": "^0.2.15",
"react-redux": "^5.0.5",
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.8",
"react-select": "^1.0.0-rc.5",
"react-table": "^6.7.4",
"react-tabs": "^2.1.1",
"redux": "^3.7.2",
"redux-thunk": "^2.1.0",
"request": "^2.74.0",
"reselect": "^3.0.1",
"webpack": "^3.9.1"
}
}
Help will be deeply appreciated !
This is honestly not that surprising. It depends a lot on the complexity of your code and your machine. It takes about 1 min 15 seconds for my project on a high end iMac.
Personally if you’re new to development create-react-app is still a great starting point as it has hot reloading. Use webpack watch or something similar so you can see updates as you develop.
There should be no reason to rerun the node server after changes. The only time to rerun node will be when you deploy.
You can wire in webpack dev server, and I'm quite sure a solution can be found by using concurrently
In package.json, wire in "dev":"concurrently \"npm run server\" \"npm run client\""
where "server":"nodemon index.js" and "client":"webpack-dev-server ...".
I haven't tested this exact setup, but do use it with create react app where client is simply
npm run start --prefix client
It depends a lot on your machine. Make sure you have enough disk space and good processor for your project.
Apart from this, for more improvements you can go through this link.

SyntaxError: Unexpected token

I am trying to configure my application (https://github.com/freeCodeCamp/meeting-for-good) for testing. I am using jest. However, I get an error when I run my test. It looks like path to my AboutDialog component is failing to transpile.
zach#zach-VirtualBox:~/Documents/Code/fcc-for-good/meeting-for-good$ npm run test
> meeting-for-good#1.0.12 test /home/zach/Documents/Code/fcc-for-good/meeting-for-good
> cross-env NODE_ENV=test jest
FAIL __tests__/test.js
● Test suite failed to run
/home/zach/Documents/Code/fcc-for-good/meeting-for-good/client/components/AboutDialog/about-dialog.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.AboutDialog {
^
SyntaxError: Unexpected token .
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
at Object.<anonymous> (client/components/AboutDialog/AboutDialog.js:7:20)
at Object.<anonymous> (__tests__/test.js:2:20)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 8.204s
Ran all test suites.
I am trying to import my AboutDialog component to my test.
import React from 'react';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import cssModules from 'react-css-modules';
import PropTypes from 'prop-types';
import styles from './about-dialog.css';
const inlineStyles = {
modal: { content: { width: '630px', maxWidth: '630px' }, bodyStyle: { paddingTop: 10, fontSize: '25px' } },
};
const AboutDialog = (props) => {
const { cbOpenModal, openModal } = props;
const actions = [
<FlatButton label="close" primary onTouchTap={() => cbOpenModal()} />,
];
return (
<Dialog
contentStyle={inlineStyles.modal.content}
bodyStyle={inlineStyles.modal.bodyStyle}
actions={actions}
modal
styleName="AboutDialog"
open={openModal}
>
<h1 styleName="titleStyle">Meeting for Good</h1>
<h6 styleName="versionStyle">Version {process.env.versionNumber}</h6>
<h4 styleName="descStyle">THE BEST MEETING COORDINATION APP</h4>
<h6>Created by campers from FreeCodeCamp</h6>
<h6> License and GitHub Repository</h6>
</Dialog>
);
};
AboutDialog.propTypes = {
cbOpenModal: PropTypes.func.isRequired,
openModal: PropTypes.bool.isRequired,
};
export default cssModules(AboutDialog, styles);
My test. If I remove the AboutDialog import from my test , the test suite runs.
import React from 'react';
import AboutDialog from '../client/components/AboutDialog/AboutDialog';
import { shallow } from 'enzyme';
describe('Test', () => {
it('should test', () => {
});
});
My .babelrc file.
{
"presets": ["react", "es2015", "stage-1"],
"plugins": [
"transform-decorators-legacy",
"react-hot-loader/babel",
["transform-runtime", { "polyfill": false, "regenerator": true }]
],
"env": {
"development": {
"presets": [
"react-hmre"
]
}
}
}
My package.json
{
"name": "meeting-for-good",
"version": "1.0.12",
"description": "Schedule events with ease!",
"homepage": "https://github.com/FreeCodeCamp/meeting-for-good/#readme",
"main": "index.js",
"scripts": {
"clean": "rimraf build",
"build:server": "babel -d ./build ./server -s",
"build:client": "cross-env NODE_ENV=production babel-node ./tools/build.js",
"build": "npm run clean && npm run copy && npm run build:server && npm run build:client",
"start": " node ./build/app.js",
"copy": "node tools/copy.js",
"serve": "npm run clean && npm run copy && npm run build:server && npm run dev",
"dev": "cross-env NODE_ENV=development node -r dotenv/config ./build/app.js",
"test": "cross-env NODE_ENV=test jest",
"heroku-postbuild": "npm run build",
"postinstall": "node tools/postInstall.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/FreeCodeCamp/meeting-for-good"
},
"author": "Jean Philip de Rogatis <jrogatis#rogatis.eti.br>",
"contributors": [
{
"name": "Aniruddh Agarwal",
"email": "aaniruddh99#gmail.com"
},
{
"name": "Bob Sutton",
"email": "anischyros#gmail.com"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/FreeCodeCamp/meeting-for-good/issues"
},
"engines": {
"node": "^8.0.0",
"npm": "^5.0.0"
},
"dependencies": {
"autobind-decorator": "^2.1.0",
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.2.1",
"babel-loader": "^7.1.1",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-1": "^6.22.0",
"babel-runtime": "^6.25.0",
"bluebird": "^3.5.0",
"body-parser": "^1.17.2",
"chai": "^4.1.0",
"chalk": "^2.0.1",
"chroma-js": "^1.3.3",
"chunk-manifest-webpack2-plugin": "^1.0.1",
"clipboard": "^1.6.1",
"compression": "^1.7.0",
"connect-flash": "^0.1.1",
"connect-mongo": "^1.3.2",
"cookie-parser": "^1.4.3",
"copy-webpack-plugin": "^4.0.1",
"cpy-cli": "^1.0.1",
"cross-env": "^5.0.1",
"css-loader": "^0.28.1",
"cssnano": "^3.10.0",
"dialog-polyfill": "^0.4.6",
"dotenv": "^4.0.0",
"ejs": "^2.5.5",
"email-templates": "^2.5.6",
"es6-promise": "^4.1.1",
"express": "^4.15.3",
"express-session": "^1.15.4",
"express-sessions": "^1.0.6",
"extract-text-webpack-plugin": "^2.1.0",
"fast-json-patch": "^2.0.4",
"favicons-webpack-plugin": "0.0.7",
"file-loader": "^0.11.1",
"google-calendar": "^1.3.2",
"html-loader": "^0.4.4",
"html-webpack-plugin": "^2.29.0",
"image-webpack-loader": "^3.3.1",
"immutable": "^3.8.1",
"isomorphic-fetch": "^2.2.1",
"jstimezonedetect": "^1.0.6",
"lodash": "^4.17.2",
"material-ui": "^0.18.5",
"mocha": "^3.4.2",
"moment": "^2.18.1",
"moment-range": "^3.0.3",
"mongoose": "^4.11.3",
"morgan": "^1.8.2",
"nodemailer": "^4.0.1",
"nodemailer-ses-transport": "^1.5.0",
"nprogress": "^0.2.0",
"offline-plugin": "^4.8.3",
"opbeat": "^4.14.2",
"optimize-css-assets-webpack-plugin": "^2.0.0",
"passport": "^0.3.2",
"passport-facebook": "^2.1.1",
"passport-google-oauth": "^1.0.0",
"passport-oauth2-refresh": "^1.0.0",
"pngquant-bin": "^3.1.1",
"prop-types": "^15.5.10",
"react": "^15.6.0",
"react-addons-update": "^15.5.2",
"react-css-modules": "^4.3.0",
"react-day-picker": "^5.5.1",
"react-dom": "^15.6.0",
"react-ga": "^2.2.0",
"react-hot-loader": "^3.0.0-beta.7",
"react-infinite": "^0.11.0",
"react-input-range": "^1.2.1",
"react-masonry-component": "^5.0.3",
"react-moment-proptypes": "^1.4.0",
"react-notification-system": "^0.2.14",
"react-router": "^3.0.2",
"react-tap-event-plugin": "^2.0.1",
"react-tooltip": "^3.3.0",
"react-transform-hmr": "^1.0.4",
"request": "^2.81.0",
"rimraf": "^2.6.1",
"shelljs": "^0.7.7",
"style-loader": "^0.18.1",
"url-loader": "^0.5.7",
"webpack": "^2.7.0",
"webpack-assets-manifest": "^0.7.0",
"webpack-bundle-analyzer": "^2.8.3",
"webpack-config": "^7.0.0",
"write-file-webpack-plugin": "^4.0.0",
"yargs": "^8.0.1"
},
"devDependencies": {
"babel-jest": "^20.0.3",
"babel-preset-jest": "^20.0.3",
"enzyme": "^2.9.1",
"eslint": "^3.19.0",
"eslint-config-airbnb": "^15.0.0",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.8.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.0",
"eslint-plugin-react": "^7.0.1",
"jest": "^20.0.4",
"jest-css-modules": "^1.1.0",
"react-dom": "^15.6.1",
"react-test-renderer": "^15.6.1",
"regenerator-runtime": "^0.10.5",
"webpack-dev-middleware": "^1.11.0",
"webpack-dev-server": "^2.5.1",
"webpack-hot-middleware": "^2.18.2"
},
"jest": {
"transform": {
".*": "<rootDir>/node_modules/babel-jest"
}
}
}
My webpack config for development.
const webpack = require('webpack');
const WriteFilePlugin = require('write-file-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCSS = require('optimize-css-assets-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const WebpackAssetsManifest = require('webpack-assets-manifest');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const cssNano = require('cssnano');
const packageJSON = require('./package.json');
const noVisualization = process.env.ANALYSE_PACK.toString() === 'false';
const lintCode = process.env.LINT_CODE.toString() === 'false';
const VENDOR_LIBS = [
'autobind-decorator',
'bluebird',
'clipboard',
'chroma-js',
'es6-promise',
'fast-json-patch',
'immutable',
'isomorphic-fetch',
'jstimezonedetect',
'lodash',
'material-ui',
'moment',
'moment-range',
'nprogress',
'react',
'react-addons-update',
'react-day-picker',
'react-tap-event-plugin',
'react-dom',
'react-css-modules',
'react-infinite',
'react-input-range',
'react-masonry-component',
'react-notification-system',
'react-router',
];
module.exports = {
context: __dirname,
entry: {
bundle: [
'react-hot-loader/patch',
'webpack-hot-middleware/client?reload=true',
'./client/main.js',
],
vendor: VENDOR_LIBS,
},
output: {
path: path.resolve('./build/client'),
publicPath: '/client/',
filename: '[name].[hash].js',
},
module: {
rules: [
(!lintCode ? {
test: /\.js$/,
enforce: 'pre',
loader: 'eslint-loader',
options: {
emitWarning: true,
},
} : {}),
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.(ttf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
use: 'file-loader',
},
{
test: /\.(png|jp?g|gif|svg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 1000,
},
},
{
loader: 'image-webpack-loader',
query: {
mozjpeg: {
progressive: true,
},
gifsicle: {
interlaced: false,
},
optipng: {
optimizationLevel: 4,
},
pngquant: {
quality: '75-90',
speed: 3,
},
},
},
],
},
{
test: /\.css$/,
exclude: [/node_modules/, /no-css-modules/],
use: [{
loader: 'style-loader?sourceMap',
},
{
loader: 'css-loader?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
},
],
},
{
test: /\.css$/,
include: [/node_modules/, /no-css-modules/],
use: ExtractTextPlugin.extract({
fallback: 'style-loader?sourceMap',
use: 'css-loader',
}),
},
],
},
plugins: [
(!noVisualization ?
new BundleAnalyzerPlugin({
analyzerMode: 'static',
}) : null),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.GOOGLE_ANALYTICS_ID': JSON.stringify(process.env.GOOGLE_ANALYTICS_ID),
'process.env.GOOGLE_ANALYTICS_DEBUG': JSON.stringify(process.env.GOOGLE_ANALYTICS_DEBUG),
'process.env.versionNumber': JSON.stringify(packageJSON.version),
}),
new ExtractTextPlugin('vendor.css'),
new OptimizeCSS({
assetNameRegExp: /\.optimize\.css$/g,
cssProcessor: cssNano,
cssProcessorOptions: {
discardComments: {
removeAll: true,
},
canPrint: true,
},
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[hash].js',
minChunks: 'Infinity',
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new WriteFilePlugin({
test: /\.(html|ejs)$/,
}),
new FaviconsWebpackPlugin({
logo: './client/assets/favicons/logo.png',
icons: {
appleStartup: false,
},
background: 'transparent',
persistentCache: true,
inject: true,
}),
new HtmlWebpackPlugin({
title: 'Meeting for Good',
template: 'html-loader!./client/index.html',
filename: '../index.html',
inject: 'body',
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new WebpackAssetsManifest({
writeToDisk: true,
merge: true,
done(manifest) {
console.log(`The manifest has been written to ${manifest.getOutputPath()}`);
},
apply(manifest) {
manifest.set('manifest_version', '2');
manifest.set('start_url', '/?homescreen=1');
manifest.set('version', '1');
manifest.set('default_locale', 'en');
manifest.set('description', 'THE BEST MEETING COORDINATION APP');
manifest.set('display', 'fullscreen');
manifest.set('short_name', 'MeetingFG');
manifest.set('name', 'Meeting For Good');
manifest.set('background_color', '#FBFFFB');
manifest.set('theme_color', '#FBFFFB');
},
}),
].filter(p => p),
resolve: {
extensions: ['.js', '.css'],
},
devtool: 'source-map',
};
I figured it out. I just needed to use jest-css-modules (https://www.npmjs.com/package/jest-css-modules).
So I just have to add to make package.json
"jest": {
"transform": {
".*": "<rootDir>/node_modules/jest-css-modules"
}
}

React.js Error: Invariant Violation: Minified React error #37

I've tried looking up in the internet, but I can't find the solution for this error.
Essentially, when I run my app in my localhost via npm start, it runs without a problem.
However, when I switch to git branch gh-pages to host in the gh-pages, I see the following error in my console.log
Uncaught Invariant Violation: Minified React error #37
_registerComponent(...): Target container is not a DOM element is what error #37 means.
Link to Git App Repository gh-pages branch
Here's my current setup:
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var ghpages = require('gh-pages');
var WriteFilePlugin = require('write-file-webpack-plugin');
module.exports = {
devtool: 'source-map',
entry: [
'./src/index.js'
],
output: {
publicPath: '/',
filename: 'bundle.js',
sourceMapFilename: "./bundle.js.map",
path: path.join(__dirname, './static')
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['react', 'es2015', 'stage-1']
}
},{
test: /\.s?css$/,
loaders: ['style','css','sass'],
include: path.join(__dirname, 'src')
}]
},
resolve: {
extensions: ['', '.js', '.jsx'],
alias: {
'jquery': path.join(__dirname, 'node_modules/jquery/dist/jquery'),
}
},
devServer: {
historyApiFallback: true,
contentBase: './',
outputPath: path.join(__dirname, './dist')
}
};
package.json
{
"name": "recipe-box",
"version": "1.0.0",
"description": "Portfolio",
"main": "index.js",
"repository": "",
"scripts": {
"start": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js",
"test": "mocha --compilers js:babel-core/register --require ./test/test_helper.js --recursive ./test",
"test:watch": "npm run test -- --watch",
"postinstall": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.2.1",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"chai": "^3.5.0",
"chai-jquery": "^2.0.0",
"file-loader": "^0.9.0",
"gh-pages": "^0.11.0",
"image-webpack-loader": "^2.0.0",
"jquery": "^3.1.0",
"jsdom": "^9.5.0",
"mocha": "^3.0.2",
"node-sass": "^3.8.0",
"react-addons-test-utils": "^15.3.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.14.0",
"write-file-webpack-plugin": "^3.3.0"
},
"dependencies": {
"babel-preset-stage-1": "^6.1.18",
"css-loader": "^0.25.0",
"express": "^4.14.0",
"jquery": "^2.2.4",
"lodash": "^4.16.1",
"materialize-css": "^0.97.7",
"node-sass": "^3.8.0",
"react": "^15.3.1",
"react-bootstrap": "^0.30.3",
"react-dom": "^15.3.1 ",
"react-materialize": "^0.16.4",
"react-redux": "^4.0.0",
"react-router": "^2.0.1",
"react-tap-event-plugin": "^1.0.0",
"redux": "^3.0.4",
"redux-logger": "^2.6.1",
"sass-loader": "^4.0.0",
"shortid": "^2.2.6",
"style-loader": "^0.13.1"
}
}
Answered my own question
It looked like I had to move bundle.js out from dist folder to the same directory where my index.html was.

Categories

Resources