mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 16:28:28 -04:00
240 lines
7.0 KiB
JavaScript
240 lines
7.0 KiB
JavaScript
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
import webpack from "webpack";
|
|
import WebpackAssetsManifest from "webpack-assets-manifest";
|
|
import CopyPlugin from "copy-webpack-plugin";
|
|
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
|
|
import TerserPlugin from "terser-webpack-plugin";
|
|
|
|
// PostCSS stuff:
|
|
import autoprefixer from "autoprefixer";
|
|
import postcssSvgo from "postcss-svgo";
|
|
import postcssFocus from "postcss-focus";
|
|
import postcssColorRgbaFallback from "postcss-color-rgba-fallback";
|
|
import postcssMergeRules from "postcss-merge-rules";
|
|
import postcssDiscardDuplicates from "postcss-discard-duplicates";
|
|
import postcssCombineDuplicatedSelectors from "postcss-combine-duplicated-selectors";
|
|
import postcssNormalizeCharset from "postcss-normalize-charset";
|
|
|
|
// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#what-do-i-use-instead-of-__dirname-and-__filename
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
const isProd = process.env.NODE_ENV === "production";
|
|
|
|
export default {
|
|
entry: [
|
|
path.resolve(__dirname, "assets/js/index.js"),
|
|
path.resolve(__dirname, "assets/sass/main.scss"),
|
|
],
|
|
mode: isProd ? "production" : "development",
|
|
devtool: isProd ? "source-map" : "inline-source-map",
|
|
output: {
|
|
filename: isProd ? "js/[name]-[contenthash:6].js" : "js/[name].js",
|
|
path: path.resolve(__dirname, "static/assets/"),
|
|
publicPath: "/assets/",
|
|
clean: true,
|
|
crossOriginLoading: "anonymous",
|
|
environment: {
|
|
// https://github.com/babel/babel-loader#top-level-function-iife-is-still-arrow-on-webpack-5
|
|
arrowFunction: false,
|
|
},
|
|
},
|
|
plugins: [
|
|
new MiniCssExtractPlugin({
|
|
filename: isProd ? "css/[name]-[contenthash:6].css" : "css/[name].css",
|
|
}),
|
|
new webpack.BannerPlugin({
|
|
banner: `@license MIT <https://opensource.org/licenses/MIT>
|
|
@copyright (c) 2017-${new Date().getFullYear()} Jake Jarvis <https://jarv.is/>`,
|
|
}),
|
|
new CopyPlugin({
|
|
patterns: [
|
|
{
|
|
from: path.resolve(__dirname, "assets/images/"),
|
|
to: "images/",
|
|
globOptions: {
|
|
dot: false,
|
|
},
|
|
},
|
|
{
|
|
from: path.resolve(__dirname, "node_modules/twemoji-emojis/vendor/svg/"),
|
|
to: "emoji/",
|
|
globOptions: {
|
|
dot: false,
|
|
},
|
|
},
|
|
],
|
|
}),
|
|
new WebpackAssetsManifest({
|
|
writeToDisk: true, // allow Hugo to access file in dev mode
|
|
output: path.resolve(__dirname, "data/manifest.json"),
|
|
publicPath: true,
|
|
integrity: true,
|
|
integrityHashes: ["sha384"],
|
|
customize: (entry) => {
|
|
// don't add thousands of unneeded twemoji graphics to the manifest
|
|
if (entry.key.startsWith("emoji/")) return false;
|
|
},
|
|
}),
|
|
],
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.js$/,
|
|
exclude: /node_modules/,
|
|
use: [
|
|
{
|
|
loader: "babel-loader",
|
|
options: {
|
|
presets: [
|
|
[
|
|
"@babel/preset-env",
|
|
{
|
|
include: [
|
|
"transform-arrow-functions",
|
|
"transform-block-scoping",
|
|
"transform-template-literals",
|
|
],
|
|
bugfixes: true,
|
|
useBuiltIns: "entry",
|
|
corejs: 3,
|
|
},
|
|
],
|
|
],
|
|
plugins: [
|
|
[
|
|
"template-html-minifier",
|
|
{
|
|
modules: {
|
|
"lit-html": ["html"],
|
|
"lit-html/static.js": ["html"],
|
|
},
|
|
htmlMinifier: {
|
|
html5: true,
|
|
caseSensitive: true,
|
|
collapseWhitespace: true,
|
|
removeComments: false,
|
|
},
|
|
},
|
|
],
|
|
],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(sa|sc|c)ss$/,
|
|
use: [
|
|
MiniCssExtractPlugin.loader,
|
|
{
|
|
loader: "css-loader",
|
|
options: {
|
|
sourceMap: true,
|
|
},
|
|
},
|
|
{
|
|
loader: "postcss-loader",
|
|
options: {
|
|
sourceMap: true,
|
|
postcssOptions: {
|
|
config: false,
|
|
plugins: [
|
|
autoprefixer(),
|
|
postcssSvgo({
|
|
encode: true,
|
|
}),
|
|
postcssFocus(),
|
|
postcssColorRgbaFallback({
|
|
properties: ["background-image"],
|
|
}),
|
|
postcssCombineDuplicatedSelectors(),
|
|
postcssMergeRules(),
|
|
postcssDiscardDuplicates(),
|
|
postcssNormalizeCharset(),
|
|
],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
loader: "sass-loader",
|
|
options: {
|
|
sourceMap: true,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(woff(2)?|ttf|otf|eot)$/,
|
|
type: "asset/resource",
|
|
generator: {
|
|
filename: "fonts/[name][ext]",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
performance: {
|
|
// only evaluate JS and CSS file sizes (ignore source maps, images, etc.)
|
|
assetFilter: (assetFilename) => /\.js$|\.css$/.test(assetFilename),
|
|
},
|
|
optimization: {
|
|
sideEffects: true,
|
|
minimize: isProd,
|
|
minimizer: [
|
|
new TerserPlugin({
|
|
test: /\.js$/,
|
|
parallel: true,
|
|
terserOptions: {
|
|
compress: {
|
|
arrows: false,
|
|
drop_console: true,
|
|
negate_iife: false,
|
|
sequences: false,
|
|
passes: 3,
|
|
},
|
|
format: {
|
|
comments: /^\**!|@preserve|@license/i,
|
|
ascii_only: true, // some symbols get disfigured otherwise
|
|
},
|
|
mangle: true,
|
|
},
|
|
extractComments: false,
|
|
}),
|
|
new CssMinimizerPlugin({
|
|
test: /\.css$/,
|
|
minify: CssMinimizerPlugin.cleanCssMinify,
|
|
minimizerOptions: {
|
|
compatibility: "*",
|
|
level: 1,
|
|
processImport: false,
|
|
format: {
|
|
breaks: {
|
|
afterAtRule: true,
|
|
afterBlockBegins: true,
|
|
afterBlockEnds: true,
|
|
afterComment: true,
|
|
afterRuleEnds: true,
|
|
beforeBlockEnds: true,
|
|
},
|
|
spaces: {
|
|
beforeBlockBegins: true,
|
|
},
|
|
semicolonAfterLastProperty: true,
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
},
|
|
devServer: {
|
|
static: {
|
|
directory: path.resolve(__dirname, "public"),
|
|
watch: true,
|
|
},
|
|
host: "0.0.0.0", // weird docker bind behavior
|
|
port: process.env.PORT || 1337,
|
|
compress: true,
|
|
liveReload: true,
|
|
setupExitSignals: false, // prevent dangling server when started via gulp
|
|
},
|
|
};
|