Skip to content

Instantly share code, notes, and snippets.

@jaredpalmer
Created January 25, 2018 21:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaredpalmer/41634e816a65a9d1abdc8c129f578692 to your computer and use it in GitHub Desktop.
Save jaredpalmer/41634e816a65a9d1abdc8c129f578692 to your computer and use it in GitHub Desktop.
Razzle TS real-world setup
'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;
},
};
@erikcohenGL
Copy link

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.

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