Vlad Ioffe
3 min readJun 24, 2017

--

React with Webpack and TypeScript:

I have tried to fined a starter for the above and couldn’t, so I created this snippet.

Here is package.json:

const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CheckerPlugin } = require('awesome-typescript-loader');

module.exports = () => {

return {
stats: {
assets: true,
cached: false,
cachedAssets: false,
children: false,
chunks: true,
chunkModules: false,
chunkOrigins: false,
colors: true,
depth: false,
entrypoints: false,
errors: true,
errorDetails: true,
maxModules: 0,
modules: true,
performance: false,
providedExports: false,
publicPath: true,
reasons: true,
source: false,
timings: true,
usedExports: false,
version: true,
warnings: false
},
performance: {
hints: false
},
entry: {
oogaday: require('path').resolve('./src/index.tsx'),
vendor: './src/vendor/vendor.ts',
},
output: {
path: require('path').resolve('./dist'),
filename: '[name].js',
publicPath: '/static/'
},
resolve: {
extensions: ['.js', '.ts', '.less', '.css', '.html', '.tsx'],
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts(x?)$/,
use: ['awesome-typescript-loader']
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
{
fallbackLoader: 'style-loader',
loader: 'css-loader'
})
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract(
{
fallbackLoader: 'style-loader',
loader: 'css-loader!less-loader'
})
},
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
use: [
'file-loader?name=fonts/[name].[ext]?[hash]'
]
},
{
test: /\.(gif|png(2)?)(\?[a-z0-9=&.]+)?$/,
use: [
'file-loader?name=images/[name].[ext]?[hash]'
]
},
{
test: /\.html$/,
use: [
'html-loader'
]
}
]
},
plugins: [
new CheckerPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new ExtractTextPlugin('[name].css'),
new HtmlWebpackPlugin({
filename: 'index.html',
hash: false,
template: './src/index.html',
chunks: ['manifest', 'vendor', 'oogaday'],
inject: 'body',
chunksSortMode: 'dependency',
env: 'dev'
})
],
devServer: {
port: 3333,
inline: true,
stats: 'errors-only',
open: true,
publicPath: '/site/',
historyApiFallback: {
index: '/site/index.html'
},
proxy: {
'/static': {
target: 'http://localhost:3333',
pathRewrite: {'static': 'site'}
}
}
}
}
};

And here is the webpack.config.dev.js:

const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CheckerPlugin } = require('awesome-typescript-loader');

module.exports = () => {

return {
stats: {
assets: true,
cached: false,
cachedAssets: false,
children: false,
chunks: true,
chunkModules: false,
chunkOrigins: false,
colors: true,
depth: false,
entrypoints: false,
errors: true,
errorDetails: true,
maxModules: 0,
modules: true,
performance: false,
providedExports: false,
publicPath: true,
reasons: true,
source: false,
timings: true,
usedExports: false,
version: true,
warnings: false
},
performance: {
hints: false
},
entry: {
oogaday: require('path').resolve('./src/index.tsx'),
vendor: './src/vendor/vendor.ts',
},
output: {
path: require('path').resolve('./dist'),
filename: '[name].js',
publicPath: '/static/'
},
resolve: {
extensions: ['.js', '.ts', '.less', '.css', '.html', '.tsx'],
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.ts(x?)$/,
use: ['awesome-typescript-loader']
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
{
fallbackLoader: 'style-loader',
loader: 'css-loader'
})
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract(
{
fallbackLoader: 'style-loader',
loader: 'css-loader!less-loader'
})
},
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
use: [
'file-loader?name=fonts/[name].[ext]?[hash]'
]
},
{
test: /\.(gif|png(2)?)(\?[a-z0-9=&.]+)?$/,
use: [
'file-loader?name=images/[name].[ext]?[hash]'
]
},
{
test: /\.html$/,
use: [
'html-loader'
]
}
]
},
plugins: [
new CheckerPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
}),
new ExtractTextPlugin('[name].css'),
new HtmlWebpackPlugin({
filename: 'index.html',
hash: false,
template: './src/index.html',
chunks: ['manifest', 'vendor', 'oogaday'],
inject: 'body',
chunksSortMode: 'dependency',
env: 'dev'
})
],
devServer: {
port: 3333,
inline: true,
stats: 'errors-only',
open: true,
publicPath: '/site/',
historyApiFallback: {
index: '/site/index.html'
},
proxy: {
'/static': {
target: 'http://localhost:3333',
pathRewrite: {'static': 'site'}
}
}
}
}
};

I know that it is not enough for newbies but if you will need more info please let me know in the comment.

--

--