Move Mastodon theme handling to custom vite plugin (#34808)
Co-authored-by: Echo <ChaosExAnima@users.noreply.github.com>
This commit is contained in:
parent
37c82a3003
commit
0372344d33
2 changed files with 60 additions and 29 deletions
58
config/vite/plugin-mastodon-themes.ts
Normal file
58
config/vite/plugin-mastodon-themes.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/* This plugins handles Mastodon's theme system
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
import type { Plugin } from 'vite';
|
||||||
|
|
||||||
|
export function MastodonThemes(): Plugin {
|
||||||
|
return {
|
||||||
|
name: 'mastodon-themes',
|
||||||
|
async config(userConfig) {
|
||||||
|
if (!userConfig.root || !userConfig.envDir) {
|
||||||
|
throw new Error('Unknown project directory');
|
||||||
|
}
|
||||||
|
|
||||||
|
const themesFile = path.resolve(userConfig.envDir, 'config/themes.yml');
|
||||||
|
const entrypoints: Record<string, string> = {};
|
||||||
|
|
||||||
|
// Get all files mentioned in the themes.yml file.
|
||||||
|
const themesString = await fs.readFile(themesFile, 'utf8');
|
||||||
|
const themes = yaml.load(themesString, {
|
||||||
|
filename: 'themes.yml',
|
||||||
|
schema: yaml.FAILSAFE_SCHEMA,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!themes || typeof themes !== 'object') {
|
||||||
|
throw new Error('Invalid themes.yml file');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const themePath of Object.values(themes)) {
|
||||||
|
if (
|
||||||
|
typeof themePath !== 'string' ||
|
||||||
|
themePath.split('.').length !== 2 || // Ensure it has exactly one period
|
||||||
|
!themePath.endsWith('css')
|
||||||
|
) {
|
||||||
|
console.warn(
|
||||||
|
`Invalid theme path "${themePath}" in themes.yml, skipping`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entrypoints[path.basename(themePath)] = path.resolve(
|
||||||
|
userConfig.root,
|
||||||
|
themePath,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
build: {
|
||||||
|
rollupOptions: {
|
||||||
|
input: entrypoints,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
import fs from 'node:fs/promises';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
||||||
|
@ -9,7 +8,6 @@ import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import RailsPlugin from 'vite-plugin-rails';
|
import RailsPlugin from 'vite-plugin-rails';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
import yaml from 'js-yaml';
|
|
||||||
import legacy from '@vitejs/plugin-legacy';
|
import legacy from '@vitejs/plugin-legacy';
|
||||||
|
|
||||||
import { defineConfig, UserConfigFnPromise, UserConfig } from 'vite';
|
import { defineConfig, UserConfigFnPromise, UserConfig } from 'vite';
|
||||||
|
@ -17,36 +15,11 @@ import postcssPresetEnv from 'postcss-preset-env';
|
||||||
|
|
||||||
import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
|
import { MastodonServiceWorkerLocales } from './config/vite/plugin-sw-locales';
|
||||||
import { MastodonEmojiCompressed } from './config/vite/plugin-emoji-compressed';
|
import { MastodonEmojiCompressed } from './config/vite/plugin-emoji-compressed';
|
||||||
|
import { MastodonThemes } from './config/vite/plugin-mastodon-themes';
|
||||||
|
|
||||||
const jsRoot = path.resolve(__dirname, 'app/javascript');
|
const jsRoot = path.resolve(__dirname, 'app/javascript');
|
||||||
const themesFile = path.resolve(__dirname, 'config/themes.yml');
|
|
||||||
|
|
||||||
export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
const entrypoints: Record<string, string> = {}; // All JS entrypoints are taken care of by Vite Ruby
|
|
||||||
|
|
||||||
// Get all files mentioned in the themes.yml file.
|
|
||||||
const themesString = await fs.readFile(themesFile, 'utf8');
|
|
||||||
const themes = yaml.load(themesString, {
|
|
||||||
filename: 'themes.yml',
|
|
||||||
schema: yaml.FAILSAFE_SCHEMA,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!themes || typeof themes !== 'object') {
|
|
||||||
throw new Error('Invalid themes.yml file');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const themePath of Object.values(themes)) {
|
|
||||||
if (
|
|
||||||
typeof themePath !== 'string' ||
|
|
||||||
themePath.split('.').length !== 2 || // Ensure it has exactly one period
|
|
||||||
!themePath.endsWith('css')
|
|
||||||
) {
|
|
||||||
console.warn(`Invalid theme path "${themePath}" in themes.yml, skipping`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entrypoints[path.basename(themePath)] = path.resolve(jsRoot, themePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
root: jsRoot,
|
root: jsRoot,
|
||||||
css: {
|
css: {
|
||||||
|
@ -72,7 +45,6 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB
|
chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input: entrypoints,
|
|
||||||
output: {
|
output: {
|
||||||
chunkFileNames({ facadeModuleId, name }) {
|
chunkFileNames({ facadeModuleId, name }) {
|
||||||
if (!facadeModuleId) {
|
if (!facadeModuleId) {
|
||||||
|
@ -113,6 +85,7 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
||||||
manifestPaths: ['.vite/manifest.json', '.vite/manifest-assets.json'],
|
manifestPaths: ['.vite/manifest.json', '.vite/manifest-assets.json'],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
MastodonThemes(),
|
||||||
react({
|
react({
|
||||||
babel: {
|
babel: {
|
||||||
plugins: ['formatjs', 'transform-react-remove-prop-types'],
|
plugins: ['formatjs', 'transform-react-remove-prop-types'],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue