Created
September 21, 2018 15:01
-
-
Save gcangussu/75342089b201be0e8554616b58552bf9 to your computer and use it in GitHub Desktop.
Webpack 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
const path = require('path'); | |
const history = require('connect-history-api-fallback'); | |
const convert = require('koa-connect'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const CopyWebpackPlugin = require('copy-webpack-plugin'); | |
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |
const TerserPlugin = require('terser-webpack-plugin'); | |
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | |
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); | |
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); | |
const isProduction = process.env.NODE_ENV === 'production'; | |
const babelLoader = { | |
loader: 'babel-loader', | |
options: { | |
cacheDirectory: !isProduction, | |
}, | |
}; | |
// Use plugin to extract .css on production | |
// Use style-loader for inline <style> and HMR on development | |
const styleLoaderOrExtract = isProduction | |
? MiniCssExtractPlugin.loader | |
: { | |
loader: 'style-loader', | |
options: { | |
sourceMap: true, | |
convertToAbsoluteUrls: true, | |
}, | |
}; | |
const cssLoader = { | |
loader: 'css-loader', | |
options: { | |
sourceMap: true, | |
}, | |
}; | |
const webpackConfig = { | |
entry: path.join(__dirname, 'app/app.js'), | |
output: { | |
// Use [chunkhash] on production filenames for chaching | |
filename: isProduction ? 'static/js/[name].[chunkhash:7].js' : undefined, | |
path: path.join(__dirname, 'build'), | |
publicPath: '/', | |
}, | |
mode: isProduction ? 'production' : 'development', | |
// cheap-module-eval-source-map for faster rebuilds | |
devtool: isProduction ? 'source-map' : 'cheap-module-eval-source-map', | |
resolve: { | |
extensions: ['.ts', '.tsx', '.js'], | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.js$/, | |
exclude: path.join(__dirname, 'node_modules'), | |
use: babelLoader, | |
}, | |
{ | |
test: /\.tsx?$/, | |
use: [ | |
babelLoader, | |
{ | |
loader: 'ts-loader', | |
options: { | |
// Disable type checker here on development (see fork plugin) | |
transpileOnly: !isProduction, | |
// Enable faster builds on development | |
experimentalWatchApi: !isProduction, | |
}, | |
}, | |
], | |
}, | |
{ | |
test: /\.scss$/, | |
use: [ | |
styleLoaderOrExtract, | |
cssLoader, | |
{ | |
loader: 'sass-loader', | |
options: { | |
sourceMap: true, | |
}, | |
}, | |
], | |
}, | |
{ | |
test: /\.css$/, | |
use: [styleLoaderOrExtract, cssLoader], | |
}, | |
{ | |
test: /\.(eot|otf|ttf|woff|woff2|xlsx)$/, | |
use: [ | |
{ | |
loader: 'file-loader', | |
options: { | |
// Use [hash] in production for caching | |
name: isProduction | |
? 'static/files/[name].[hash:7].[ext]' | |
: '[path][name].[ext]', | |
}, | |
}, | |
], | |
}, | |
{ | |
test: /\.(jpg|png|gif|svg)$/, | |
use: [ | |
{ | |
loader: 'file-loader', | |
options: { | |
// Use [hash] in production for caching | |
name: isProduction | |
? 'static/images/[name].[hash:7].[ext]' | |
: '[path][name].[ext]', | |
}, | |
}, | |
isProduction && { | |
// Optimize images on production builds | |
loader: 'image-webpack-loader', | |
options: { | |
mozjpeg: { progressive: true, quality: 65 }, | |
gifsicle: { interlaced: false }, | |
optipng: { enabled: false }, | |
pngquant: { quality: '65-90', speed: 4 }, | |
}, | |
}, | |
].filter(Boolean), // removes false elements | |
}, | |
], | |
}, | |
plugins: [ | |
new HtmlWebpackPlugin({ | |
// Generate index.html with assets | |
template: path.join(__dirname, 'app/index.html'), | |
minify: isProduction && { | |
collapseWhitespace: true, | |
removeAttributeQuotes: true, | |
removeComments: true, | |
removeEmptyAttributes: true, | |
removeRedundantAttributes: true, | |
removeScriptTypeAttributes: true, | |
removeStyleLinkTypeAttributes: true, | |
useShortDoctype: true, | |
minifyCSS: true, | |
minifyJS: true, | |
}, | |
}), | |
// Get fast builds and typechecking with typescript on development | |
!isProduction && new ForkTsCheckerWebpackPlugin(), | |
// Copy files on public/ to build/ on production | |
isProduction && | |
new CopyWebpackPlugin([ | |
{ | |
context: 'public/', | |
from: '**/*', | |
to: './', | |
}, | |
]), | |
// Inline webpack runtime in index.html on production | |
isProduction && | |
new ScriptExtHtmlWebpackPlugin({ | |
inline: ['runtime'], | |
}), | |
// Extract .css files on production | |
isProduction && | |
new MiniCssExtractPlugin({ | |
// Use [chunkhash] filenames for chaching | |
filename: 'static/css/[name].[contenthash:7].css', | |
}), | |
].filter(Boolean), // filter to remove false elements | |
// Optimizations for production builds | |
...(isProduction && { | |
optimization: { | |
// Split code config for caching | |
// See: https://webpack.js.org/guides/caching/ | |
moduleIds: 'hashed', | |
runtimeChunk: 'single', | |
splitChunks: { | |
cacheGroups: { | |
vendor: { | |
test: /[\\/]node_modules[\\/]/, | |
name: 'vendors', | |
chunks: 'all', | |
}, | |
}, | |
}, | |
// Minimizers for JS and CSS on production | |
minimizer: [ | |
new TerserPlugin({ | |
cache: false, | |
parallel: true, | |
sourceMap: true, | |
extractComments: true, | |
}), | |
new OptimizeCSSAssetsPlugin({ | |
cssProcessorOptions: { | |
map: { | |
inline: false, | |
annotation: true, | |
}, | |
}, | |
}), | |
], | |
}, | |
}), | |
// Development only configs | |
...(!isProduction && { | |
stats: { | |
// Suppress "export not found" warnings due to ForkTsCheckerWebpackPlugin | |
warningsFilter: /export .* was not found in/, | |
}, | |
}), | |
}; | |
// webpack-serve config | |
const serve = { | |
port: 4000, | |
content: path.join(__dirname, 'public'), | |
add: app => { | |
app.use(convert(history())); // History api fallback | |
}, | |
}; | |
module.exports = isProduction ? webpackConfig : { ...webpackConfig, serve }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment