Skip to content

Instantly share code, notes, and snippets.

@Milkywayrules
Last active September 17, 2021 08:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Milkywayrules/1886682f00906dcce24f79e9206fd711 to your computer and use it in GitHub Desktop.
Save Milkywayrules/1886682f00906dcce24f79e9206fd711 to your computer and use it in GitHub Desktop.
Webpack + Babel + minify js + minify css + fonts + generate favicons + optimized for cache + ready for common, dev, and prod.
// Split into 3 webpack files
// Install all dev dependencies:
// yarn add -D @babel/core @babel/preset-env babel-loader
// yarn add -D css-loader css-minimizer-webpack-plugin
// yarn add -D favicons favicons-webpack-plugin html-webpack-plugin
// yarn add -D mini-css-extract-plugin terser-webpack-plugin
// yarn add -D webpack webpack-cli webpack-dev-server webpack-merge
// If you're using async in your code and have trouble when running,
// probably you need to install this:
// yarn add regenerator-runtime
//
// webpack.dev.js
//
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './',
},
});
// ------------------------------------------------------------------
//
// webpack.prod.js
//
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map',
});
// ------------------------------------------------------------------
//
// webpack.common.js
//
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const path = require('path');
// use [contenthash] for better and specific hashing related to "the content"
module.exports = {
entry: {
app: './src/app.js',
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
module: {
rules: [
// handle css files
{
test: /.*\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
// handle modern js
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory: true,
},
},
},
// handle fonts
{
test: /.*\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'assets/fonts/[name].[contenthash][ext]',
},
},
],
},
plugins: [
// handle html
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'index.html'),
}),
// split(?) css
new MiniCssExtractPlugin({
filename: 'assets/css/[name].[contenthash].css',
chunkFilename: 'assets/css/[id].[contenthash].css',
}),
// handle & generate favicons
new FaviconsWebpackPlugin({
logo: './static/images/icon/favicon-310.png',
prefix: '',
publicPath: '/static/images/icon',
outputPath: './static/images/icon',
cache: true,
inject: true, // inject these icons to html tag
favicons: {
theme_color: '#EA580C', // match with inside of index.html (orange-600)
icons: {
// `boolean` or `{ offset, background, mask, overlayGlow, overlayShadow }` or an array of sources
favicons: true,
android: true,
appleIcon: true,
appleStartup: false,
coast: false,
firefox: false,
windows: false,
yandex: false,
},
},
}),
],
optimization: {
// split js for better cache and split runtime aka node_modules etc
moduleIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
// splitChunks: {
// chunks: 'all',
// },
minimizer: [
// js minified by default in webpack 5
// but we use multiple minimizer, so we init the terser again here
new TerserPlugin({
terserOptions: {
// keep_classnames: true,
// keep_fnames: true,
mangle: false, // minified var etc names
},
}),
// minify css
new CssMinimizerPlugin({
minimizerOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
},
}),
],
},
};
// This is the package.json deps structure at the time this Gist created.
{
"name": "my-very-amazing-and-cool-app",
"author": "Dio Ilham Djatiadi",
"scripts": {
"dev": "webpack --config webpack.dev.js",
"serve": "webpack serve --open --config webpack.dev.js --port 8000",
"build": "webpack --config webpack.prod.js",
"rm:dist": "rm -r ./dist"
},
"devDependencies": {
"@babel/core": "^7.14.6",
"@babel/preset-env": "^7.14.7",
"babel-loader": "^8.2.2",
"css-loader": "^5.2.6",
"css-minimizer-webpack-plugin": "^3.0.2",
"favicons": "^6.2.2",
"favicons-webpack-plugin": "^5.0.2",
"html-webpack-plugin": "^5.3.2",
"mini-css-extract-plugin": "^2.0.0",
"terser-webpack-plugin": "^5.1.4",
"webpack": "^5.41.1",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"regenerator-runtime": "^0.13.9",
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment