Created
January 25, 2018 21:04
-
-
Save jaredpalmer/41634e816a65a9d1abdc8c129f578692 to your computer and use it in GitHub Desktop.
Razzle TS real-world setup
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 autoprefixer = require('autoprefixer'); | |
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | |
const path = require('path'); | |
const scssPlugin = new ExtractTextPlugin( | |
'static/css/[name].[contenthash:8].css' | |
); | |
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); | |
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') | |
.BundleAnalyzerPlugin; | |
module.exports = { | |
modify: (baseConfig, { target, dev }, webpack) => { | |
const config = Object.assign({}, baseConfig); | |
config.resolve.alias.common = path.resolve('./src/common'); | |
config.resolve.extensions = config.resolve.extensions.concat([ | |
'.ts', | |
'.tsx', | |
]); | |
config.devtool = 'cheap-module-source-map'; | |
const babelLoader = config.module.rules.findIndex( | |
rule => rule.options && rule.options.babelrc | |
); | |
// Get the correct `include` option, since that hasn't changed. | |
// This tells Razzle which directories to transform. | |
const { include } = config.module.rules[babelLoader]; | |
// Declare our TypeScript loader configuration | |
const tsLoader = { | |
include, | |
test: /\.tsx?$/, | |
use: [ | |
dev && { loader: 'cache-loader' }, | |
dev && { | |
loader: 'thread-loader', | |
options: { | |
// there should be 1 cpu for the fork-ts-checker-webpack-plugin | |
workers: 2, | |
}, | |
}, | |
{ | |
loader: 'ts-loader', | |
options: { | |
happyPackMode: true, // IMPORTANT! use happyPackMode mode to speed-up compilation and reduce errors reported to webpack | |
}, | |
}, | |
].filter(x => x), | |
}; | |
// Fully replace babel-loader with ts-loader | |
config.module.rules[babelLoader] = tsLoader; | |
if (target === 'web') { | |
config.plugins.push( | |
new ForkTsCheckerWebpackPlugin({ | |
checkSyntacticErrors: true, | |
formatter: 'codeframe', | |
tslint: './tslint.json', | |
watch: './src', | |
workers: 2, | |
}) | |
); | |
// config.plugins.push(new BundleAnalyzerPlugin()); | |
} | |
if (target === 'web') { | |
config.module.rules.push( | |
dev | |
? { | |
test: /.scss$/, | |
use: [ | |
'style-loader', | |
{ | |
loader: 'css-loader', | |
options: { | |
modules: false, | |
sourceMap: true, | |
}, | |
}, | |
{ | |
loader: 'postcss-loader', | |
options: { | |
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options | |
plugins: () => [ | |
autoprefixer({ | |
browsers: [ | |
'>1%', | |
'last 4 versions', | |
'Firefox ESR', | |
'not ie < 9', // React doesn't support IE8 anyway | |
], | |
}), | |
], | |
}, | |
}, | |
'sass-loader', | |
], | |
} | |
: { | |
test: /.scss$/, | |
use: scssPlugin.extract({ | |
fallback: 'style-loader', | |
use: [ | |
{ | |
loader: 'css-loader', | |
options: { | |
minimize: true, | |
importLoaders: 1, | |
}, | |
}, | |
{ | |
loader: 'postcss-loader', | |
options: { | |
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options | |
plugins: () => [ | |
autoprefixer({ | |
browsers: [ | |
'>1%', | |
'last 4 versions', | |
'Firefox ESR', | |
'not ie < 9', // React doesn't support IE8 anyway | |
], | |
}), | |
], | |
}, | |
}, | |
'sass-loader', | |
], | |
}), | |
} | |
); | |
config.output.filename = dev | |
? 'static/js/[name].js' | |
: 'static/js/[name].[hash:7].js'; | |
config.entry.vendor = [ | |
require.resolve('razzle/polyfills'), | |
require.resolve('./polyfill'), | |
require.resolve('react'), | |
require.resolve('react-dom'), | |
require.resolve('react-router-dom'), | |
require.resolve('redux'), | |
require.resolve('react-redux'), | |
require.resolve('redux-thunk'), | |
require.resolve('redux-pack'), | |
require.resolve('react-helmet'), | |
require.resolve('axios'), | |
require.resolve('formik'), | |
require.resolve('react-gateway'), | |
require.resolve('google-map-react'), | |
require.resolve('classnames'), | |
require.resolve('react-toggled'), | |
require.resolve('react-instantsearch'), | |
require.resolve('algoliasearch'), | |
require.resolve('he'), | |
require.resolve('react-select'), | |
require.resolve('yup'), | |
require.resolve('downshift'), | |
]; | |
config.plugins.push( | |
new webpack.optimize.CommonsChunkPlugin({ | |
names: ['vendor', 'manifest'], | |
minChunks: Infinity, | |
}) | |
); | |
// extract common modules from all the chunks (requires no 'name' property) | |
config.plugins.push( | |
new webpack.optimize.CommonsChunkPlugin({ | |
async: true, | |
children: true, | |
minChunks: 4, | |
}) | |
); | |
// config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin()); | |
if (!dev) { | |
config.plugins.push(scssPlugin); | |
} | |
} else { | |
config.module.rules.push({ | |
test: /.scss$/, | |
use: 'css-loader', | |
}); | |
} | |
return config; | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you still recommend to setup typescript this way?
Some guides specify that everything should be transpiled through typescript and I read in the docs that only babel should be used.