mirror of
https://github.com/mastodon/mastodon.git
synced 2025-09-05 17:31:12 +00:00
Replace Webpacker usage with Vite
This commit is contained in:
parent
86c353040a
commit
73e92ac250
|
@ -9,6 +9,9 @@ public/system
|
|||
public/assets
|
||||
public/packs
|
||||
public/packs-test
|
||||
public/vite
|
||||
public/vite-dev
|
||||
public/vite-test
|
||||
node_modules
|
||||
neo4j
|
||||
vendor/bundle
|
||||
|
|
2
.github/workflows/test-ruby.yml
vendored
2
.github/workflows/test-ruby.yml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
|||
|
||||
- name: Archive asset artifacts
|
||||
run: |
|
||||
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs*
|
||||
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: matrix.mode == 'test'
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -69,5 +69,8 @@ yarn-debug.log
|
|||
# Ignore Docker option files
|
||||
docker-compose.override.yml
|
||||
|
||||
# Vite Ruby
|
||||
/public/vite*
|
||||
|
||||
# Ignore dotenv .local files
|
||||
.env*.local
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
/public/assets
|
||||
/public/packs
|
||||
/public/packs-test
|
||||
/public/vite
|
||||
/public/vite-dev
|
||||
/public/vite-test
|
||||
.env
|
||||
.env.production
|
||||
.env.development
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -94,8 +94,8 @@ gem 'strong_migrations', '1.8.0'
|
|||
gem 'tty-prompt', '~> 0.23', require: false
|
||||
gem 'twitter-text', '~> 3.1.0'
|
||||
gem 'tzinfo-data', '~> 1.2023'
|
||||
gem 'vite_rails', '~> 3.0.17'
|
||||
gem 'webauthn', '~> 3.0'
|
||||
gem 'webpacker', '~> 5.4'
|
||||
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
|
||||
|
||||
gem 'json-ld'
|
||||
|
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -212,6 +212,7 @@ GEM
|
|||
railties (>= 5)
|
||||
dotenv (3.1.2)
|
||||
drb (2.2.1)
|
||||
dry-cli (1.0.0)
|
||||
ed25519 (1.3.0)
|
||||
elasticsearch (7.17.10)
|
||||
elasticsearch-api (= 7.17.10)
|
||||
|
@ -782,7 +783,6 @@ GEM
|
|||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2, < 3.0)
|
||||
websocket (~> 1.0)
|
||||
semantic_range (3.0.0)
|
||||
sidekiq (6.5.12)
|
||||
connection_pool (>= 2.2.5, < 3)
|
||||
rack (~> 2.0)
|
||||
|
@ -865,6 +865,13 @@ GEM
|
|||
validate_url (1.0.15)
|
||||
activemodel (>= 3.0.0)
|
||||
public_suffix
|
||||
vite_rails (3.0.17)
|
||||
railties (>= 5.1, < 8)
|
||||
vite_ruby (~> 3.0, >= 3.2.2)
|
||||
vite_ruby (3.5.0)
|
||||
dry-cli (>= 0.7, < 2)
|
||||
rack-proxy (~> 0.6, >= 0.6.1)
|
||||
zeitwerk (~> 2.2)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
webauthn (3.1.0)
|
||||
|
@ -883,11 +890,6 @@ GEM
|
|||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
webpacker (5.4.4)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.1)
|
||||
websocket (1.2.10)
|
||||
websocket-driver (0.7.6)
|
||||
|
@ -1046,9 +1048,9 @@ DEPENDENCIES
|
|||
tty-prompt (~> 0.23)
|
||||
twitter-text (~> 3.1.0)
|
||||
tzinfo-data (~> 1.2023)
|
||||
vite_rails (~> 3.0.17)
|
||||
webauthn (~> 3.0)
|
||||
webmock (~> 3.18)
|
||||
webpacker (~> 5.4)
|
||||
webpush!
|
||||
xorcist (~> 1.1)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
|
||||
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
|
||||
stream: env PORT=4000 yarn workspace @mastodon/streaming start
|
||||
webpack: bin/webpack-dev-server
|
||||
vite: bin/vite dev
|
||||
|
|
|
@ -4,7 +4,7 @@ module RoutingHelper
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
include ActionView::Helpers::AssetTagHelper
|
||||
include Webpacker::Helper
|
||||
include ViteRails::TagHelpers
|
||||
|
||||
included do
|
||||
include Rails.application.routes.url_helpers
|
||||
|
@ -25,7 +25,7 @@ module RoutingHelper
|
|||
end
|
||||
|
||||
def frontend_asset_path(source, **options)
|
||||
asset_pack_path("media/#{source}", **options)
|
||||
vite_asset_path(source, **options)
|
||||
end
|
||||
|
||||
def frontend_asset_url(source, **options)
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
module ThemeHelper
|
||||
def theme_style_tags(theme)
|
||||
if theme == 'system'
|
||||
stylesheet_pack_tag('mastodon-light', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') +
|
||||
stylesheet_pack_tag('default', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
|
||||
vite_stylesheet_tag('styles/mastodon-light.scss', media: 'not all and (prefers-color-scheme: dark)', crossorigin: 'anonymous') +
|
||||
vite_stylesheet_tag('styles/application.scss', media: '(prefers-color-scheme: dark)', crossorigin: 'anonymous')
|
||||
else
|
||||
stylesheet_pack_tag theme, media: 'all', crossorigin: 'anonymous'
|
||||
vite_stylesheet_tag "styles/#{theme}.scss", media: 'all', crossorigin: 'anonymous'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import './public-path';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import Rails from '@rails/ujs';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import './public-path';
|
||||
import main from 'mastodon/main';
|
||||
|
||||
import { start } from '../mastodon/common';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import './public-path';
|
||||
import ready from '../mastodon/ready';
|
||||
|
||||
ready(() => {
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
import '../styles/mailer.scss';
|
||||
|
||||
require.context('../icons');
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import './public-path';
|
||||
|
||||
import { IntlMessageFormat } from 'intl-messageformat';
|
||||
import type { MessageDescriptor, PrimitiveType } from 'react-intl';
|
||||
import { defineMessages } from 'react-intl';
|
||||
|
|
|
@ -8,8 +8,6 @@ and performs no other task.
|
|||
|
||||
*/
|
||||
|
||||
import './public-path';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
interface JRDLink {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import './public-path';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import { start } from '../mastodon/common';
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import './public-path';
|
||||
import axios from 'axios';
|
||||
|
||||
import ready from '../mastodon/ready';
|
||||
|
|
|
@ -2,7 +2,7 @@ import Rails from '@rails/ujs';
|
|||
import 'font-awesome/css/font-awesome.css';
|
||||
|
||||
export function start() {
|
||||
require.context('../images/', true, /\.(jpg|png|svg)$/);
|
||||
// require.context('../images/', true, /\.(jpg|png|svg)$/);
|
||||
|
||||
try {
|
||||
Rails.start();
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/* eslint-disable import/no-commonjs --
|
||||
We need to use CommonJS here due to preval */
|
||||
// @preval
|
||||
// http://www.unicode.org/Public/emoji/5.0/emoji-test.txt
|
||||
// This file contains the compressed version of the emoji data from
|
||||
|
@ -11,16 +9,16 @@
|
|||
// to ensure that the prevaled file is regenerated by Babel
|
||||
// version: 2
|
||||
|
||||
const { emojiIndex } = require('emoji-mart');
|
||||
let data = require('emoji-mart/data/all.json');
|
||||
const { uncompress: emojiMartUncompress } = require('emoji-mart/dist/utils/data');
|
||||
import { emojiIndex } from 'emoji-mart';
|
||||
import data from 'emoji-mart/data/all.json';
|
||||
import { uncompress as emojiMartUncompress } from 'emoji-mart/dist/utils/data';
|
||||
|
||||
const emojiMap = require('./emoji_map.json');
|
||||
const { unicodeToFilename } = require('./unicode_to_filename');
|
||||
const { unicodeToUnifiedName } = require('./unicode_to_unified_name');
|
||||
import emojiMap from './emoji_map.json';
|
||||
import { unicodeToFilename } from './unicode_to_filename';
|
||||
import { unicodeToUnifiedName } from './unicode_to_unified_name';
|
||||
|
||||
if(data.compressed) {
|
||||
data = emojiMartUncompress(data);
|
||||
emojiMartUncompress(data);
|
||||
}
|
||||
|
||||
const emojiMartData = data;
|
||||
|
@ -119,7 +117,7 @@ Object.keys(emojiIndex.emojis).forEach(key => {
|
|||
|
||||
// JSON.parse/stringify is to emulate what @preval is doing and avoid any
|
||||
// inconsistent behavior in dev mode
|
||||
module.exports = JSON.parse(JSON.stringify([
|
||||
const emojiData = JSON.parse(JSON.stringify([
|
||||
shortCodesToEmojiData,
|
||||
/*
|
||||
* The property `skins` is not found in the current context.
|
||||
|
@ -136,3 +134,5 @@ module.exports = JSON.parse(JSON.stringify([
|
|||
emojiMartData.aliases,
|
||||
emojisWithoutShortCodes,
|
||||
]));
|
||||
|
||||
export default emojiData;
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
/* eslint-disable import/no-commonjs --
|
||||
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
|
||||
|
||||
// taken from:
|
||||
// https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866
|
||||
exports.unicodeToFilename = (str) => {
|
||||
export function unicodeToFilename(str) {
|
||||
let result = '';
|
||||
let charCode = 0;
|
||||
let p = 0;
|
||||
|
@ -26,4 +23,4 @@ exports.unicodeToFilename = (str) => {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/* eslint-disable import/no-commonjs --
|
||||
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
|
||||
|
||||
function padLeft(str, num) {
|
||||
while (str.length < num) {
|
||||
str = '0' + str;
|
||||
|
@ -9,7 +6,7 @@ function padLeft(str, num) {
|
|||
return str;
|
||||
}
|
||||
|
||||
exports.unicodeToUnifiedName = (str) => {
|
||||
export function unicodeToUnifiedName(str) {
|
||||
let output = '';
|
||||
|
||||
for (let i = 0; i < str.length; i += 2) {
|
||||
|
@ -21,4 +18,4 @@ exports.unicodeToUnifiedName = (str) => {
|
|||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ import { connect } from 'react-redux';
|
|||
import Textarea from 'react-textarea-autosize';
|
||||
import { length } from 'stringz';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js';
|
||||
import tesseractWorkerPath from 'tesseract.js/dist/worker.min.js?url';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js';
|
||||
import tesseractCorePath from 'tesseract.js-core/tesseract-core.wasm.js?url';
|
||||
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
import { Button } from 'mastodon/components/button';
|
||||
|
|
|
@ -5,6 +5,10 @@ import { isLocaleLoaded, setLocale } from './global_locale';
|
|||
|
||||
const localeLoadingSemaphore = new Semaphore(1);
|
||||
|
||||
const localeFiles = import.meta.glob<{ default: LocaleData['messages'] }>([
|
||||
'./*.json',
|
||||
]);
|
||||
|
||||
export async function loadLocale() {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we want to match empty strings
|
||||
const locale = document.querySelector<HTMLElement>('html')?.lang || 'en';
|
||||
|
@ -17,13 +21,14 @@ export async function loadLocale() {
|
|||
// if the locale is already set, then do nothing
|
||||
if (isLocaleLoaded()) return;
|
||||
|
||||
const localeData = (await import(
|
||||
/* webpackMode: "lazy" */
|
||||
/* webpackChunkName: "locale/[request]" */
|
||||
/* webpackInclude: /\.json$/ */
|
||||
/* webpackPreload: true */
|
||||
`mastodon/locales/${locale}.json`
|
||||
)) as LocaleData['messages'];
|
||||
// If there is no locale file, then fallback to english
|
||||
const localeFile = Object.hasOwn(localeFiles, '`./${locale}.json`')
|
||||
? localeFiles[`./${locale}.json`]
|
||||
: localeFiles[`./en.json`];
|
||||
|
||||
if (!localeFile) throw new Error('Could not load the locale JSON file');
|
||||
|
||||
const { default: localeData } = await localeFile();
|
||||
|
||||
setLocale({ messages: localeData, locale });
|
||||
});
|
||||
|
|
|
@ -54,11 +54,9 @@ async function loadIntlPluralRulesPolyfills(locale: string) {
|
|||
return;
|
||||
}
|
||||
// Load the polyfill 1st BEFORE loading data
|
||||
await import('@formatjs/intl-pluralrules/polyfill-force');
|
||||
await import(
|
||||
/* webpackChunkName: "i18n-pluralrules-polyfill" */ '@formatjs/intl-pluralrules/polyfill-force'
|
||||
);
|
||||
await import(
|
||||
/* webpackChunkName: "i18n-pluralrules-polyfill-[request]" */ `@formatjs/intl-pluralrules/locale-data/${unsupportedLocale}`
|
||||
`../../../../node_modules/@formatjs/intl-pluralrules/locale-data/${unsupportedLocale}.js`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
/* eslint-disable import/no-commonjs --
|
||||
We need to use CommonJS here as its imported into a preval file (`emoji_compressed.js`) */
|
||||
|
||||
/* @preval */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const filtered = {};
|
||||
const filenames = fs.readdirSync(path.resolve(__dirname, '../locales'));
|
||||
|
@ -35,4 +32,6 @@ filenames.forEach(filename => {
|
|||
};
|
||||
});
|
||||
|
||||
module.exports = JSON.parse(JSON.stringify(filtered));
|
||||
const locales = JSON.parse(JSON.stringify(filtered));
|
||||
|
||||
export default locales;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
export function isDevelopment() {
|
||||
if (typeof process !== 'undefined')
|
||||
return process.env.NODE_ENV === 'development';
|
||||
else return import.meta.env.DEV;
|
||||
}
|
||||
|
||||
export function isProduction() {
|
||||
if (typeof process !== 'undefined')
|
||||
return process.env.NODE_ENV === 'production';
|
||||
else return import.meta.env.PROD;
|
||||
}
|
||||
|
|
19
app/javascript/types/image.d.ts
vendored
19
app/javascript/types/image.d.ts
vendored
|
@ -1,3 +1,5 @@
|
|||
/// <reference types="vite-plugin-svgr/client" />
|
||||
|
||||
/* eslint-disable import/no-default-export */
|
||||
declare module '*.avif' {
|
||||
const path: string;
|
||||
|
@ -19,23 +21,6 @@ declare module '*.png' {
|
|||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
const path: string;
|
||||
export default path;
|
||||
}
|
||||
|
||||
declare module '*.svg?react' {
|
||||
import type React from 'react';
|
||||
|
||||
interface SVGPropsWithTitle extends React.SVGProps<SVGSVGElement> {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
const ReactComponent: React.FC<SVGPropsWithTitle>;
|
||||
|
||||
export default ReactComponent;
|
||||
}
|
||||
|
||||
declare module '*.webp' {
|
||||
const path: string;
|
||||
export default path;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- content_for :page_title do
|
||||
= t('auth.login')
|
||||
|
||||
= javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'two_factor_authentication.ts', crossorigin: 'anonymous'
|
||||
|
||||
- if webauthn_enabled?
|
||||
= render partial: 'auth/sessions/two_factor/webauthn_form', locals: { hidden: @scheme_type != 'webauthn' }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- content_for :page_title do
|
||||
= t('auth.setup.title')
|
||||
|
||||
= javascript_pack_tag 'sign_up', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'sign_up.ts', crossorigin: 'anonymous'
|
||||
|
||||
= simple_form_for(@user, url: auth_setup_path) do |f|
|
||||
= render 'auth/shared/progress', stage: 'confirm'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- content_for :header_tags do
|
||||
= render_initial_state
|
||||
= javascript_pack_tag 'public', crossorigin: 'anonymous'
|
||||
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'public.tsx', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'admin.tsx', crossorigin: 'anonymous'
|
||||
|
||||
- content_for :content do
|
||||
.admin-wrapper
|
||||
|
|
|
@ -26,17 +26,17 @@
|
|||
|
||||
%title= html_title
|
||||
|
||||
= stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
|
||||
= vite_client_tag
|
||||
= vite_react_refresh_tag
|
||||
= theme_style_tags current_theme
|
||||
-# Needed for the wicg-inert polyfill. It needs to be on it's own <style> tag, with this `id`
|
||||
= stylesheet_pack_tag 'inert', media: 'all', id: 'inert-style'
|
||||
= vite_stylesheet_tag 'styles/inert.scss', media: 'all', id: 'inert-style'
|
||||
|
||||
= javascript_pack_tag 'common', crossorigin: 'anonymous'
|
||||
= preload_pack_asset "locale/#{I18n.locale}-json.js"
|
||||
-# = preload_pack_asset "locale/#{I18n.locale}-json.js"
|
||||
= csrf_meta_tags unless skip_csrf_meta_tags?
|
||||
%meta{ name: 'style-nonce', content: request.content_security_policy_nonce }
|
||||
|
||||
= stylesheet_link_tag custom_css_path, skip_pipeline: true, host: root_url, media: 'all'
|
||||
-# = stylesheet_link_tag custom_css_path, skip_pipeline: true, host: root_url, media: 'all'
|
||||
|
||||
= yield :header_tags
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- content_for :header_tags do
|
||||
= javascript_pack_tag 'public', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'public.tsx', crossorigin: 'anonymous'
|
||||
|
||||
- content_for :content do
|
||||
.container-alt
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
- if storage_host?
|
||||
%link{ rel: 'dns-prefetch', href: storage_host }/
|
||||
|
||||
= stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
|
||||
= vite_client_tag
|
||||
= vite_react_refresh_tag
|
||||
= theme_style_tags Setting.theme # Use the admin-configured theme here, even if logged in
|
||||
= javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
|
||||
= preload_pack_asset "locale/#{I18n.locale}-json.js"
|
||||
= render_initial_state
|
||||
= javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
|
||||
-# = preload_pack_asset "locale/#{I18n.locale}-json.js"
|
||||
= vite_typescript_tag 'public.tsx', crossorigin: 'anonymous'
|
||||
%body.embed
|
||||
= yield
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
%meta{ charset: 'utf-8' }/
|
||||
%title= safe_join([yield(:page_title), Setting.default_settings['site_title']], ' - ')
|
||||
%meta{ content: 'width=device-width,initial-scale=1', name: 'viewport' }/
|
||||
= stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous'
|
||||
|
||||
= vite_client_tag
|
||||
= vite_react_refresh_tag
|
||||
= theme_style_tags Setting.default_settings['theme']
|
||||
= javascript_pack_tag 'common', crossorigin: 'anonymous'
|
||||
= javascript_pack_tag 'error', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'error.ts', crossorigin: 'anonymous'
|
||||
%body.error
|
||||
.dialog
|
||||
.dialog__illustration
|
||||
|
|
|
@ -3,6 +3,4 @@
|
|||
%head
|
||||
%meta{ charset: 'utf-8' }/
|
||||
|
||||
= javascript_pack_tag 'common', crossorigin: 'anonymous'
|
||||
|
||||
= yield :header_tags
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
= stylesheet_pack_tag 'mailer'
|
||||
= vite_stylesheet_tag 'styles/mailer.scss'
|
||||
%body
|
||||
.email{ dir: locale_direction }
|
||||
%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- content_for :header_tags do
|
||||
= javascript_pack_tag 'public', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'public.tsx', crossorigin: 'anonymous'
|
||||
|
||||
- content_for :content do
|
||||
- if user_signed_in? && !@hide_header
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- content_for :header_tags do
|
||||
= render_initial_state
|
||||
= javascript_pack_tag 'public', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'public.tsx', crossorigin: 'anonymous'
|
||||
|
||||
:ruby
|
||||
meta = @media_attachment.file.meta || {}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
= t('settings.relationships')
|
||||
|
||||
- content_for :header_tags do
|
||||
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'admin.tsx', crossorigin: 'anonymous'
|
||||
|
||||
.filters
|
||||
.filter-subset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- content_for :header_tags do
|
||||
%meta{ name: 'robots', content: 'noindex' }/
|
||||
|
||||
= javascript_pack_tag 'remote_interaction_helper', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'remote_interaction_helper.ts', crossorigin: 'anonymous'
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
.actions
|
||||
= f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit
|
||||
|
||||
= javascript_pack_tag 'two_factor_authentication', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'two_factor_authentication.ts', crossorigin: 'anonymous'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
- content_for :header_tags do
|
||||
- if user_signed_in?
|
||||
-#
|
||||
= preload_pack_asset 'features/compose.js'
|
||||
= preload_pack_asset 'features/home_timeline.js'
|
||||
= preload_pack_asset 'features/notifications.js'
|
||||
|
@ -8,7 +9,7 @@
|
|||
%meta{ name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key }
|
||||
|
||||
= render_initial_state
|
||||
= javascript_pack_tag 'application', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'application.ts', crossorigin: 'anonymous'
|
||||
|
||||
.notranslate.app-holder#mastodon{ data: { props: Oj.dump(default_props) } }
|
||||
%noscript
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- content_for :header_tags do
|
||||
= render_initial_state
|
||||
= javascript_pack_tag 'share', crossorigin: 'anonymous'
|
||||
= vite_typescript_tag 'share.tsx', crossorigin: 'anonymous'
|
||||
|
||||
#mastodon-compose{ data: { props: Oj.dump(default_props) } }
|
||||
|
|
27
bin/vite
Executable file
27
bin/vite
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# This file was generated by Bundler.
|
||||
#
|
||||
# The application 'vite' is installed as part of a gem, and
|
||||
# this file is here to facilitate running it.
|
||||
#
|
||||
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
||||
|
||||
bundle_binstub = File.expand_path("bundle", __dir__)
|
||||
|
||||
if File.file?(bundle_binstub)
|
||||
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
||||
load(bundle_binstub)
|
||||
else
|
||||
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
||||
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
||||
end
|
||||
end
|
||||
|
||||
require "rubygems"
|
||||
require "bundler/setup"
|
||||
|
||||
load Gem.bin_path("vite_ruby", "vite")
|
|
@ -45,8 +45,6 @@ require_relative '../lib/chewy/settings_extensions'
|
|||
require_relative '../lib/chewy/index_extensions'
|
||||
require_relative '../lib/chewy/strategy/mastodon'
|
||||
require_relative '../lib/chewy/strategy/bypass_with_warning'
|
||||
require_relative '../lib/webpacker/manifest_extensions'
|
||||
require_relative '../lib/webpacker/helper_extensions'
|
||||
require_relative '../lib/rails/engine_extensions'
|
||||
require_relative '../lib/action_dispatch/remote_ip_extensions'
|
||||
require_relative '../lib/active_record/database_tasks_extensions'
|
||||
|
|
|
@ -36,7 +36,6 @@ Rails.application.config.content_security_policy do |p|
|
|||
p.frame_ancestors :none
|
||||
p.font_src :self, assets_host
|
||||
p.img_src :self, :data, :blob, *media_hosts
|
||||
p.style_src :self, assets_host
|
||||
p.media_src :self, :data, *media_hosts
|
||||
p.frame_src :self, :https
|
||||
p.manifest_src :self, assets_host
|
||||
|
@ -51,14 +50,15 @@ Rails.application.config.content_security_policy do |p|
|
|||
p.worker_src :self, :blob, assets_host
|
||||
|
||||
if Rails.env.development?
|
||||
webpacker_public_host = ENV.fetch('WEBPACKER_DEV_SERVER_PUBLIC', Webpacker.config.dev_server[:public])
|
||||
front_end_build_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{webpacker_public_host}" }
|
||||
front_end_build_urls = %w(ws http).map { |protocol| "#{protocol}#{ViteRuby.config.https ? 's' : ''}://#{ViteRuby.config.host_with_port}" }
|
||||
|
||||
p.connect_src :self, :data, :blob, *media_hosts, Rails.configuration.x.streaming_api_base_url, *front_end_build_urls
|
||||
p.script_src :self, :unsafe_inline, :unsafe_eval, assets_host
|
||||
p.style_src :self, assets_host, :unsafe_inline
|
||||
else
|
||||
p.connect_src :self, :data, :blob, *media_hosts, Rails.configuration.x.streaming_api_base_url
|
||||
p.script_src :self, assets_host, "'wasm-unsafe-eval'"
|
||||
p.style_src :self, assets_host
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
"additionalEntrypoints": ["~/{icons,images}/**/*", "~/styles/*.scss"],
|
||||
"watchAdditionalPaths": []
|
||||
},
|
||||
"production": {
|
||||
"publicOutputDir": "packs"
|
||||
},
|
||||
"development": {
|
||||
"autoBuild": true,
|
||||
"publicOutputDir": "vite-dev",
|
||||
|
|
|
@ -2,21 +2,33 @@
|
|||
|
||||
module PremailerBundledAssetStrategy
|
||||
def load(url)
|
||||
asset_host = ENV['CDN_HOST'] || ENV['WEB_DOMAIN'] || ENV.fetch('LOCAL_DOMAIN', nil)
|
||||
if ViteRuby.instance.dev_server_running?
|
||||
return unless url.start_with?("/#{ViteRuby.config.public_output_dir}/")
|
||||
|
||||
if Webpacker.dev_server.running?
|
||||
asset_host = "#{Webpacker.dev_server.protocol}://#{Webpacker.dev_server.host_with_port}"
|
||||
url = File.join(asset_host, url)
|
||||
end
|
||||
# Request from the dev server
|
||||
|
||||
css = if url.start_with?('http')
|
||||
HTTP.get(url).to_s
|
||||
headers = {}
|
||||
# Vite dev server wants this header for CSS files, otherwise it will respond with a JS file that inserts the CSS (to support hot reloading)
|
||||
headers['Accept'] = 'text/css' if url.end_with?('.scss', '.css')
|
||||
|
||||
Net::HTTP.get(
|
||||
URI("#{ViteRuby.config.origin}#{url}"),
|
||||
headers
|
||||
).presence
|
||||
else
|
||||
url = url[1..] if url.start_with?('/')
|
||||
Rails.public_path.join(url).read
|
||||
end
|
||||
# Read the file from filesystem
|
||||
vite_path = ViteRuby.instance.manifest.path_for(url)
|
||||
|
||||
css.gsub(%r{url\(/}, "url(#{asset_host}/")
|
||||
return unless vite_path
|
||||
|
||||
path = Rails.public_path.join(vite_path.delete_prefix('/'))
|
||||
|
||||
return unless path.exist?
|
||||
|
||||
path.read
|
||||
end
|
||||
rescue ViteRuby::MissingEntrypointError
|
||||
# If the path is not in the manifest, ignore it
|
||||
end
|
||||
|
||||
module_function :load
|
||||
|
|
|
@ -14,7 +14,6 @@ end
|
|||
|
||||
if Rake::Task.task_defined?('assets:precompile')
|
||||
Rake::Task['assets:precompile'].enhance do
|
||||
Webpacker.manifest.refresh
|
||||
Rake::Task['assets:generate_static_pages'].invoke
|
||||
end
|
||||
end
|
||||
|
|
|
@ -139,6 +139,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@formatjs/cli": "^6.1.1",
|
||||
"@optimize-lodash/rollup-plugin": "^4.0.4",
|
||||
"@testing-library/react": "^15.0.0",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/emoji-mart": "^3.0.9",
|
||||
|
@ -187,6 +188,7 @@
|
|||
"stylelint": "^16.0.2",
|
||||
"stylelint-config-standard-scss": "^13.0.0",
|
||||
"typescript": "^5.0.4",
|
||||
"vite-bundle-analyzer": "^0.9.4",
|
||||
"vite-plugin-rails": "^0.5.0",
|
||||
"vite-plugin-svgr": "^4.2.0",
|
||||
"vitest": "^1.5.0",
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = ({ env }) => ({
|
||||
const config = () => ({
|
||||
plugins: [
|
||||
require('postcss-preset-env'),
|
||||
require('autoprefixer'),
|
||||
env === 'production' ? require('cssnano') : '',
|
||||
require('autoprefixer')
|
||||
],
|
||||
});
|
||||
|
||||
|
|
|
@ -80,9 +80,6 @@ end
|
|||
RSpec.configure do |config|
|
||||
config.before :suite do
|
||||
if streaming_examples_present?
|
||||
# Compile assets
|
||||
Webpacker.compile
|
||||
|
||||
# Start the node streaming server
|
||||
streaming_server_manager.start(port: STREAMING_PORT)
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"target": "esnext",
|
||||
"module": "CommonJS",
|
||||
"module": "es2022",
|
||||
"moduleResolution": "node",
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
|
@ -11,7 +11,7 @@
|
|||
"noUncheckedIndexedAccess": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["vitest/globals"],
|
||||
"types": ["vite/client", "vitest/globals"],
|
||||
"baseUrl": "./",
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "tmp/cache/tsconfig.tsbuildinfo",
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
// import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
||||
import { optimizeLodashImports } from '@optimize-lodash/rollup-plugin';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vite';
|
||||
import { analyzer } from 'vite-bundle-analyzer';
|
||||
import RailsPlugin from 'vite-plugin-rails';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
import { defineConfig, configDefaults } from 'vitest/config';
|
||||
import { configDefaults } from 'vitest/config';
|
||||
import GithubActionsReporter from 'vitest-github-actions-reporter';
|
||||
|
||||
const sourceCodeDir = 'app/javascript';
|
||||
|
@ -25,6 +27,40 @@ directories.forEach((directory) => {
|
|||
});
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
commonjsOptions: { transformMixedEsModules: true },
|
||||
rollupOptions: {
|
||||
output: {
|
||||
chunkFileNames: (chunkInfo) => {
|
||||
if (
|
||||
chunkInfo.facadeModuleId?.match(
|
||||
/mastodon\/locales\/[a-zA-Z-]+\.json/,
|
||||
)
|
||||
) {
|
||||
// put all locale files in `intl/`
|
||||
return `intl/[name]-[hash].js`;
|
||||
} else if (
|
||||
chunkInfo.facadeModuleId?.match(/node_modules\/@formatjs\//)
|
||||
) {
|
||||
// use a custom name for formatjs polyfill files
|
||||
const name = chunkInfo.facadeModuleId.match(
|
||||
/node_modules\/@formatjs\/([^/]+)\//,
|
||||
);
|
||||
|
||||
if (name?.[1]) return `intl/[name]-${name[1]}-[hash].js`;
|
||||
} else if (chunkInfo.name === 'index' && chunkInfo.facadeModuleId) {
|
||||
// Use a custom name for chunks, to avoid having too many of them called "index"
|
||||
const parts = chunkInfo.facadeModuleId.split('/');
|
||||
|
||||
const parent = parts.at(-2);
|
||||
|
||||
if (parent) return `${parent}-[name]-[hash].js`;
|
||||
}
|
||||
return `[name]-[hash].js`;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
...aliasesFromJavascriptRoot,
|
||||
|
@ -45,9 +81,9 @@ export default defineConfig({
|
|||
},
|
||||
}),
|
||||
svgr(),
|
||||
// optimizeLodashImports(),
|
||||
// !!process.env.ANALYZE_BUNDLE_SIZE &&
|
||||
// visualizer({ open: true, gzipSize: true, brotliSize: true }),
|
||||
// @ts-expect-error the types for the plugin are not up-to-date
|
||||
optimizeLodashImports(),
|
||||
!!process.env.ANALYZE_BUNDLE_SIZE && analyzer({ analyzerMode: 'static' }),
|
||||
],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
|
|
84
yarn.lock
84
yarn.lock
|
@ -3009,6 +3009,7 @@ __metadata:
|
|||
"@formatjs/intl-pluralrules": "npm:^5.2.2"
|
||||
"@gamestdio/websocket": "npm:^0.3.2"
|
||||
"@github/webauthn-json": "npm:^2.1.1"
|
||||
"@optimize-lodash/rollup-plugin": "npm:^4.0.4"
|
||||
"@rails/ujs": "npm:7.1.3"
|
||||
"@reduxjs/toolkit": "npm:^2.0.1"
|
||||
"@svgr/webpack": "npm:^5.5.0"
|
||||
|
@ -3136,6 +3137,7 @@ __metadata:
|
|||
twitter-text: "npm:3.1.0"
|
||||
typescript: "npm:^5.0.4"
|
||||
vite: "npm:^5.2.8"
|
||||
vite-bundle-analyzer: "npm:^0.9.4"
|
||||
vite-plugin-rails: "npm:^0.5.0"
|
||||
vite-plugin-svgr: "npm:^4.2.0"
|
||||
vitest: "npm:^1.5.0"
|
||||
|
@ -3273,6 +3275,28 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@optimize-lodash/rollup-plugin@npm:^4.0.4":
|
||||
version: 4.0.4
|
||||
resolution: "@optimize-lodash/rollup-plugin@npm:4.0.4"
|
||||
dependencies:
|
||||
"@optimize-lodash/transform": "npm:3.0.3"
|
||||
"@rollup/pluginutils": "npm:~5.0.2"
|
||||
peerDependencies:
|
||||
rollup: ">=2.x"
|
||||
checksum: 10c0/219f9f2f2b10efb22c0e4a6f362394483498ba7998aeac041e0c696f65e696a170657f0ac2670e32c2aa2cfdcb72bf91e8a0c32564c48970b9871aef42de227d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@optimize-lodash/transform@npm:3.0.3":
|
||||
version: 3.0.3
|
||||
resolution: "@optimize-lodash/transform@npm:3.0.3"
|
||||
dependencies:
|
||||
estree-walker: "npm:2.x"
|
||||
magic-string: "npm:0.30.x"
|
||||
checksum: 10c0/ad85a78d793d4c5d5bdd055b5bc15c45674b1bc6eaa8c170fc04f83ac49d497976dd910a854e3c7798b9701df7a5426136dcec4bc96dea4a62574fa8bf099aed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@pkgjs/parseargs@npm:^0.11.0":
|
||||
version: 0.11.0
|
||||
resolution: "@pkgjs/parseargs@npm:0.11.0"
|
||||
|
@ -3425,6 +3449,22 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rollup/pluginutils@npm:~5.0.2":
|
||||
version: 5.0.5
|
||||
resolution: "@rollup/pluginutils@npm:5.0.5"
|
||||
dependencies:
|
||||
"@types/estree": "npm:^1.0.0"
|
||||
estree-walker: "npm:^2.0.2"
|
||||
picomatch: "npm:^2.3.1"
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
checksum: 10c0/18a1f5a9afa993a76663cc2102169cd546786b39a3e92bdc8a2a0b408b509d070a02b20970a30daa9d5d0b1b591b5e7734add84b3aaf263178aef5a26cfab2cf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rollup/rollup-android-arm-eabi@npm:4.14.1":
|
||||
version: 4.14.1
|
||||
resolution: "@rollup/rollup-android-arm-eabi@npm:4.14.1"
|
||||
|
@ -8360,6 +8400,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"estree-walker@npm:2.x, estree-walker@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "estree-walker@npm:2.0.2"
|
||||
checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"estree-walker@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "estree-walker@npm:1.0.1"
|
||||
|
@ -8367,13 +8414,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"estree-walker@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "estree-walker@npm:2.0.2"
|
||||
checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"estree-walker@npm:^3.0.3":
|
||||
version: 3.0.3
|
||||
resolution: "estree-walker@npm:3.0.3"
|
||||
|
@ -11194,6 +11234,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-string@npm:0.30.x, magic-string@npm:^0.30.5":
|
||||
version: 0.30.9
|
||||
resolution: "magic-string@npm:0.30.9"
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec": "npm:^1.4.15"
|
||||
checksum: 10c0/edbeea35b4f90b58815d8b13899fa412b5bc1e81cae14fe6d24d5c383c5f04331fce2c5a75bfb7926203ab6fc8c71290cdab56703a5b82432d8a1e144d6042e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-string@npm:^0.25.0, magic-string@npm:^0.25.7":
|
||||
version: 0.25.9
|
||||
resolution: "magic-string@npm:0.25.9"
|
||||
|
@ -11212,15 +11261,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-string@npm:^0.30.5":
|
||||
version: 0.30.9
|
||||
resolution: "magic-string@npm:0.30.9"
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec": "npm:^1.4.15"
|
||||
checksum: 10c0/edbeea35b4f90b58815d8b13899fa412b5bc1e81cae14fe6d24d5c383c5f04331fce2c5a75bfb7926203ab6fc8c71290cdab56703a5b82432d8a1e144d6042e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"make-dir@npm:^3.0.2, make-dir@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "make-dir@npm:3.1.0"
|
||||
|
@ -15649,7 +15689,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"source-map@npm:^0.7.3":
|
||||
"source-map@npm:^0.7.3, source-map@npm:^0.7.4":
|
||||
version: 0.7.4
|
||||
resolution: "source-map@npm:0.7.4"
|
||||
checksum: 10c0/dc0cf3768fe23c345ea8760487f8c97ef6fca8a73c83cd7c9bf2fde8bc2c34adb9c0824d6feb14bc4f9e37fb522e18af621543f1289038a66ac7586da29aa7dc
|
||||
|
@ -17237,6 +17277,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-bundle-analyzer@npm:^0.9.4":
|
||||
version: 0.9.4
|
||||
resolution: "vite-bundle-analyzer@npm:0.9.4"
|
||||
dependencies:
|
||||
picocolors: "npm:^1.0.0"
|
||||
source-map: "npm:^0.7.4"
|
||||
checksum: 10c0/518c8e50be44c1fef0bd754a86bb992349d8aa5df338215188c4e76df5a503f53290442fedb2ca2bd3cafff2eff9d0434bd56d9b5ac4a5a1cf14550e354a141f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vite-node@npm:1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "vite-node@npm:1.5.0"
|
||||
|
|
Loading…
Reference in New Issue
Block a user