Skip to content

Instantly share code, notes, and snippets.

@olpeh
Created November 5, 2018 12:12
Show Gist options
  • Save olpeh/e07939c427fbdbbec447a0630196e208 to your computer and use it in GitHub Desktop.
Save olpeh/e07939c427fbdbbec447a0630196e208 to your computer and use it in GitHub Desktop.
React lazy + Suspense
{
"name": "<NAME>",
"version": "1.0.0",
"private": true,
"description": "<DESCRIPTION>",
"main": "index.tsx",
"scripts": {
"start": "webpack-dev-server --mode development --hot --progress --colors --port 3000",
"build": "webpack -p --progress --colors",
"lint": "tslint -c tslint.json 'src/**/*.{ts,tsx}'",
"pretest": "npm run lint",
"test": "node scripts/tests.js",
"no-watch-test": "node scripts/tests.js --no-watch",
"prebuild": "npm run no-watch-test",
"install-build": "npm-run-all install build",
"format": "prettier --write 'src/**/*.{ts,tsx}' 'src/**/*.{css,scss}' 'test/**/*.{ts,tsx}'",
"precommit": "lint-staged"
},
"lint-staged": {
"linters": {
"*.{ts,tsx,scss,css}": [
"prettier --write",
"git add"
]
}
},
"devDependencies": {
"@types/classnames": "^2.2.3",
"@types/highcharts": "^5.0.20",
"@types/jest": "^23.0.0",
"@types/node": "^10.12.0",
"@types/react": "16.4.18",
"@types/react-dom": "16.0.9",
"@types/react-router": "^4.0.22",
"@types/webpack": "^4.4.17",
"css-loader": "^1.0.0",
"file-loader": "^2.0.0",
"html-loader": "^1.0.0-alpha.0",
"html-webpack-plugin": "^3.0.4",
"husky": "^1.1.2",
"identity-obj-proxy": "^3.0.0",
"jest": "^23.1.0",
"jest-cli": "^23.1.0",
"jest-dom": "^2.1.0",
"jest-fetch-mock": "^1.6.2",
"lint-staged": "^7.1.3",
"npm-run-all": "^4.1.3",
"postcss": "^7.0.5",
"postcss-browser-reporter": "^0.5.0",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^12.0.1",
"postcss-loader": "^3.0.0",
"postcss-reporter": "^6.0.0",
"postcss-url": "^8.0.0",
"prettier": "^1.11.1",
"react-hot-loader": "^4.3.11",
"react-test-renderer": "^16.4.0",
"react-testing-library": "^5.2.1",
"style-loader": "^0.23.1",
"ts-jest": "^23.10.4",
"ts-loader": "^5.2.2",
"tslint": "^5.10.0",
"typescript": "^3.1.3",
"url-loader": "^1.0.0-beta.0",
"wait-for-expect": "^1.0.1",
"webpack": "^4.23.1",
"webpack-cleanup-plugin": "^0.5.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.4",
"webpack-hot-middleware": "^2.22.2"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.0-14",
"@fortawesome/free-solid-svg-icons": "^5.1.0-11",
"@fortawesome/react-fontawesome": "^0.1.0-11",
"classnames": "^2.2.5",
"date-fns": "^1.29.0",
"highcharts": "^6.0.7",
"highcharts-more": "^0.1.7",
"mini-css-extract-plugin": "^0.4.4",
"mobx": "^5.5.2",
"mobx-react": "^5.0.0",
"mobx-react-devtools": "^6.0.3",
"mobx-react-router": "^4.0.1",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"react": "16.6.0",
"react-dom": "16.6.0",
"react-highcharts": "^16.0.2",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-select": "2.1.1"
},
"jest": {
"globals": {
"ts-jest": {
"tsConfig": "tsconfig.jest.json"
}
},
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": "(/test/(\\w*\\/)?\\w*(\\.(test|spec))\\.(jsx?|tsx?))$",
"moduleNameMapper": {
"^.+\\.css$": "identity-obj-proxy",
"^(app/.+)$": "<rootDir>/src/$1/"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx"
],
"automock": false,
"setupFiles": [
"./scripts/setupJest.js"
]
}
}
const webpack = require('webpack');
const path = require('path');
// vartiables
const isProduction = process.argv.indexOf('-p') >= 0;
const sourcePath = path.join(__dirname, './src');
const outPath = path.join(__dirname, '../public');
// plugins
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
context: sourcePath,
entry: {
main: './main.tsx'
},
output: {
path: outPath,
filename: 'bundle.js',
chunkFilename: '[chunkhash].js',
publicPath: '/'
},
target: 'web',
resolve: {
extensions: ['.js', '.ts', '.tsx'],
// Fix webpack's default behavior to not load packages with jsnext:main module
// (jsnext:main directs not usually distributable es6 format, but es6 sources)
mainFields: ['module', 'browser', 'main'],
alias: {
app: path.resolve(__dirname, 'src/app/'),
assets: path.resolve(__dirname, 'src/assets/')
}
},
module: {
rules: [
// .ts, .tsx
{
test: /\.tsx?$/,
use: 'ts-loader'
},
// css
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: !isProduction,
modules: true,
localIdentName: '[local]__[hash:base64:5]'
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [
require('postcss-import')({ addDependencyTo: webpack }),
require('postcss-url')(),
require('postcss-cssnext')(),
require('postcss-reporter')(),
require('postcss-browser-reporter')({
disabled: isProduction
})
]
}
}
]
},
// static assets
{ test: /\.html$/, use: 'html-loader' },
{
test: /\.(png|jp(e*)g|svg|ico|gif)$/,
use: [
{
loader: 'url-loader',
options: { limit: 10000, name: 'images/[hash]-[name].[ext]' }
}
]
}
]
},
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})],
splitChunks: {
name: true,
cacheGroups: {
commons: {
chunks: 'initial',
minChunks: 2
},
vendors: {
test: /[\\/]node_modules[\\/]/,
chunks: 'all',
priority: -10
}
}
},
runtimeChunk: true,
namedModules: true,
namedChunks: true
},
plugins: [
new WebpackCleanupPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
path: outPath,
filename: isProduction ? '[name].[hash].css' : '[name].css',
chunkFilename: isProduction ? '[id].[hash].css' : '[id].css',
publicPath: '/'
}),
new HtmlWebpackPlugin({
template: 'assets/index.html',
favicon: 'assets/favicon.ico'
})
],
devServer: {
contentBase: sourcePath,
hot: true,
inline: true,
historyApiFallback: {
disableDotRule: true
},
stats: 'minimal'
},
devtool: isProduction ? 'source-map' : 'cheap-module-eval-source-map',
node: {
// workaround for webpack-dev-server issue
// https://github.com/webpack/webpack-dev-server/issues/60#issuecomment-103411179
fs: 'empty',
net: 'empty'
}
};
@olpeh
Copy link
Author

olpeh commented Nov 5, 2018

- minimizer: [new OptimizeCSSAssetsPlugin({})]
+ minimizer: [new UglifyJsPlugin({}), new OptimizeCSSAssetsPlugin({})],

This was needed in order to optimize the JS bundles, see https://twitter.com/0lpeh/status/1059479032146915328

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment