Last active
March 8, 2021 03:02
-
-
Save chemitaxis/000728e2cb8cdcb7f8e4cc79c32631c1 to your computer and use it in GitHub Desktop.
Webpack config example with react router 4 and bundle loader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
import { | |
BrowserRouter as Router, | |
Route, | |
Link, | |
Switch | |
} from 'react-router-dom' | |
import { Provider, observer } from 'mobx-react' | |
import DevTools from 'mobx-react-devtools' | |
import NotMatch from '../../Containers/NotMatch' | |
import About from '../../Containers/About' | |
import Login from '../../Containers/Login' | |
import Home from '../../Containers/Home' | |
import Find from '../../Containers/Find' | |
@observer | |
export default class App extends Component { | |
constructor (props) { | |
super(props) | |
this.store = this.props.store | |
} | |
render () { | |
return ( | |
<Provider store={this.store}> | |
<Router> | |
<div> | |
<Route path='/' component={Header} /> | |
<Switch> | |
<Route exact path='/home' component={Home} /> | |
<Route exact path='/about' component={About} /> | |
<Route exact path='/find' component={Find} /> | |
<Route component={NotMatch} /> | |
</Switch> | |
</div> | |
</Router> | |
</Provider> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react' | |
class Bundle extends Component { | |
constructor (props) { | |
super(props) | |
this.state = { | |
// short for "module" but that's a keyword in js, so "mod" | |
mod: null | |
} | |
} | |
componentWillMount () { | |
this.load(this.props) | |
} | |
componentWillReceiveProps (nextProps) { | |
if (nextProps.load !== this.props.load) { | |
this.load(nextProps) | |
} | |
} | |
load (props) { | |
this.setState({ | |
mod: null | |
}) | |
props.load((mod) => { | |
this.setState({ | |
// handle both es imports and cjs | |
mod: mod.default ? mod.default : mod | |
}) | |
}) | |
} | |
render () { | |
return this.props.children(this.state.mod) | |
} | |
} | |
export default Bundle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import Bundle from '../../Utils/Bundle' | |
import loadHome from 'bundle-loader?lazy&name=home!../../Components/Home/home' | |
// components load their module for initial visit | |
const HomeContainer = ({...props}) => ( | |
<Bundle load={loadHome}> | |
{(Home) => Home | |
? <Home {...props}/> | |
: <div>Loading...</div> | |
} | |
</Bundle> | |
) | |
export default HomeContainer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react' | |
import { Link } from 'react-router-dom' | |
import { inject, observer } from 'mobx-react' | |
import jquery from 'jquery' | |
@inject('store') | |
@observer | |
class Home extends Component { | |
constructor(props) | |
{ | |
super(props) | |
alert(jquery) | |
} | |
render () { | |
return ( | |
<div> | |
<h2>Home</h2> | |
<Link to='/about'>Home</Link> | |
</div> | |
) | |
} | |
} | |
export default Home |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ReactDOM from 'react-dom' | |
import React from 'react' | |
import { useStrict } from 'mobx' | |
import App from './Containers/App' | |
import appState from './AppState' | |
import './index.scss' | |
const el = document.getElementById('app') | |
useStrict(true) | |
// import jquery from 'jquery' <- If I uncomment this line code is spliting is working fine | |
ReactDOM.render( | |
<App store={appState} /> | |
, | |
el | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin') | |
const PurifyCSSWebpackPlugin = require('purifycss-webpack-plugin') | |
const ExtractTextPlugin = require('extract-text-webpack-plugin') | |
const HtmlWebpackPlugin = require('html-webpack-plugin') | |
const webpack = require('webpack') | |
const path = require('path') | |
const WebpackMd5Hash = require('webpack-md5-hash') | |
const config = require('./config.json') | |
const pkg = require('./package.json') | |
// const { HashedModuleIdsPlugin } = webpack | |
const { | |
OccurrenceOrderPlugin, | |
AggressiveMergingPlugin, | |
CommonsChunkPlugin, | |
UglifyJsPlugin } = webpack.optimize | |
function _isVendor (module) { | |
return module.context && module.context.indexOf('node_modules') !== -1 | |
} | |
module.exports = { | |
devtool: 'source-map', | |
entry: { | |
app: | |
[ | |
'babel-polyfill', | |
'./src/app/index.prod.js' | |
] | |
}, | |
output: { | |
path: path.resolve('src/www'), | |
filename: 'assets/js/[name]-[chunkhash].js', | |
chunkFilename: 'assets/js/[name]-[chunkhash].js' | |
}, | |
resolve: { | |
extensions: ['.scss', '.css', '.js'], | |
modules: ['node_modules'] | |
}, | |
plugins: [ | |
new webpack.DefinePlugin({ | |
'process.env.NODE_ENV': JSON.stringify('production'), | |
'APP_VERSION': JSON.stringify(pkg.version) | |
}), | |
new HtmlWebpackPlugin(Object.assign({}, config, { | |
template: path.resolve('index.ejs'), | |
alwaysWriteToDisk: true, | |
inject: false, | |
hash: false, | |
minify: { | |
collapseWhitespace: true, | |
decodeEntities: true, | |
html5: true, | |
processConditionalComments: true, | |
removeAttributeQuotes: true, | |
removeComments: true, | |
removeEmptyAttributes: true, | |
removeOptionalTags: true, | |
removeRedundantAttributes: true, | |
removeScriptTypeAttributes: true, | |
removeStyleLinkTypeAttributes: true, | |
removeTagWhitespace: true, | |
sortAttributes: true, | |
sortClassName: true, | |
useShortDoctype: true, | |
keepClosingSlash: true, | |
minifyJS: true, | |
minifyCSS: true, | |
minifyURLs: true | |
} | |
})), | |
new HtmlWebpackHarddiskPlugin(), | |
new AggressiveMergingPlugin(), | |
new ExtractTextPlugin({ | |
allChunks: true, | |
filename: 'assets/css/[name]-[chunkhash].css' | |
}), | |
new PurifyCSSWebpackPlugin({ | |
basePath: path.resolve('src/www'), | |
resolveExtensions: ['.js'], | |
purifyOptions: { | |
minify: true, | |
rejected: true | |
} | |
}), | |
// optimizations | |
new CommonsChunkPlugin({ | |
name: 'vendor', | |
chunks: ['app'], | |
filename: 'assets/js/vendor-[chunkhash].bundle.js', | |
minChunks: function (module) { | |
// this assumes your vendor imports exist in the node_modules directory | |
return _isVendor(module) | |
} | |
}), | |
new WebpackMd5Hash(), | |
new OccurrenceOrderPlugin(), | |
new UglifyJsPlugin({ | |
sourceMap: true, | |
minimize: true, | |
compress: { warnings: false, drop_console: true }, | |
comments: false | |
}) | |
], | |
module: { | |
rules: [{ | |
test: /\.(js|jsx)$/, | |
exclude: /node_modules/, | |
use: ['babel-loader'] | |
}, { | |
test: /\.(css|scss)$/, | |
use: ExtractTextPlugin.extract({ | |
fallback: 'style-loader', | |
use: [ | |
'css-loader?minimize&sourceMap', | |
'sass-loader', | |
'postcss-loader' | |
] | |
}) | |
}] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment