From a768ca3037f0fcd17d96977aafdd8035789f1f69 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Tue, 25 Mar 2025 12:21:57 -0400 Subject: [PATCH] Update webpack config to build sass themes --- webpack.common.js | 80 +++++++++++++++++++++++++++-------------------- webpack.dev.js | 17 +++++++++- webpack.prod.js | 15 ++++++++- 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/webpack.common.js b/webpack.common.js index 3534e683e1..39af742598 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -60,13 +60,14 @@ const config = { filename: 'index.html', template: 'index.html', // Append file hashes to bundle urls for cache busting - hash: true + hash: true, + chunks: [ + 'main.jellyfin', + 'serviceworker' + ] }), new CopyPlugin({ patterns: [ - { - from: 'themes/**/*.{css,jpg}' - }, { from: 'assets/**', globOptions: { @@ -107,6 +108,15 @@ const config = { typescript: { configFile: path.resolve(__dirname, 'tsconfig.json') } + }), + new MiniCssExtractPlugin({ + filename: pathData => { + if (pathData.chunk?.name?.startsWith('themes/')) { + return '[name]/theme.css'; + } + return '[name].[contenthash].css'; + }, + chunkFilename: '[name].[contenthash].css' }) ], output: { @@ -288,33 +298,41 @@ const config = { }] }, { - test: /\.s[ac]ss$/i, - use: [ - DEV_MODE ? 'style-loader' : MiniCssExtractPlugin.loader, - 'css-loader', + test: /\.(sa|sc|c)ss$/i, + oneOf: [ { - loader: 'postcss-loader', - options: { - postcssOptions: { - config: path.resolve(__dirname, 'postcss.config.js') - } - } + // Themes always need to use the MiniCssExtractPlugin since they are loaded directly + include: [ + path.resolve(__dirname, 'src/themes/') + ], + use: [ + MiniCssExtractPlugin.loader, + 'css-loader', + { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: path.resolve(__dirname, 'postcss.config.js') + } + } + }, + 'sass-loader' + ] }, - 'sass-loader' - ] - }, - { - test: /\.css$/i, - use: [ - DEV_MODE ? 'style-loader' : MiniCssExtractPlugin.loader, - 'css-loader', { - loader: 'postcss-loader', - options: { - postcssOptions: { - config: path.resolve(__dirname, 'postcss.config.js') - } - } + use: [ + DEV_MODE ? 'style-loader' : MiniCssExtractPlugin.loader, + 'css-loader', + { + loader: 'postcss-loader', + options: { + postcssOptions: { + config: path.resolve(__dirname, 'postcss.config.js') + } + } + }, + 'sass-loader' + ] } ] }, @@ -341,10 +359,4 @@ const config = { } }; -if (!DEV_MODE) { - config.plugins.push(new MiniCssExtractPlugin({ - filename: '[name].[contenthash].css' - })); -} - module.exports = config; diff --git a/webpack.dev.js b/webpack.dev.js index a6288a80ce..5721f54f76 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -1,11 +1,26 @@ const common = require('./webpack.common'); const { merge } = require('webpack-merge'); +const THEMES = [ + 'appletv', + 'blueradiance', + 'dark', + 'light', + 'purplehaze', + 'wmc' +]; + module.exports = merge(common, { // In order for live reload to work we must use "web" as the target not "browserslist" target: process.env.WEBPACK_SERVE ? 'web' : 'browserslist', mode: 'development', - entry: { 'main.jellyfin': './index.jsx' }, + entry: { + 'main.jellyfin': './index.jsx', + ...THEMES.reduce((acc, theme) => { + acc[`themes/${theme}`] = `./themes/${theme}/theme.scss`; + return acc; + }, {}) + }, devtool: 'eval-cheap-module-source-map', module: { rules: [ diff --git a/webpack.prod.js b/webpack.prod.js index 8b2c9aad5e..4912329b3b 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -1,10 +1,23 @@ const common = require('./webpack.common'); const { merge } = require('webpack-merge'); +const THEMES = [ + 'appletv', + 'blueradiance', + 'dark', + 'light', + 'purplehaze', + 'wmc' +]; + module.exports = merge(common, { mode: 'production', entry: { 'main.jellyfin': './index.jsx', - 'serviceworker': './serviceworker.js' + 'serviceworker': './serviceworker.js', + ...THEMES.reduce((acc, theme) => { + acc[`themes/${theme}`] = `./themes/${theme}/theme.scss`; + return acc; + }, {}) } });