Use git hash to break cache (#1684)

* Use git hash to break cache

* Address PR feedback

* Make hash docker agnostic

* Add trailing slash

* Update .prettierignore

Co-authored-by: Alec Armbruster <35377827+alectrocute@users.noreply.github.com>

* Remove debugging log

* implement getStaticDir util

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: Alec Armbruster <35377827+alectrocute@users.noreply.github.com>
This commit is contained in:
SleeplessOne1917 2023-06-29 10:29:33 -04:00 committed by GitHub
parent ad6db69dda
commit 751495702c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 57 deletions

View file

@ -2,3 +2,4 @@ src/shared/translations
lemmy-translations
src/assets/css/themes/*.css
stats.json
dist

View file

@ -20,6 +20,7 @@ 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"

View file

@ -8,9 +8,9 @@
"scripts": {
"analyze": "webpack --mode=none",
"prebuild:dev": "yarn clean && node generate_translations.js",
"build:dev": "webpack --mode=development",
"build:dev": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --mode=development",
"prebuild:prod": "yarn clean && node generate_translations.js",
"build:prod": "webpack --mode=production",
"build:prod": "webpack --env COMMIT_HASH=$(git rev-parse --short HEAD) --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}\"",

View file

@ -1,4 +1,5 @@
import { setupDateFns } from "@utils/app";
import { getStaticDir } from "@utils/env";
import express from "express";
import path from "path";
import process from "process";
@ -19,7 +20,7 @@ const [hostname, port] = process.env["LEMMY_UI_HOST"]
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
server.use("/static", express.static(path.resolve("./dist")));
server.use(getStaticDir(), express.static(path.resolve("./dist")));
server.use(setCacheControl);
if (!process.env["LEMMY_UI_DISABLE_CSP"] && !process.env["LEMMY_UI_DEBUG"]) {

View file

@ -1,3 +1,4 @@
import { getStaticDir } from "@utils/env";
import { Helmet } from "inferno-helmet";
import { renderToString } from "inferno-server";
import serialize from "serialize-javascript";
@ -87,7 +88,7 @@ export async function createSsrHtml(
<link rel="apple-touch-startup-image" href=${appleTouchIcon} />
<!-- Styles -->
<link rel="stylesheet" type="text/css" href="/static/styles/styles.css" />
<link rel="stylesheet" type="text/css" href="${getStaticDir()}/styles/styles.css" />
<!-- Current theme and more -->
${helmet.link.toString() || fallbackTheme}
@ -102,7 +103,7 @@ export async function createSsrHtml(
</noscript>
<div id='root'>${root}</div>
<script defer src='/static/js/client.js'></script>
<script defer src='${getStaticDir()}/js/client.js'></script>
</body>
</html>
`;

View file

@ -1,3 +1,4 @@
import { getStaticDir } from "@utils/env";
import classNames from "classnames";
import { Component } from "inferno";
import { I18NextService } from "../../services";
@ -23,7 +24,9 @@ export class Icon extends Component<IconProps, any> {
})}
>
<use
xlinkHref={`/static/assets/symbols.svg#icon-${this.props.icon}`}
xlinkHref={`${getStaticDir()}/assets/symbols.svg#icon-${
this.props.icon
}`}
></use>
<div className="visually-hidden">
<title>{this.props.icon}</title>

View file

@ -1,4 +1,5 @@
import { showAvatars } from "@utils/app";
import { getStaticDir } from "@utils/env";
import { hostname, isCakeDay } from "@utils/helpers";
import classNames from "classnames";
import { Component } from "inferno";
@ -88,7 +89,7 @@ export class PersonListing extends Component<PersonListingProps, any> {
!this.props.person.banned &&
showAvatars() && (
<PictrsImage
src={avatar ?? "/static/assets/icons/icon-96x96.png"}
src={avatar ?? `${getStaticDir()}/assets/icons/icon-96x96.png`}
icon
/>
)}

View file

@ -1,5 +1,7 @@
export const favIconUrl = "/static/assets/icons/favicon.svg";
export const favIconPngUrl = "/static/assets/icons/apple-touch-icon.png";
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 repoUrl = "https://github.com/LemmyNet";
export const joinLemmyUrl = "https://join-lemmy.org";

View file

@ -0,0 +1,5 @@
// Returns path to static directory, intended
// for cache-busting based on latest commit hash.
export default function getStaticDir() {
return `/static/${process.env.COMMIT_HASH}`;
}

View file

@ -6,6 +6,7 @@ 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";
@ -18,6 +19,7 @@ export {
getHttpBaseInternal,
getInternalHost,
getSecure,
getStaticDir,
httpExternalPath,
isHttps,
};

View file

@ -14,56 +14,62 @@ const banner = `
@license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0
`;
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/"),
function getBase(env) {
return {
output: {
filename: "js/server.js",
publicPath: "/",
hashFunction: "xxhash64",
},
},
performance: {
hints: false,
},
module: {
rules: [
{
test: /\.(scss|css)$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx"],
alias: {
"@": path.resolve(__dirname, "src/"),
"@utils": path.resolve(__dirname, "src/shared/utils/"),
},
{
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,
},
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,
},
},
],
},
plugins: [
new webpack.DefinePlugin({
"process.env.COMMIT_HASH": `"${env.COMMIT_HASH}"`,
}),
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 createServerConfig = (env, mode) => {
const base = getBase(env);
const config = merge({}, base, {
mode,
entry: "./src/server/index.tsx",
@ -90,13 +96,14 @@ const createServerConfig = (_env, mode) => {
return config;
};
const createClientConfig = (_env, mode) => {
const createClientConfig = (env, mode) => {
const base = getBase(env);
const config = merge({}, base, {
mode,
entry: "./src/client/index.tsx",
output: {
filename: "js/client.js",
publicPath: "/static/",
publicPath: `/static/${env.COMMIT_HASH}/`,
},
plugins: [
...base.plugins,
@ -104,7 +111,7 @@ const createClientConfig = (_env, mode) => {
enableInDevelopment: mode !== "development", // this may seem counterintuitive, but it is correct
workbox: {
modifyURLPrefix: {
"/": "/static/",
"/": `/static/${env.COMMIT_HASH}/`,
},
cacheId: "lemmy",
include: [/(assets|styles|js)\/.+\..+$/g],