How to display console.logs using Webpack build? - reactjs

I'm using Webpack to build a React app. I'm trying to use console.log to debug but they don't show up in the browser console or in the terminal. It doesn't seem to like there's too much on this (The only other question I've found on this is here: Webpack console.log output?)
webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/App.tsx',
mode: 'development',
module: {
rules: [
{
test: /\.(|ts|tsx|js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react',
'#babel/preset-typescript',
],
plugins: [
'#babel/plugin-proposal-class-properties',
],
},
},
},
{
test: /\.(css|scss)$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(jpe?g|gif|png|svg)$/i,
loader: 'url-loader',
options: {
limit: 25000,
esModule: false,
},
},
],
},
resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'] },
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '/dist/',
filename: 'bundle.js',
},
devServer: {
contentBase: path.join(__dirname, 'public/'),
port: 3000,
publicPath: 'http://localhost:3000/dist/',
hot: true,
},
plugins: [new webpack.HotModuleReplacementPlugin()],
};
App.tsx
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
console.log('test1') // this gets logged
render(<Hello />, document.querySelector('#main'));
Hello.tsx
import React, { RefObject } from 'react';
interface Props { }
interface State { }
console.log('test2') // this gets logged
export default class Hello extends React.Component<Props, State> {
private start() {
console.log('test3') // this doesn't get logged
}
constructor(p: Props) {
super(p);
this.start();
console.log('test4') // this gets logged
}
}
Any insights are appreciated!

Related

React froala Super expression must either be null or a function not undefined

I am trying to use froala editor in my react code and It is working perfectly in my local. But in production it is crashing. It is just a blank page. When I opened console there is a error message Super expression must either be null or a function not undefined. If I remove froala editor then it is working fine.
import React from 'react';
import 'froala-editor/css/froala_style.min.css';
import 'froala-editor/css/froala_editor.pkgd.min.css';
import FroalaEditorComponent from 'react-froala-wysiwyg';
const Editor = (props) => {
return <FroalaEditorComponent {...props} />;
};
export default Editor;
and this is my webpack config
const webpack = require('webpack');
const path = require('path');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
main: ['./client/app/main'],
},
externals: {
react: 'React',
'react-dom': 'ReactDOM'
},
output: {
path: path.resolve(__dirname, './client/dist'),
filename: '[name].app.bundle.js',
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.html$/,
loader: 'file-loader?name=[name].[ext]',
},
{
test: /\.js?$/,
exclude: /node_modules[\/\\](?!(swiper|dom7|#jimp\/core|d3-array|d3-scale|file-type|react-wordcloud|striptags)[\/\\])/,
loader: 'babel-loader',
options: {
cacheDirectory: true,
babelrc: false,
presets: ['#babel/preset-env', '#babel/react'],
plugins: [
['#babel/plugin-proposal-decorators', { 'legacy': true }],
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-class-properties',
]
},
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
],
},
resolve: {
modules: [path.resolve(__dirname, './client/app'), 'node_modules'],
extensions: ['.jsx', '.js', '.json'],
// These extensions are tried when resolving a file
enforceExtension: false,
// If false it will also try to use no extension from above
moduleExtensions: ['-loader'],
// These extensions are tried when resolving a module
enforceModuleExtension: false,
},
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new CompressionPlugin({
test: /\.js?$/,
deleteOriginalAssets: true,
})
],
node: {
fs: 'empty'
}
};
Any help would be really thankfull

unable to import react component from library

After going through almost all the answers related to this topic I had no luck so have to create a new question.
Problem Statement :
I have a library of components (module) that I want to import inside my react application which has an export syntax like(working in another app) :
export * from 'button'; // this returns jsx component
Now, in my application I am using this as :
import {button} from ./library; // this is the bundled module where button component exists.
When I do this Webpack gives me an error :
(function (exports, require, module, __filename, __dirname) { export * from './button';
^^^^^^
SyntaxError: Unexpected token export
I am using Webpack 4 and babel 7 with these configurations :
webpack.config.js
//this is exports.
module.exports = {
entry: {
client: ['whatwg-fetch', './client/index.js', 'webpack-hot-middleware/client']
},
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})]
},
output: {
path: path.resolve(__dirname, `dist/client/${pkg.version}`),
filename: '[name].js',
publicPath: `/myApp/${pkg.version}`
},
devtool: ifProduction('nosources-source-map', 'source-map'),
resolve: {
modules: [path.resolve('./client'), path.resolve('./node_modules')]
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
},
{
test: /\.(ttf|eot|svg|woff|woff2?)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader?name=fonts/[name].[ext]'
},
{
test: /\.(png|jpg|ico|svg|eot|ttf)$/,
loader: 'url-loader'
}
]
},
mode,
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin(),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: '../report.html'
})
]
};
babel.config.js
// prettier-ignore
module.exports = {
presets: [
'#babel/preset-env',
'#babel/preset-react',
],
plugins: [
'#babel/plugin-transform-spread',
'react-hot-loader/babel',
'babel-plugin-syntax-export-extensions',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-syntax-export-namespace-from',
'#babel/plugin-syntax-export-default-from',
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-proposal-class-properties',
['#babel/plugin-transform-runtime',
{
regenerator: true,
},
],
],
env: {
development: {
presets: [
'#babel/preset-env', ['#babel/preset-react', { development: true } ],
],
},
test: {
presets: [['#babel/preset-env'], '#babel/preset-react'],
},
},
};
I am not sure what's going wrong, Any help would be much appreciated.
Thanks.

Routes chunks are bundling external scripts in every chunk

In my webpack I've used externals which has React, React Dom, Redux etc.
Now when I implement my Route Chunking, every chunk which is generated re-bundles the external scripts again, so eventually my bundle size is very huge.
How can I avoid my individual chunks not to re-bundle the external scripts and use them from externals.
EDIT
Using https://chrisbateman.github.io/webpack-visualizer/ I can see that all my chunks are bundling common libs - which are are actually supposed to come from externals in webpack.
EDIT 2
webpack file
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: ['./src/containers/AppContainer', './src/index'],
devtool: 'cheap-module-source-map',
output: {
path: __dirname + '/dist',
publicPath: 'public/',
filename: 'bundle.js',
chunkFilename: '[name].[id].chunk.[chunkhash].js',
libraryTarget: 'umd'
},
target: 'web',
externals: {
antd: 'antd',
react: 'react',
'react-dom': 'react-dom',
'react-router': 'react-router',
redux: 'redux',
'react-redux': 'react-redux',
immutable: 'immutable',
},
resolve: {
modules: [
path.join(__dirname, '../node_modules')
],
extensions: ['.js', '.jsx', '.json'],
alias:{
constants: path.resolve(__dirname, './src/constants'),
actions: path.resolve(__dirname, './src/actions'),
styles: path.resolve(__dirname, './src/styles'),
utils: path.resolve(__dirname, './src/utils')
}
},
resolveLoader: {
modules: [
path.join(__dirname, '../node_modules')
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
comments: false
})
]
module: {
loaders: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// Ignore local .babelrc files
babelrc: false,
presets: [
['es2015', { modules: false }],
'react'
],
plugins: [
'react-html-attrs',
'transform-class-properties',
'transform-decorators-legacy',
'transform-object-rest-spread',
[
'import', {
libraryName: 'antd'
}
]
]
}
},
{ test: /\.png$/, loader: 'file-loader' },
{
test: /\.s?css$/i,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.s?less$/i,
exclude:'/node_modules/',
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader',
options: {
limit: 100000
}
},
{
test: /\.eot\?iefix$/,
loader: 'url-loader',
options: {
limit: 100000
}
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
configFile: './eslint/.eslintrc',
failOnWarning: false,
failOnError: false
}
}
]
}
};
Routes file
import React from 'react';
import { Route, IndexRoute } from 'react-router';
export default (
<Route path='/base/'
getComponent={ (location, callback) => {
require.ensure([], function (require) {
callback(null, require('./containers/AppContainer').default);
});
} }>
<Route path='/route1'
getComponent={ (location, callback) => {
require.ensure([], function (require) {
callback(null,
require('./containter1')
.default);
});
} }
/>
<Route path='/route2'
getComponent={ (location, callback) => {
require.ensure([], function (require) {
callback(null,
require('./container2')
.default);
});
} }
/>
<Route path='/route3'
getComponent={ (location, callback) => {
require.ensure([], function (require) {
callback(null,
require('./container3')
.default);
});
} }
/>
</Route>
);
Try to change your externals section like this:
externals: {
React: require.resolve('react'),
'window.React': require.resolve('react'),
ReactDOM: require.resolve('react-dom'),
'window.ReactDOM': require.resolve('react-dom')
}
Also, remove import React from 'react' from your code. Just use React.
EDIT
Apologies, I edited my answer. Just realised my mistake. I changed the code. The key inside your externals will be the name of the global variable. Usually it's also safer to put it inside the window object

Split component wasn't rendered after getComponent()

I used Code Splitting for React Router to load component async, and I made it successfully. But when i opened my page in browser, i got nothing. Here're some key code snippets:
routeConfig
// When i removed the annotation below, it did render !
// import Home from './containers/Home/Home'
const routeConfig = [
{
path: '/',
component: App,
//indexRoute: {
// component: Home
//}
getIndexRoute(location, callback) {
require.ensure([], (require) => {
callback(null, require('./containers/Home/Home'))
}, 'Home');
}
}];
Home.jsx
console.log('HOME'); // It works!
class Home extends Component {
render() {
console.log('HOME COMPONENT'); // not working!
}
}
Any ideas? I'm stuck here :(
Here're my full webpack config codes:
/**
* webpack config
*/
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
vendor: [
'react',
'react-dom',
'redux',
'react-redux',
'react-router',
'redux-logger',
'redux-thunk'
],
main: [
'./html/index'
]
},
output: {
// path: path.join(__dirname, 'html/dist'),
path: './html/dist',
publicPath: '/html/dist/',
filename: '[name].js',
chunkFilename: '[name].js'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.js|jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel', // 'babel-loader' is also a legal name to reference
query: {
plugins: ['transform-object-rest-spread'],
presets: ['react', 'es2015']
}
},
{
test: /\.less$/,
exclude: /(node_modules|bower_components)/,
loader: "style!css!less"
}
]
},
externals: {
//don't bundle the 'react' npm package with our bundle.js
//but get it from a global 'React' variable
// 'react': 'React',
// 'react-dom': 'ReactDOM',
// 'redux': 'Redux',
// 'react-redux': 'ReactRedux',
// 'react-router': 'ReactRouter',
// 'redux-logger': 'reduxLogger',
// 'redux-thunk': 'ReduxThunk'
},
// add this handful of plugins that optimize the build
// when we're in production
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: 'vendor'
})
]
};
Hope this would help.
Home.js did being loaded, but the Home component seems to be uninitialized.
I just figured it out. Refer to links below:
invariant-violation-the-root-route-must-render-a-single-element-error-in-react
react-router/issues/2588
react-router/issues/2881

React, Webpack and Babel for Internet Explorer 9

Trying to support IE 9 for React. Upgraded to use babel 6.3.26 and babel-preset-es2015 and babel-preset-react for Webpack. However, when the file is loaded in IE 9, a syntax error occurs.
webpack.config.js
/* eslint-env node */
var path = require('path');
var packageJson = require('./package.json');
var _ = require('lodash');
var webpack = require('webpack');
var context = process.env.NODE_ENV || 'development';
var configFunctions = {
development: getDevConfig,
production: getProdConfig,
test: getTestConfig
};
var config = configFunctions[context]();
console.log('Building version %s in %s mode', packageJson.version, context);
module.exports = config;
function getLoaders() {
if (context.indexOf('test') === -1) {
return [
{
test: /\.js?$/,
exclude: /(test|node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['transform-runtime']
}
}
]
} else {
return [
{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015'],
plugins: ['transform-runtime']
}
}
]
}
}
function getBaseConfig() {
return {
context: __dirname + "/src",
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
stats: {
colors: true,
reasons: true
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: _.union(
getLoaders(),
[
{
test: /\.scss$/,
loader: 'style!css!sass'
},
{
test: /\.eot$|\.svg$|\.woff$|\.ttf$/,
loader: 'url-loader?limit=30000&name=fonts/[name]-[hash:6].[ext]'
},
{
test: /\.(png|.jpe?g|gif)$/,
loader: 'url-loader?limit=5000&name=img/[name]-[hash:6].[ext]'
},
{
test: /\.mp4$/,
loader: 'url-loader?limit=5000&name=videos/[name]-[hash:6].[ext]'
}
]
)
}
};
}
function getDevConfig() {
return _.merge({}, getBaseConfig(), {
devtool: 'cheap-module-eval-source-map',
entry: [
'babel-polyfill',
'webpack-hot-middleware/client',
'./App'
],
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
eslint: {
emitError: false,
failOnError: false,
failOnWarning: false,
quiet: true
}
});
}
function getProdConfig() {
return _.merge({}, getBaseConfig(), {
devtool: 'source-map',
entry: [
'babel-polyfill',
'./App'
],
plugins: [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
compress: {
warnings: false
}
})
],
eslint: {
emitError: true,
failOnError: true
}
})
}
function getTestConfig() {
return _.merge({}, getBaseConfig(), {})
}
Checking bundle.js for the offending lines reveals the usage of const which is not ES5. Am I missing something here? Do I need to transpile ES6 code into ES5 for production usage?
IE9 is not compatible with ES6, so, yes, you must transform your ES6 code to ES5. I believe the problem is you aren't telling babel to use the react and es2015 presets. I'm sure you installed them on your machine, but the babel loader only does what you tell it.
Inside your getLoaders() function, add the presets to your babel loader configuration query:
query: {
plugins: ['transform-runtime'],
presets: ['react', 'es2015']
}
Hopefully, that works for you.
babel/babel-loader reference
I am using create-react-app (v16.4.2). I tried using the followings to get the default hello world working in IE9:
1:
import 'core-js/es6/map';
import 'core-js/es6/set';
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
2:
import "babel-polyfill";
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
But neither of them worked for me. I ended up adding the following line into my index.html file in the public folder and it fixed my issue:
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
More information is available at:https://polyfill.io/v2/docs/

Resources