File: /var/www/linde-ai/html/webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
// Setup path constants
const THEME_FOLDER_PATH = path.resolve(__dirname, "./../wp-content/themes/linde/");
const THEME_FOLDER_PATH_BUILD = path.resolve(THEME_FOLDER_PATH, "./frontend");
const WEBPACK_PUBLIC_PATH = "/wp-content/themes/linde/frontend/";
/**
* Creates configuration object for Webpack dev server. Configuration is only necessary in development. For production this object is empty.
* @param {Boolean} isProduction
*/
const getDevServerConfig = (isProduction) => {
if (isProduction) {
return {};
} else {
const borealisConfig = require("./borealis.config")();
return {
watchFiles: borealisConfig.development.devServer.reloadOnPhpFileChange
? [`${THEME_FOLDER_PATH}/**/*.php`, `${THEME_FOLDER_PATH}/**/*.twig`]
: [],
static: THEME_FOLDER_PATH_BUILD,
host: borealisConfig.development.devServer.host,
port: borealisConfig.development.devServer.port,
devMiddleware: {
publicPath: WEBPACK_PUBLIC_PATH,
// We want to write files to disk since we cannot serve SVG using "<use>" from a different domain (dev server is on different port when serving assets from memory) during development
writeToDisk: (filePath) => {
// Do not write hot reload update files to disk since there could be many many of those
return !filePath.includes("hot-update");
},
},
headers: {
// To fix CORS issue when loading certain assets such as fonts
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
},
compress: true,
};
}
};
/**
* Register additional plugins if needed depending on environment.
* @param {Boolean} isProduction
*/
const getAdditionalMinimizerPlugins = (isProduction) => {
if (!isProduction) {
return [];
} else {
return [
// Initialize image minimizer plugin that optimizes various image types
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
// Lossless optimization with custom options
plugins: [
["gifsicle", { interlaced: true }],
["mozjpeg", { quality: 85 }],
["optipng", { optimizationLevel: 4 }],
// Svgo configuration here https://github.com/svg/svgo#configuration
[
"svgo",
{
plugins: [
{
name: "preset-default",
params: {
overrides: {
removeDoctype: false,
removeViewBox: false,
addAttributesToSVGElement: {
params: {
attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
},
},
},
},
},
],
},
],
],
},
},
}),
];
}
};
module.exports = () => {
const IS_PRODUCTION = process.env.NODE_ENV === "production";
return {
entry: {
app: path.resolve(__dirname, "./scripts/index.js"),
},
output: {
// Use contenthashed file all the time to prevent caching in development mode
filename: "[name].[contenthash].js",
path: THEME_FOLDER_PATH_BUILD,
publicPath: WEBPACK_PUBLIC_PATH,
clean: true,
},
mode: IS_PRODUCTION ? "production" : "development",
devtool: !IS_PRODUCTION ? "source-map" : false,
target: ["web", "es5"],
resolve: {
extensions: [".js"],
alias: {
"@": path.resolve(__dirname),
},
},
optimization: {
minimizer: ["...", new CssMinimizerPlugin(), ...getAdditionalMinimizerPlugins(IS_PRODUCTION)],
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
test: /\.css$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// URLs resolved through CSS must have different public path
// Since app.css gets generated inside output folder, using "" here will make all imports from CSS relative to the root of that CSS file which is "/wp-content/themes/linde/frontend/"
publicPath: "",
},
},
{
loader: "css-loader",
options: {
// "url" must be true in order to parse and properly output url() required files to output folder
url: true,
modules: false,
sourceMap: !IS_PRODUCTION,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [["autoprefixer"]],
},
},
},
],
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// URLs resolved through CSS must have different public path
// Since app.css gets generated inside output folder, using "" here will make all imports from CSS relative to the root of that CSS file which is "/wp-content/themes/linde/frontend/"
publicPath: "",
},
},
{
loader: "css-loader",
options: {
// "url" must be true in order to parse and properly output url() required files to output folder
url: true,
modules: false,
sourceMap: !IS_PRODUCTION,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [["autoprefixer"]],
},
},
},
{
// This loader helps resolve url() paths from imported SCSS files inside different "main" SCSS files
// Helps you write relative path from SCSS files that get properly resolved as if required from "main" SCSS file that imports those modules
loader: "resolve-url-loader",
options: {
sourceMap: !IS_PRODUCTION,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
sassOptions: {
outputStyle: IS_PRODUCTION ? "compressed" : "expanded",
},
},
},
],
},
{
test: /\.(png|svg|jpg|jpeg|gif|ico)$/i,
type: "asset/resource",
include: [path.resolve(__dirname, "./assets/images"), path.resolve(__dirname, "./assets/favicon")],
exclude: [path.resolve(__dirname, "./assets/icons")],
generator: {
filename: "[path][hash][ext][query]",
},
},
{
test: /\.(svg)$/i,
type: "asset/resource",
include: [path.resolve(__dirname, "./assets/icons")],
generator: {
filename: "[path][hash][ext][query]",
},
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: "asset/resource",
include: [path.resolve(__dirname, "./assets/fonts")],
generator: {
filename: "[path][hash][ext][query]",
},
},
],
},
plugins: [
new MiniCssExtractPlugin({
// Use contenthashed file all the time to prevent caching in development mode
filename: "[name].[contenthash].css",
}),
new WebpackManifestPlugin({
writeToFileEmit: true,
}),
],
devServer: getDevServerConfig(IS_PRODUCTION),
};
};