mirror of
https://github.com/ApfelTeeSaft/LiveSplitOne.git
synced 2026-08-27 03:33:40 +00:00
Even though we added the margin, some Android devices still need it to be maskable to properly understand the margin.
223 lines
8.0 KiB
JavaScript
223 lines
8.0 KiB
JavaScript
import HtmlWebpackPlugin from "html-webpack-plugin";
|
|
import HtmlInlineScriptPlugin from 'html-inline-script-webpack-plugin';
|
|
import FaviconsWebpackPlugin from "favicons-webpack-plugin";
|
|
import { CleanWebpackPlugin } from "clean-webpack-plugin";
|
|
import WorkboxPlugin from "workbox-webpack-plugin";
|
|
import ReactRefreshTypeScript from 'react-refresh-typescript';
|
|
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
|
|
import webpack from "webpack";
|
|
import { execSync } from "child_process";
|
|
import moment from "moment";
|
|
import path from "path";
|
|
import fetch from "node-fetch";
|
|
import { fileURLToPath } from 'url';
|
|
import * as sass from "sass";
|
|
|
|
function parseChangelog() {
|
|
return execSync("git log --grep \"^Changelog: \" -10")
|
|
.toString()
|
|
.split(/^commit /m)
|
|
.slice(1)
|
|
.map((commit) => {
|
|
const changelogIndex = commit.indexOf(" Changelog: ");
|
|
if (changelogIndex === -1) {
|
|
throw `Changelog not found in commit:\n${commit}`;
|
|
}
|
|
const dateString = commit.match(/^Date: (.*)$/m)?.[1];
|
|
if (!dateString) {
|
|
throw `Date not found in commit:\n${commit}`;
|
|
}
|
|
const date = moment(new Date(dateString)).utc().format("YYYY-MM-DD");
|
|
const id = commit.substring(0, commit.indexOf("\n"));
|
|
const message = commit
|
|
.substring(changelogIndex + 15)
|
|
.replaceAll("\n ", "\n")
|
|
.trim();
|
|
return {
|
|
id,
|
|
message,
|
|
date,
|
|
};
|
|
})
|
|
.filter((changelog) => changelog.message);
|
|
}
|
|
|
|
export default async (env, argv) => {
|
|
const getContributorsForRepo = async (repoName) => {
|
|
const contributorsData = await fetch(`https://api.github.com/repos/LiveSplit/${repoName}/contributors`);
|
|
return contributorsData.json();
|
|
}
|
|
|
|
const lsoContributorsList = await getContributorsForRepo("LiveSplitOne");
|
|
const coreContributorsList = await getContributorsForRepo("livesplit-core");
|
|
|
|
const coreContributorsMap = {};
|
|
for (const coreContributor of coreContributorsList) {
|
|
if (coreContributor.type === "User" && !coreContributor.login.includes("dependabot")) {
|
|
coreContributorsMap[coreContributor.login] = coreContributor;
|
|
}
|
|
}
|
|
|
|
for (let lsoContributor of lsoContributorsList) {
|
|
const existingContributor = coreContributorsMap[lsoContributor.login];
|
|
if (existingContributor) {
|
|
existingContributor.contributions += lsoContributor.contributions;
|
|
} else if (lsoContributor.type === "User" && !lsoContributor.login.includes("dependabot")) {
|
|
coreContributorsMap[lsoContributor.login] = lsoContributor;
|
|
}
|
|
}
|
|
|
|
const contributorsList = Object.values(coreContributorsMap)
|
|
// Sort by contributions, but fallback to alphabetical order for the
|
|
// same amount of contributions
|
|
.sort((a, b) => a.login > b.login ? 1 : b.login > a.login ? -1 : 0)
|
|
.sort((a, b) => b.contributions - a.contributions)
|
|
.map((user) => {
|
|
return { id: user.id, name: user.login };
|
|
});
|
|
const commitHash = execSync("git rev-parse --short HEAD").toString();
|
|
const date = moment.utc().format("YYYY-MM-DD kk:mm:ss z");
|
|
|
|
const changelog = parseChangelog();
|
|
|
|
const basePath = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
const isProduction = argv.mode === "production";
|
|
const distPath = path.join(basePath, "dist");
|
|
|
|
return {
|
|
entry: {
|
|
"bundle": ["./src/index.tsx"],
|
|
},
|
|
output: {
|
|
filename: "[name].js",
|
|
path: distPath,
|
|
publicPath: '',
|
|
},
|
|
|
|
devtool: isProduction ? undefined : "source-map",
|
|
|
|
devServer: {
|
|
port: 8080,
|
|
hot: true
|
|
},
|
|
|
|
resolve: {
|
|
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js", ".json", ".wasm"],
|
|
},
|
|
|
|
plugins: [
|
|
...(isProduction ? [new CleanWebpackPlugin()] : []),
|
|
new FaviconsWebpackPlugin({
|
|
logo: path.resolve("src/assets/icon.svg"),
|
|
inject: true,
|
|
logoMaskable: path.resolve("src/assets/maskable.svg"),
|
|
favicons: {
|
|
appName: "LiveSplit One",
|
|
appDescription: "A version of LiveSplit that works on a lot of platforms.",
|
|
developerName: "CryZe",
|
|
developerURL: "https://livesplit.org",
|
|
background: "#171717",
|
|
theme_color: "#232323",
|
|
appleStatusBarStyle: "black-translucent",
|
|
icons: {
|
|
appleIcon: {
|
|
offset: 10,
|
|
},
|
|
appleStartup: {
|
|
offset: 15,
|
|
},
|
|
windows: false,
|
|
coast: false,
|
|
yandex: false,
|
|
},
|
|
start_url: "/",
|
|
},
|
|
}),
|
|
new HtmlWebpackPlugin({
|
|
template: "./src/index.html",
|
|
}),
|
|
new webpack.DefinePlugin({
|
|
BUILD_DATE: JSON.stringify(date),
|
|
COMMIT_HASH: JSON.stringify(commitHash),
|
|
CONTRIBUTORS_LIST: JSON.stringify(contributorsList),
|
|
CHANGELOG: JSON.stringify(changelog),
|
|
}),
|
|
...(isProduction ? [
|
|
new HtmlInlineScriptPlugin({
|
|
scriptMatchPattern: ['^bundle.js$'],
|
|
}),
|
|
new WorkboxPlugin.GenerateSW({
|
|
clientsClaim: true,
|
|
skipWaiting: true,
|
|
maximumFileSizeToCacheInBytes: 100 * 1024 * 1024,
|
|
exclude: [
|
|
/^assets/,
|
|
/\.LICENSE\.txt$/,
|
|
],
|
|
|
|
runtimeCaching: [{
|
|
urlPattern: (context) => {
|
|
return self.origin === context.url.origin &&
|
|
context.url.pathname.startsWith("/assets/");
|
|
},
|
|
handler: "CacheFirst",
|
|
}],
|
|
})
|
|
] : []),
|
|
...(!isProduction ? [new ReactRefreshWebpackPlugin()] : [])
|
|
],
|
|
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.tsx?$/,
|
|
use: [
|
|
{
|
|
loader: "ts-loader",
|
|
options: {
|
|
getCustomTransformers: () => ({
|
|
before: [!isProduction && ReactRefreshTypeScript()].filter(Boolean),
|
|
}),
|
|
transpileOnly: !isProduction,
|
|
},
|
|
},
|
|
],
|
|
exclude: "/node_modules",
|
|
},
|
|
{
|
|
test: /\.(s?)css$/,
|
|
use: [
|
|
"style-loader",
|
|
{
|
|
loader: "css-loader",
|
|
options: {
|
|
importLoaders: 1,
|
|
modules: "icss",
|
|
},
|
|
},
|
|
{
|
|
loader: "sass-loader",
|
|
options: {
|
|
// Prefer `dart-sass`
|
|
implementation: sass,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(png|jpg|gif|woff|ico|svg)$/,
|
|
type: 'asset/resource'
|
|
},
|
|
],
|
|
},
|
|
|
|
experiments: {
|
|
syncWebAssembly: true,
|
|
topLevelAwait: true,
|
|
},
|
|
|
|
mode: isProduction ? "production" : "development",
|
|
};
|
|
};
|