Make Vite devserver work
This commit is contained in:
parent
f7b84982e3
commit
2acab99e5b
15 changed files with 1313 additions and 93 deletions
24
app/index.html
Normal file
24
app/index.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link href="/manifest.json" rel="manifest">
|
||||
<!--server-generated-meta-->
|
||||
<script type="module" src="./soapbox/main.tsx"></script>
|
||||
</head>
|
||||
<body class="theme-mode-light no-reduce-motion">
|
||||
<div id="soapbox" class="h-full">
|
||||
<div class="loading-indicator-wrapper">
|
||||
<div class="loading-indicator">
|
||||
<div class="loading-indicator__container">
|
||||
<div class="loading-indicator__figure"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<noscript>To use this website, please enable JavaScript.</noscript>
|
||||
</body>
|
||||
</html>
|
45
app/soapbox/build-config-compiletime.ts
Normal file
45
app/soapbox/build-config-compiletime.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Build config: configuration set at build time.
|
||||
* @module soapbox/build-config
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line import/extensions
|
||||
import trim from 'lodash/trim.js';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import trimEnd from 'lodash/trimEnd.js';
|
||||
|
||||
const {
|
||||
NODE_ENV,
|
||||
BACKEND_URL,
|
||||
FE_SUBDIRECTORY,
|
||||
FE_BUILD_DIR,
|
||||
FE_INSTANCE_SOURCE_DIR,
|
||||
SENTRY_DSN,
|
||||
} = process.env;
|
||||
|
||||
const sanitizeURL = (url: string | undefined = ''): string => {
|
||||
try {
|
||||
return trimEnd(new URL(url).toString(), '/');
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const sanitizeBasename = (path: string | undefined = ''): string => {
|
||||
return `/${trim(path, '/')}`;
|
||||
};
|
||||
|
||||
const sanitizePath = (path: string | undefined = ''): string => {
|
||||
return trim(path, '/');
|
||||
};
|
||||
|
||||
export default () => ({
|
||||
data: {
|
||||
NODE_ENV: NODE_ENV || 'development',
|
||||
BACKEND_URL: sanitizeURL(BACKEND_URL),
|
||||
FE_SUBDIRECTORY: sanitizeBasename(FE_SUBDIRECTORY),
|
||||
FE_BUILD_DIR: sanitizePath(FE_BUILD_DIR) || 'static',
|
||||
FE_INSTANCE_SOURCE_DIR: FE_INSTANCE_SOURCE_DIR || 'instance',
|
||||
SENTRY_DSN,
|
||||
},
|
||||
});
|
|
@ -1,46 +0,0 @@
|
|||
// @preval
|
||||
/**
|
||||
* Build config: configuration set at build time.
|
||||
* @module soapbox/build-config
|
||||
*/
|
||||
|
||||
const trim = require('lodash/trim');
|
||||
const trimEnd = require('lodash/trimEnd');
|
||||
|
||||
const {
|
||||
NODE_ENV,
|
||||
BACKEND_URL,
|
||||
FE_SUBDIRECTORY,
|
||||
FE_BUILD_DIR,
|
||||
FE_INSTANCE_SOURCE_DIR,
|
||||
SENTRY_DSN,
|
||||
} = process.env;
|
||||
|
||||
const sanitizeURL = url => {
|
||||
try {
|
||||
return trimEnd(new URL(url).toString(), '/');
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const sanitizeBasename = path => {
|
||||
return `/${trim(path, '/')}`;
|
||||
};
|
||||
|
||||
const sanitizePath = path => {
|
||||
return trim(path, '/');
|
||||
};
|
||||
|
||||
// JSON.parse/stringify is to emulate what @preval is doing and avoid any
|
||||
// inconsistent behavior in dev mode
|
||||
const sanitize = obj => JSON.parse(JSON.stringify(obj));
|
||||
|
||||
module.exports = sanitize({
|
||||
NODE_ENV: NODE_ENV || 'development',
|
||||
BACKEND_URL: sanitizeURL(BACKEND_URL),
|
||||
FE_SUBDIRECTORY: sanitizeBasename(FE_SUBDIRECTORY),
|
||||
FE_BUILD_DIR: sanitizePath(FE_BUILD_DIR) || 'static',
|
||||
FE_INSTANCE_SOURCE_DIR: FE_INSTANCE_SOURCE_DIR || 'instance',
|
||||
SENTRY_DSN,
|
||||
});
|
18
app/soapbox/build-config.ts
Normal file
18
app/soapbox/build-config.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
// @ts-nocheck
|
||||
const {
|
||||
NODE_ENV,
|
||||
BACKEND_URL,
|
||||
FE_SUBDIRECTORY,
|
||||
FE_BUILD_DIR,
|
||||
FE_INSTANCE_SOURCE_DIR,
|
||||
SENTRY_DSN,
|
||||
} = import.meta.compileTime('./build-config-compiletime.ts');
|
||||
|
||||
export {
|
||||
NODE_ENV,
|
||||
BACKEND_URL,
|
||||
FE_SUBDIRECTORY,
|
||||
FE_BUILD_DIR,
|
||||
FE_INSTANCE_SOURCE_DIR,
|
||||
SENTRY_DSN,
|
||||
};
|
|
@ -7,9 +7,8 @@ import * as BuildConfig from 'soapbox/build-config';
|
|||
export const custom = (filename: string, fallback: any = {}): any => {
|
||||
if (BuildConfig.NODE_ENV === 'test') return fallback;
|
||||
|
||||
// @ts-ignore: yes it does
|
||||
const context = require.context('custom', false, /\.json$/);
|
||||
const path = `./${filename}.json`;
|
||||
const modules = import.meta.glob('../../custom/*.json', { eager: true });
|
||||
const key = `../../custom/${filename}.json`;
|
||||
|
||||
return context.keys().includes(path) ? context(path) : fallback;
|
||||
return modules[key] ? modules[key] : fallback;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import genericIcon from 'cryptocurrency-icons/svg/color/generic.svg';
|
||||
import React from 'react';
|
||||
|
||||
/** Get crypto icon URL by ticker symbol, or fall back to generic icon */
|
||||
const getIcon = (ticker: string): string => {
|
||||
try {
|
||||
return require(`cryptocurrency-icons/svg/color/${ticker.toLowerCase()}.svg`);
|
||||
} catch {
|
||||
return require('cryptocurrency-icons/svg/color/generic.svg');
|
||||
}
|
||||
const modules: Record<string, any> = import.meta.glob('../../../../../node_modules/cryptocurrency-icons/svg/color/*.svg', { eager: true });
|
||||
const key = `../../../../../node_modules/cryptocurrency-icons/svg/color/${ticker}.svg`;
|
||||
return modules[key]?.default || genericIcon;
|
||||
};
|
||||
|
||||
interface ICryptoIcon {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Index } from 'flexsearch-ts';
|
||||
import Index from 'flexsearch/dist/module';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
|
||||
import data from './data';
|
||||
|
|
|
@ -2,7 +2,7 @@ import { List as ImmutableList, Map as ImmutableMap, Record as ImmutableRecord,
|
|||
import trim from 'lodash/trim';
|
||||
|
||||
import { MASTODON_PRELOAD_IMPORT } from 'soapbox/actions/preload';
|
||||
import BuildConfig from 'soapbox/build-config';
|
||||
import * as BuildConfig from 'soapbox/build-config';
|
||||
import KVStore from 'soapbox/storage/kv-store';
|
||||
import { validId, isURL } from 'soapbox/utils/auth';
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// @preval
|
||||
const { execSync } = require('child_process');
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
const pkg = require('../../../package.json');
|
||||
import pkg from '../../../package.json';
|
||||
|
||||
const { CI_COMMIT_TAG, CI_COMMIT_REF_NAME, CI_COMMIT_SHA } = process.env;
|
||||
|
||||
const shortRepoName = url => new URL(url).pathname.substring(1);
|
||||
const trimHash = hash => hash.substring(0, 7);
|
||||
const shortRepoName = (url: string): string => new URL(url).pathname.substring(1);
|
||||
const trimHash = (hash: string): string => hash.substring(0, 7);
|
||||
|
||||
const tryGit = cmd => {
|
||||
const tryGit = (cmd: string): string | undefined => {
|
||||
try {
|
||||
return String(execSync(cmd));
|
||||
} catch (e) {
|
||||
|
@ -16,7 +15,7 @@ const tryGit = cmd => {
|
|||
}
|
||||
};
|
||||
|
||||
const version = pkg => {
|
||||
const version = (pkg: Record<string, any>) => {
|
||||
// Try to discern from GitLab CI first
|
||||
if (CI_COMMIT_TAG === `v${pkg.version}` || CI_COMMIT_REF_NAME === 'stable') {
|
||||
return pkg.version;
|
||||
|
@ -36,12 +35,14 @@ const version = pkg => {
|
|||
return pkg.version;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
name: pkg.name,
|
||||
displayName: pkg.displayName,
|
||||
url: pkg.repository.url,
|
||||
repository: shortRepoName(pkg.repository.url),
|
||||
version: version(pkg),
|
||||
homepage: pkg.homepage,
|
||||
ref: CI_COMMIT_TAG || CI_COMMIT_SHA || tryGit('git rev-parse HEAD'),
|
||||
};
|
||||
export default () => ({
|
||||
data: {
|
||||
name: pkg.name,
|
||||
displayName: pkg.displayName,
|
||||
url: pkg.repository.url,
|
||||
repository: shortRepoName(pkg.repository.url),
|
||||
version: version(pkg),
|
||||
homepage: pkg.homepage,
|
||||
ref: CI_COMMIT_TAG || CI_COMMIT_SHA || tryGit('git rev-parse HEAD'),
|
||||
},
|
||||
});
|
3
app/soapbox/utils/code.ts
Normal file
3
app/soapbox/utils/code.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
const data: any = import.meta.compileTime('./code-compiletime.ts');
|
||||
|
||||
export default data;
|
|
@ -3,7 +3,7 @@
|
|||
* @module soapbox/utils/static
|
||||
*/
|
||||
|
||||
import { join } from 'path';
|
||||
import { join } from 'path-browserify';
|
||||
|
||||
import * as BuildConfig from 'soapbox/build-config';
|
||||
|
||||
|
|
14
package.json
14
package.json
|
@ -2,6 +2,7 @@
|
|||
"name": "soapbox",
|
||||
"displayName": "Soapbox",
|
||||
"version": "3.2.0",
|
||||
"type": "module",
|
||||
"description": "Soapbox frontend for the Fediverse.",
|
||||
"homepage": "https://soapbox.pub/",
|
||||
"repository": {
|
||||
|
@ -16,9 +17,9 @@
|
|||
"url": "https://gitlab.com/soapbox-pub/soapbox/-/issues"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "npx webpack-dev-server",
|
||||
"start": "npx vite serve",
|
||||
"dev": "${npm_execpath} run start",
|
||||
"build": "npx webpack",
|
||||
"build": "npx vite build",
|
||||
"audit:fix": "npx yarn-audit-fix",
|
||||
"manage:translations": "npx ts-node ./scripts/translationRunner.ts",
|
||||
"i18n": "rm -rf build tmp && npx cross-env NODE_ENV=production ${npm_execpath} run build && ${npm_execpath} manage:translations en",
|
||||
|
@ -74,6 +75,7 @@
|
|||
"@types/leaflet": "^1.8.0",
|
||||
"@types/lodash": "^4.14.180",
|
||||
"@types/object-assign": "^4.0.30",
|
||||
"@types/path-browserify": "^1.0.0",
|
||||
"@types/react": "^18.0.26",
|
||||
"@types/react-color": "^3.0.6",
|
||||
"@types/react-datepicker": "^4.4.2",
|
||||
|
@ -90,6 +92,7 @@
|
|||
"@types/webpack-assets-manifest": "^5.1.0",
|
||||
"@types/webpack-bundle-analyzer": "^4.6.0",
|
||||
"@types/webpack-deadcode-plugin": "^0.1.2",
|
||||
"@vitejs/plugin-react": "^4.0.4",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"axios": "^1.2.2",
|
||||
"axios-mock-adapter": "^1.21.1",
|
||||
|
@ -112,7 +115,7 @@
|
|||
"emoji-mart": "^5.5.2",
|
||||
"escape-html": "^1.0.3",
|
||||
"exif-js": "^2.3.0",
|
||||
"flexsearch-ts": "^0.7.31",
|
||||
"flexsearch": "^0.7.31",
|
||||
"fork-ts-checker-webpack-plugin": "^8.0.0",
|
||||
"graphemesplit": "^2.4.4",
|
||||
"html-webpack-harddisk-plugin": "^2.0.0",
|
||||
|
@ -183,6 +186,11 @@
|
|||
"typescript": "^5.1.3",
|
||||
"util": "^0.12.4",
|
||||
"uuid": "^9.0.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-compile-time": "^0.2.1",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"vite-plugin-require": "^1.1.10",
|
||||
"vite-plugin-static-copy": "^0.17.0",
|
||||
"webpack": "^5.72.1",
|
||||
"webpack-assets-manifest": "^5.1.0",
|
||||
"webpack-bundle-analyzer": "^4.5.0",
|
||||
|
|
|
@ -4,15 +4,19 @@
|
|||
"outDir": "build/",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"module": "es2022",
|
||||
"lib": ["es2019", "es6", "dom", "webworker"],
|
||||
"target": "es2015",
|
||||
"module": "ESNext",
|
||||
"lib": ["ESNext", "DOM", "WebWorker"],
|
||||
"target": "ESNext",
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"typeRoots": [ "./types", "./node_modules/@types"]
|
||||
"typeRoots": [ "./types", "./node_modules/@types"],
|
||||
"types": [
|
||||
"vite/client",
|
||||
"vite-plugin-compile-time/client"
|
||||
]
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
|
|
45
vite.config.ts
Normal file
45
vite.config.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import path from 'path';
|
||||
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vite';
|
||||
import compileTime from 'vite-plugin-compile-time';
|
||||
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||
import vitePluginRequire from 'vite-plugin-require';
|
||||
import { viteStaticCopy } from 'vite-plugin-static-copy';
|
||||
|
||||
export default defineConfig({
|
||||
root: 'app',
|
||||
build: {
|
||||
// Relative to the root
|
||||
outDir: '../static',
|
||||
assetsDir: 'packs',
|
||||
},
|
||||
plugins: [
|
||||
// @ts-ignore
|
||||
vitePluginRequire.default(),
|
||||
createHtmlPlugin({
|
||||
template: 'index.html',
|
||||
}),
|
||||
react({
|
||||
// Use React plugin in all *.jsx and *.tsx files
|
||||
include: '**/*.{jsx,tsx}',
|
||||
// babel: {
|
||||
// configFile: './babel.config.cjs',
|
||||
// },
|
||||
}),
|
||||
compileTime(),
|
||||
viteStaticCopy({
|
||||
targets: [{
|
||||
src: '../node_modules/twemoji/assets/svg/*',
|
||||
dest: 'packs/emoji/',
|
||||
}],
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
alias: [
|
||||
{ find: 'soapbox', replacement: path.resolve(__dirname, 'app', 'soapbox') },
|
||||
{ find: 'assets', replacement: path.resolve(__dirname, 'app', 'assets') },
|
||||
],
|
||||
},
|
||||
assetsInclude: ['**/*.oga'],
|
||||
});
|
Loading…
Reference in a new issue