diff --git a/.prettierignore b/.prettierignore index c6145fd..004c815 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,3 @@ src/shared/translations lemmy-translations src/assets/css/themes/*.css stats.json -dist diff --git a/Dockerfile b/Dockerfile index 92b3f7e..2b36581 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ COPY .git .git RUN echo "export const VERSION = '$(git describe --tag)';" > "src/shared/version.ts" RUN yarn --production --prefer-offline -RUN NODE_OPTIONS="--max-old-space-size=8192" yarn build:prod +RUN yarn build:prod # Prune the image RUN node-prune /usr/src/app/node_modules diff --git a/dev.dockerfile b/dev.dockerfile index 881d9bc..3bfc10d 100644 --- a/dev.dockerfile +++ b/dev.dockerfile @@ -20,7 +20,6 @@ COPY generate_translations.js \ COPY lemmy-translations lemmy-translations COPY src src -COPY .git .git # Set UI version RUN echo "export const VERSION = 'dev';" > "src/shared/version.ts" diff --git a/package.json b/package.json index 9acaba4..16d3aec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lemmy-ui", - "version": "0.18.1-rc.5", + "version": "0.18.1-rc.3", "description": "An isomorphic UI for lemmy", "repository": "https://github.com/LemmyNet/lemmy-ui", "license": "AGPL-3.0", @@ -8,9 +8,9 @@ "scripts": { "analyze": "webpack --mode=none", "prebuild:dev": "yarn clean && node generate_translations.js", - "build:dev": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=development", + "build:dev": "webpack --mode=development", "prebuild:prod": "yarn clean && node generate_translations.js", - "build:prod": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=production", + "build:prod": "webpack --mode=production", "clean": "yarn run rimraf dist", "dev": "yarn build:dev --watch", "lint": "yarn translations:generate && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx \"src/**\" && prettier --check \"src/**/*.{ts,tsx,js,css,scss}\"", @@ -22,16 +22,9 @@ "translations:update": "git submodule update --remote --recursive" }, "lint-staged": { - "*.{ts,tsx,js}": [ - "prettier --write", - "eslint --fix" - ], - "*.{css, scss}": [ - "prettier --write" - ], - "package.json": [ - "sortpack" - ] + "*.{ts,tsx,js}": ["prettier --write", "eslint --fix"], + "*.{css, scss}": ["prettier --write"], + "package.json": ["sortpack"] }, "dependencies": { "@babel/plugin-proposal-decorators": "^7.21.0", diff --git a/src/server/index.tsx b/src/server/index.tsx index 458d7f0..270f33c 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -1,5 +1,4 @@ import { setupDateFns } from "@utils/app"; -import { getStaticDir } from "@utils/env"; import express from "express"; import path from "path"; import process from "process"; @@ -20,13 +19,7 @@ const [hostname, port] = process.env["LEMMY_UI_HOST"] server.use(express.json()); server.use(express.urlencoded({ extended: false })); -server.use( - getStaticDir(), - express.static(path.resolve("./dist"), { - maxAge: 24 * 60 * 60 * 1000, // 1 day - immutable: true, - }) -); +server.use("/static", express.static(path.resolve("./dist"))); server.use(setCacheControl); if (!process.env["LEMMY_UI_DISABLE_CSP"] && !process.env["LEMMY_UI_DEBUG"]) { diff --git a/src/server/middleware.ts b/src/server/middleware.ts index 235f072..9815e71 100644 --- a/src/server/middleware.ts +++ b/src/server/middleware.ts @@ -1,4 +1,4 @@ -import type { NextFunction, Request, Response } from "express"; +import type { NextFunction, Response } from "express"; import { UserService } from "../shared/services"; export function setDefaultCsp({ @@ -18,33 +18,24 @@ export function setDefaultCsp({ // Set cache-control headers. If user is logged in, set `private` to prevent storing data in // shared caches (eg nginx) and leaking of private data. If user is not logged in, allow caching -// all responses for 5 seconds to reduce load on backend and database. The specific cache +// all responses for 60 seconds to reduce load on backend and database. The specific cache // interval is rather arbitrary and could be set higher (less server load) or lower (fresher data). // // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control -export function setCacheControl( - req: Request, - res: Response, - next: NextFunction -) { +export function setCacheControl({ + res, + next, +}: { + res: Response; + next: NextFunction; +}) { const user = UserService.Instance; let caching: string; - - if ( - process.env.NODE_ENV === "production" && - (req.path.match(/\.(js|css|txt|manifest\.webmanifest)\/?$/) || - req.path.includes("/css/themelist")) - ) { - // Static content gets cached publicly for a day - caching = "public, max-age=86400"; + if (user.auth()) { + caching = "private"; } else { - if (user.auth()) { - caching = "private"; - } else { - caching = "public, max-age=5"; - } + caching = "public, max-age=60"; } - res.setHeader("Cache-Control", caching); next(); diff --git a/src/server/utils/create-ssr-html.tsx b/src/server/utils/create-ssr-html.tsx index ba85228..1377598 100644 --- a/src/server/utils/create-ssr-html.tsx +++ b/src/server/utils/create-ssr-html.tsx @@ -1,4 +1,3 @@ -import { getStaticDir } from "@utils/env"; import { Helmet } from "inferno-helmet"; import { renderToString } from "inferno-server"; import serialize from "serialize-javascript"; @@ -24,7 +23,7 @@ export async function createSsrHtml( if (!appleTouchIcon) { appleTouchIcon = site?.site_view.site.icon - ? `data:image/png;base64,${await sharp( + ? `data:image/png;base64,${sharp( await fetchIconPng(site.site_view.site.icon) ) .resize(180, 180) @@ -88,7 +87,7 @@ export async function createSsrHtml( - + ${helmet.link.toString() || fallbackTheme} @@ -103,7 +102,7 @@ export async function createSsrHtml(
${root}
- + `; diff --git a/src/shared/components/common/icon.tsx b/src/shared/components/common/icon.tsx index 92a41a3..5b6ddf8 100644 --- a/src/shared/components/common/icon.tsx +++ b/src/shared/components/common/icon.tsx @@ -1,4 +1,3 @@ -import { getStaticDir } from "@utils/env"; import classNames from "classnames"; import { Component } from "inferno"; import { I18NextService } from "../../services"; @@ -24,9 +23,7 @@ export class Icon extends Component { })} >
{this.props.icon} diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index 5e73367..5ef1a87 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -279,15 +279,13 @@ export class Home extends Component { trendingCommunitiesRes, commentsRes, postsRes, + tagline: getRandomFromList(this.state?.siteRes?.taglines ?? []) + ?.content, isIsomorphic: true, }; HomeCacheService.postsRes = postsRes; } - - this.state.tagline = getRandomFromList( - this.state?.siteRes?.taglines ?? [] - )?.content; } componentWillUnmount() { diff --git a/src/shared/components/home/tagline-form.tsx b/src/shared/components/home/tagline-form.tsx index f7cf99a..bdbe1e6 100644 --- a/src/shared/components/home/tagline-form.tsx +++ b/src/shared/components/home/tagline-form.tsx @@ -141,7 +141,7 @@ export class TaglineForm extends Component { handleEditTaglineClick(d: { i: TaglineForm; index: number }, event: any) { event.preventDefault(); - if (d.i.state.editingRow == d.index) { + if (this.state.editingRow == d.index) { d.i.setState({ editingRow: undefined }); } else { d.i.setState({ editingRow: d.index }); diff --git a/src/shared/components/person/person-listing.tsx b/src/shared/components/person/person-listing.tsx index dfc5d66..6631a8e 100644 --- a/src/shared/components/person/person-listing.tsx +++ b/src/shared/components/person/person-listing.tsx @@ -1,5 +1,4 @@ import { showAvatars } from "@utils/app"; -import { getStaticDir } from "@utils/env"; import { hostname, isCakeDay } from "@utils/helpers"; import classNames from "classnames"; import { Component } from "inferno"; @@ -89,7 +88,7 @@ export class PersonListing extends Component { !this.props.person.banned && showAvatars() && ( )} diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index 5c562a4..586403b 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -403,9 +403,8 @@ export class PostListing extends Component { createdLine() { const post_view = this.postView; - return ( -
+
diff --git a/src/shared/config.ts b/src/shared/config.ts index 58ecc08..97b28d2 100644 --- a/src/shared/config.ts +++ b/src/shared/config.ts @@ -1,7 +1,5 @@ -import { getStaticDir } from "@utils/env"; - -export const favIconUrl = `${getStaticDir()}/assets/icons/favicon.svg`; -export const favIconPngUrl = `${getStaticDir()}/assets/icons/apple-touch-icon.png`; +export const favIconUrl = "/static/assets/icons/favicon.svg"; +export const favIconPngUrl = "/static/assets/icons/apple-touch-icon.png"; export const repoUrl = "https://github.com/LemmyNet"; export const joinLemmyUrl = "https://join-lemmy.org"; diff --git a/src/shared/utils/app/is-auth-path.ts b/src/shared/utils/app/is-auth-path.ts index 5a201ac..0ec963a 100644 --- a/src/shared/utils/app/is-auth-path.ts +++ b/src/shared/utils/app/is-auth-path.ts @@ -1,5 +1,5 @@ export default function isAuthPath(pathname: string) { - return /^\/create_.*|inbox|settings|admin|reports|registration_applications/g.test( + return /create_.*|inbox|settings|admin|reports|registration_applications/g.test( pathname ); } diff --git a/src/shared/utils/env/get-static-dir.ts b/src/shared/utils/env/get-static-dir.ts deleted file mode 100644 index 1d19596..0000000 --- a/src/shared/utils/env/get-static-dir.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Returns path to static directory, intended -// for cache-busting based on latest commit hash. -export default function getStaticDir() { - return `/static/${process.env.COMMIT_HASH}`; -} diff --git a/src/shared/utils/env/index.ts b/src/shared/utils/env/index.ts index 3a9a3fe..e14c673 100644 --- a/src/shared/utils/env/index.ts +++ b/src/shared/utils/env/index.ts @@ -6,7 +6,6 @@ import getHttpBaseExternal from "./get-http-base-external"; import getHttpBaseInternal from "./get-http-base-internal"; import getInternalHost from "./get-internal-host"; import getSecure from "./get-secure"; -import getStaticDir from "./get-static-dir"; import httpExternalPath from "./http-external-path"; import isHttps from "./is-https"; @@ -19,7 +18,6 @@ export { getHttpBaseInternal, getInternalHost, getSecure, - getStaticDir, httpExternalPath, isHttps, }; diff --git a/webpack.config.js b/webpack.config.js index 0c9806d..a2b31d0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,63 +14,56 @@ const banner = ` @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0 `; -function getBase(env, mode) { - return { - output: { - filename: "js/server.js", - publicPath: "/", - hashFunction: "xxhash64", +const base = { + output: { + filename: "js/server.js", + publicPath: "/", + hashFunction: "xxhash64", + }, + resolve: { + extensions: [".js", ".jsx", ".ts", ".tsx"], + alias: { + "@": path.resolve(__dirname, "src/"), + "@utils": path.resolve(__dirname, "src/shared/utils/"), }, - resolve: { - extensions: [".js", ".jsx", ".ts", ".tsx"], - alias: { - "@": path.resolve(__dirname, "src/"), - "@utils": path.resolve(__dirname, "src/shared/utils/"), + }, + performance: { + hints: false, + }, + module: { + rules: [ + { + test: /\.(scss|css)$/i, + use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, - }, - performance: { - hints: false, - }, - module: { - rules: [ - { - test: /\.(scss|css)$/i, - use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], + { + test: /\.(js|jsx|tsx|ts)$/, // All ts and tsx files will be process by + exclude: /node_modules/, // ignore node_modules + loader: "babel-loader", + }, + // Due to some weird babel issue: https://github.com/webpack/webpack/issues/11467 + { + test: /\.m?js/, + resolve: { + fullySpecified: false, }, - { - test: /\.(js|jsx|tsx|ts)$/, // All ts and tsx files will be process by - exclude: /node_modules/, // ignore node_modules - loader: "babel-loader", - }, - // Due to some weird babel issue: https://github.com/webpack/webpack/issues/11467 - { - test: /\.m?js/, - resolve: { - fullySpecified: false, - }, - }, - ], - }, - plugins: [ - new webpack.DefinePlugin({ - "process.env.COMMIT_HASH": `"${env.COMMIT_HASH}"`, - "process.env.NODE_ENV": `"${mode}"`, - }), - new MiniCssExtractPlugin({ - filename: "styles/styles.css", - }), - new CopyPlugin({ - patterns: [{ from: "./src/assets", to: "./assets" }], - }), - new webpack.BannerPlugin({ - banner, - }), + }, ], - }; -} + }, + plugins: [ + new MiniCssExtractPlugin({ + filename: "styles/styles.css", + }), + new CopyPlugin({ + patterns: [{ from: "./src/assets", to: "./assets" }], + }), + new webpack.BannerPlugin({ + banner, + }), + ], +}; -const createServerConfig = (env, mode) => { - const base = getBase(env, mode); +const createServerConfig = (_env, mode) => { const config = merge({}, base, { mode, entry: "./src/server/index.tsx", @@ -97,14 +90,13 @@ const createServerConfig = (env, mode) => { return config; }; -const createClientConfig = (env, mode) => { - const base = getBase(env, mode); +const createClientConfig = (_env, mode) => { const config = merge({}, base, { mode, entry: "./src/client/index.tsx", output: { filename: "js/client.js", - publicPath: `/static/${env.COMMIT_HASH}/`, + publicPath: "/static/", }, plugins: [ ...base.plugins, @@ -112,7 +104,7 @@ const createClientConfig = (env, mode) => { enableInDevelopment: mode !== "development", // this may seem counterintuitive, but it is correct workbox: { modifyURLPrefix: { - "/": `/static/${env.COMMIT_HASH}/`, + "/": "/static/", }, cacheId: "lemmy", include: [/(assets|styles|js)\/.+\..+$/g],