Applied required changes to the automatic build system

master
WolverinDEV 2021-03-17 19:41:51 +01:00
parent 65dc29a229
commit ecf12c788e
24 changed files with 172 additions and 248 deletions

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ node_modules/
# Some build output
/dist/
/dist-package/
/declarations/
/travis-build/

View File

@ -1,4 +1,9 @@
# Changelog:
* **17.03.21**
- Updated from webpack 4 to webpack 5
- Reworked the client build process
- Using webpack dev server from now on
* **14.03.21**
- Enchanted the bookmark system
- Added support for auto connect on startup

View File

@ -31,7 +31,7 @@ export async function loadManifest() : Promise<TeaManifest> {
}
try {
const response = await fetch(config.baseUrl + "js/manifest.json?_date=" + Date.now());
const response = await fetch(config.baseUrl + "/manifest.json?_date=" + Date.now());
if(!response.ok) throw response.status + " " + response.statusText;
manifest = await response.json();
@ -56,7 +56,7 @@ export async function loadManifestTarget(chunkName: string, taskId: number) {
modules: manifest.chunks[chunkName].modules
});
loader.style.load_multiple(manifest.chunks[chunkName].css_files.map(e => "js/" + e.file), {
loader.style.load_multiple(manifest.chunks[chunkName].css_files.map(e => e.file), {
cache_tag: undefined,
max_parallel_requests: 4
}, (entry, state) => {
@ -67,7 +67,7 @@ export async function loadManifestTarget(chunkName: string, taskId: number) {
loader.setCurrentTaskName(taskId, script_name(entry, false));
});
await loader.scripts.load_multiple(manifest.chunks[chunkName].files.map(e => "js/" + e.file), {
await loader.scripts.load_multiple(manifest.chunks[chunkName].files.map(e => e.file), {
cache_tag: undefined,
max_parallel_requests: 4
}, (script, state) => {

24
package-lock.json generated
View File

@ -3700,6 +3700,12 @@
"node-releases": "^1.1.58"
}
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
"buffer-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
@ -19518,11 +19524,29 @@
"camelcase": "^3.0.0"
}
},
"yazl": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
"integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3"
}
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
},
"zip-webpack-plugin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/zip-webpack-plugin/-/zip-webpack-plugin-4.0.1.tgz",
"integrity": "sha512-G041Q4qUaog44Ynit6gs4o+o3JIv0WWfOLvc8Q3IxvPfuqd2KBHhpJWAXUB9Cm1JcWHTIOp9vS3oGMWa1p1Ehw==",
"dev": true,
"requires": {
"yazl": "^2.5.1"
}
}
}
}

View File

@ -85,7 +85,8 @@
"webpack-bundle-analyzer": "^3.6.1",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2",
"webpack-svg-sprite-generator": "^5.0.2"
"webpack-svg-sprite-generator": "^5.0.2",
"zip-webpack-plugin": "^4.0.1"
},
"repository": {
"type": "git",

View File

@ -49,32 +49,18 @@ if [[ $_exit_code -ne 0 ]]; then
exit 1
fi
echo "Generating style files"
npm run compile-scss; _exit_code=$?
if [[ $_exit_code -ne 0 ]]; then
echo "Failed to generate style files"
exit 1
fi
if [[ "$build_type" == "release" ]]; then # Compile everything for release mode
NODE_ENV=production npm run build-$build_target; _exit_code=$?
NODE_ENV=production npm run build-$build_target -- --env package=1; _exit_code=$?
if [[ $_exit_code -ne 0 ]]; then
echo "Failed to build the $build_target applcation"
echo "Failed to build the $build_target application"
exit 1
fi
elif [[ "$build_type" == "development" ]]; then
NODE_ENV=development npm run build-$build_target; _exit_code=$?
NODE_ENV=development npm run build-$build_target -- --env package=1; _exit_code=$?
if [[ $_exit_code -ne 0 ]]; then
echo "Failed to build the $build_target applcation"
echo "Failed to build the $build_target application"
exit 1
fi
fi
echo "Generating environment"
node file.js generate $build_target ${build_type}; _exit_code=$?
if [[ $_exit_code -ne 0 ]]; then
echo "Failed to generate environment"
exit 1
fi
echo "$build_target builded successfully!"
echo "$build_target build successfully!"

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
BASEDIR=$(dirname "$0")
cd "$BASEDIR/../"
cd "$BASEDIR/../" || exit
# This script cleanups all generated files
function remove_if_exists() {

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
response=$(git diff-index HEAD -- . ':!asm/libraries/' ':!package-lock.json' ':!vendor/')
response=$(git diff-index HEAD -- . ':!package-lock.json' ':!vendor/')
if [[ "$response" != "" ]]; then
if [[ "$1" == "sort-tag" ]]; then
echo "0000000"

View File

@ -34,52 +34,5 @@ install_node() {
fi
}
install_rust() {
rustup_version=$(rustup --version 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "> Missing rustup, installing..."
curl https://build.travis-ci.org/files/rustup-init.sh -sSf | sh -s -- -y --default-toolchain nightly
# shellcheck disable=SC2181
[[ $? -ne 0 ]] && {
echo "> Failed to install rustup"
exit 1
}
PATH="$PATH:$HOME/.cargo/bin"
rustup_version=$(rustup --version 2>/dev/null)
echo "> Installed $rustup_version"
else
echo "> Found $rustup_version"
fi
echo "> Installing/updating the wasm32-unknown-unknown host"
rustup target add wasm32-unknown-unknown
if [[ $? -ne 0 ]]; then
echo "> Failed to install/updating the wasm target"
exit 1
fi
}
install_wasmpack() {
wasmpack_version=$(wasm-pack --version 2>/dev/null)
if [[ $? -ne 0 ]]; then
echo "> Missing wasm-pack, installing..."
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# shellcheck disable=SC2181
[[ $? -ne 0 ]] && {
echo "> Failed to install wasm-pack"
exit 1
}
wasmpack_version=$(wasm-pack --version 2>/dev/null)
echo "> Installed $wasmpack_version"
else
echo "> Found $wasmpack_version"
fi
}
install_sys_deps
install_node
install_rust
install_wasmpack

View File

@ -176,11 +176,6 @@ function execute_build_release() {
"Failed to build release" \
"./scripts/build.sh web release"
execute \
"Packaging release" \
"Failed to package release" \
"./scripts/web_package.sh release"
move_target_file
}
function execute_build_debug() {
@ -189,11 +184,6 @@ function execute_build_debug() {
"Failed to build debug" \
"./scripts/build.sh web dev"
execute \
"Packaging release" \
"Failed to package debug" \
"./scripts/web_package.sh dev"
move_target_file
}

View File

@ -86,10 +86,10 @@ for folder in "${folders[@]}"; do
[[ $? -eq 0 ]] && {
echo " Uploaded.";
uploaded_files+="$file"
uploaded_files+=("$file")
} || {
echo "Failed to generate git release"
failed_files+="$file"
failed_files+=("$file")
}
done
done

View File

@ -37,7 +37,7 @@ _exit_code=$?
echo "Failed to delete the old .zip files ($_exit_code)"
}
filename="TeaWeb-Release-$(git rev-parse --short HEAD).zip"
filename="TeaWeb-release-$(git rev-parse --short HEAD).zip"
sftp -oStrictHostKeyChecking=no -oIdentitiesOnly=yes -i /tmp/sftp_key TeaSpeak-Travis-Web@web.teaspeak.dev << EOF
put $file tmp-upload/$filename
EOF

View File

@ -1,53 +0,0 @@
#!/usr/bin/env bash
cd "$(dirname "$0")/../" || { echo "Failed to enter base directory"; exit 1; }
if [[ "$1" == "development" ]] || [[ "$1" == "dev" ]] || [[ "$1" == "dev" ]]; then
source_path="web/environment/development"
type="development"
elif [[ "$1" == "release" ]] || [[ "$1" == "rel" ]]; then
source_path="web/environment/release"
type="release"
else
if [[ $# -lt 1 ]]; then
echo "Invalid argument count!"
else
echo "Invalid option $1"
fi
echo 'Available options are: "development" or "dev", "release" or "rel"'
exit 1
fi
if [[ ! -d "$source_path" ]]; then
echo "Could not find environment! ($source_path)"
echo "Please generate it first!"
exit 1
fi
response=$(git diff-index HEAD -- . ':!asm/libraries/' ':!package-lock.json' ':!vendor/')
if [[ "$response" != "" ]]; then
echo "You're using a private modified build! Cant assign git hash!"
NAME="TeaWeb-${type}.zip"
else
NAME="TeaWeb-${type}-$(git rev-parse --short HEAD).zip"
fi
if [[ -e ${NAME} ]]; then
echo "Found old file. Deleting it."
rm -r "${NAME}"
fi
current_path=$(pwd)
cd "$source_path" || { echo "Failed to enter source path"; exit 1; }
zip -9 -r "${NAME}" ./*; _exit_code=$?
if [[ $_exit_code -ne 0 ]]; then
echo "Failed to package environment!"
exit 1
fi
cd "$current_path" || { echo "Failed to reenter source path"; exit 1; }
mv "${source_path}/${NAME}" .
echo "Release package successfully packaged!"
echo "Target file: ${NAME} ($(pwd))"

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;" xml:space="preserve" version="1.1" id="svg2"><metadata id="metadata8"><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/></cc:Work></rdf:RDF></metadata><defs id="defs6"><clipPath id="clipPath16" clipPathUnits="userSpaceOnUse"><path id="path18" d="M 0,36 36,36 36,0 0,0 0,36 Z"/></clipPath><clipPath id="clipPath28" clipPathUnits="userSpaceOnUse"><path id="path30" d="M 2,18 C 2,9.164 9.164,2 18,2 l 0,0 c 8.836,0 16,7.164 16,16 l 0,0 c 0,8.836 -7.164,16 -16,16 l 0,0 C 9.164,34 2,26.836 2,18 m 11.235,0 c 0,2.632 2.133,4.765 4.765,4.765 l 0,0 c 2.631,0 4.766,-2.133 4.766,-4.765 l 0,0 c 0,-2.631 -2.135,-4.766 -4.766,-4.766 l 0,0 c -2.632,0 -4.765,2.135 -4.765,4.766"/></clipPath></defs><g transform="matrix(1.25,0,0,-1.25,0,45)" id="g10"><g id="g12"><g clip-path="url(#clipPath16)" id="g14"><g transform="translate(18,21)" id="g20"><path id="path22" style="fill:#8899a6;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 c -1.657,0 -3,-1.343 -3,-3 0,-1.657 1.343,-3 3,-3 1.657,0 3,1.343 3,3 0,1.657 -1.343,3 -3,3 m 18,-3 c 0,-9.941 -8.059,-18 -18,-18 -9.941,0 -18,8.059 -18,18 0,9.941 8.059,18 18,18 9.941,0 18,-8.059 18,-18"/></g></g></g><g id="g24"><g clip-path="url(#clipPath28)" id="g26"><g transform="translate(18,18)" id="g32"><path id="path34" style="fill:#ccd6dd;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 -18,2 0,16 16,0 2,-18 z"/></g><g transform="translate(18,18)" id="g36"><path id="path38" style="fill:#ccd6dd;fill-opacity:1;fill-rule:nonzero;stroke:none" d="M 0,0 18,-2 18,-18 2,-18 0,0 Z"/></g><g transform="translate(18.0005,17.9995)" id="g40"><path id="path42" style="fill:#f5f8fa;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 2.124,-18.999 15.875,1 L 0,0 Z"/></g><g transform="translate(18.0005,17.9995)" id="g44"><path id="path46" style="fill:#f5f8fa;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 0,0 -18.001,18.001 16,1 L 0,0 Z"/></g></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<g>
<path transform='rotate(90, 256, 256)' d="M85.333,213.333h341.333C473.728,213.333,512,175.061,512,128s-38.272-85.333-85.333-85.333H85.333
C38.272,42.667,0,80.939,0,128S38.272,213.333,85.333,213.333z"/>
<path transform='rotate(90, 256, 256)' d="M426.667,298.667H85.333C38.272,298.667,0,336.939,0,384s38.272,85.333,85.333,85.333h341.333
C473.728,469.333,512,431.061,512,384S473.728,298.667,426.667,298.667z"/>
</g>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1021 B

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 231.2 231.2" style="enable-background:new 0 0 231.2 231.2;" xml:space="preserve">
<style type="text/css">
.st0{fill:#333333;}
</style>
<path class="st0" d="M230.5,102.8c-0.4-3.2-4.2-5.7-7.4-5.7c-10.6,0-20-6.2-23.9-15.8c-4-9.9-1.4-21.3,6.5-28.6
c2.5-2.3,2.8-6.1,0.7-8.7c-5.4-6.9-11.6-13.1-18.3-18.5c-2.6-2.1-6.5-1.8-8.8,0.7c-6.9,7.6-19.3,10.5-28.8,6.5
c-10-4.2-16.2-14.3-15.6-25.1c0.2-3.4-2.3-6.4-5.7-6.8c-8.6-1-17.3-1-26-0.1c-3.3,0.4-5.8,3.3-5.7,6.6c0.4,10.7-6,20.6-15.8,24.7
c-9.5,3.9-21.7,1-28.6-6.5c-2.3-2.5-6.1-2.8-8.7-0.7c-6.9,5.4-13.2,11.7-18.7,18.5c-2.1,2.7-1.8,6.5,0.7,8.8
c8,7.3,10.6,18.9,6.5,28.8c-4,9.5-13.9,15.6-25.2,15.6c-3.7-0.1-6.3,2.3-6.7,5.7c-1,8.7-1,17.5,0,26.3c0.4,3.3,4.3,5.7,7.6,5.7
c10.1-0.3,19.7,6,23.8,15.8c4,9.9,1.4,21.3-6.5,28.6c-2.5,2.3-2.8,6.1-0.7,8.7c5.4,6.8,11.5,13.1,18.3,18.5c2.7,2.1,6.5,1.8,8.8-0.7
c6.9-7.6,19.3-10.5,28.8-6.5c10,4.2,16.3,14.3,15.6,25.1c-0.2,3.4,2.3,6.4,5.7,6.8c4.4,0.5,8.9,0.8,13.3,0.8c4.2,0,8.5-0.2,12.7-0.7
c3.4-0.4,5.8-3.3,5.7-6.6c-0.4-10.7,6-20.6,15.8-24.7c9.5-3.9,21.8-1,28.6,6.5c2.3,2.5,6.1,2.8,8.7,0.7c6.9-5.4,13.2-11.6,18.7-18.5
c2.1-2.6,1.8-6.5-0.7-8.8c-8-7.3-10.7-18.9-6.5-28.8c3.9-9.4,13.4-15.7,23.6-15.7l1.4,0c3.3,0.3,6.4-2.3,6.8-5.7
C231.5,120.4,231.5,111.5,230.5,102.8z M115.6,182.3c-36.8,0-66.7-29.8-66.7-66.7S78.8,49,115.6,49s66.7,29.8,66.7,66.7
c0,12.5-3.4,24.2-9.4,34.2l-29.2-29.2c2.1-5,3.2-10.4,3.2-16c0-10.9-4.3-21.2-12-28.9c-7.7-7.7-18-12-28.9-12
c-3.6,0-7.3,0.5-10.8,1.4c-1.5,0.4-2.8,1.7-3.2,3.2c-0.4,1.6,0.1,3.2,1.3,4.4c0,0,14.4,14.5,19.2,19.3c0.5,0.5,0.5,1.7,0.4,2.1
l0,0.3c-0.5,5.3-1.4,11.7-2.2,14.1c-0.1,0.1-0.2,0.2-0.3,0.3c-0.1,0.1-0.2,0.2-0.3,0.3c-2.5,0.8-8.9,1.7-14.3,2.2l0,0l-0.2,0.1
c0,0-0.1,0-0.2,0c-0.6,0-1.4-0.2-2.2-0.9c-5-5-18.9-18.8-18.9-18.8c-1.2-1.2-2.5-1.5-3.4-1.5c-2,0-3.8,1.4-4.3,3.5
c-3.8,14.1,0.2,29.3,10.5,39.6c7.7,7.7,18,12,28.9,12c5.6,0,11-1.1,16-3.2l29.5,29.5C141.1,178.4,128.8,182.3,115.6,182.3z"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -13,6 +13,7 @@ import {preview_image} from "tc-shared/ui/frames/image_preview";
import {joinClassList, useTr} from "tc-shared/ui/react-elements/Helper";
import {spawnContextMenu} from "tc-shared/ui/ContextMenu";
import {copyToClipboard} from "tc-shared/utils/helpers";
import ImagePlaylistNoThumbnail from "./MusicPlaylistNoThumbnail.png";
const cssStyle = require("./MusicPlaylistRenderer.scss");
@ -58,7 +59,7 @@ export const DefaultThumbnail = (_props: { type: "loading" | "none-present" }) =
return (
<img
draggable={false}
src="img/music/no-thumbnail.png"
src={ImagePlaylistNoThumbnail}
alt={useTr("loading")}
/>
);

View File

@ -1,14 +1,13 @@
import * as ts from "typescript";
import {createTransformer, deltaTranslations, TransformerConfig} from "./TsTransformer";
import {createTransformer, TransformerConfig} from "./TsTransformer";
import * as webpack from "webpack";
import {extractJsRendererTranslations} from "./JsRendererGenerator";
import * as path from "path";
export interface TranslateableWebpackPluginConfig {
assetName: string,
}
export class TranslateableWebpackPlugin {
export default class TranslateableWebpackPlugin {
private readonly config: TranslateableWebpackPluginConfig;
private readonly transformerConfig: TransformerConfig;

View File

@ -1,7 +1,7 @@
import * as path from "path";
import * as config_base from "./webpack.config";
export = () => config_base.config("client").then(config => {
export = env => config_base.config(env, "client").then(config => {
Object.assign(config.entry, {
"client-app": ["./client/app/index.ts"]
});

View File

@ -1,7 +1,7 @@
import * as path from "path";
import * as config_base from "./webpack.config";
export = () => config_base.config("web").then(config => {
export = env => config_base.config(env, "web").then(config => {
Object.assign(config.entry, {
"shared-app": ["./web/app/index.ts"],
"modal-external": ["./web/app/index-external.ts"]

View File

@ -3,18 +3,21 @@ import * as util from "util";
import * as path from "path";
import * as child_process from "child_process";
import {GeneratedAssetPlugin} from "./webpack/GeneratedAssetPlugin";
import { DefinePlugin, Configuration, } from "webpack";
import { Plugin as SvgSpriteGenerator } from "webpack-svg-sprite-generator";
const ManifestGenerator = require("./webpack/ManifestPlugin");
const HtmlWebpackInlineSourcePlugin = require("./webpack/HtmlWebpackInlineSource");
import ManifestGenerator from "./webpack/ManifestPlugin";
import HtmlWebpackInlineSourcePlugin from "./webpack/HtmlWebpackInlineSource";
import TranslateableWebpackPlugin from "./tools/trgen/WebpackPlugin";
import ZipWebpackPlugin from "zip-webpack-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";
import {TranslateableWebpackPlugin} from "./tools/trgen/WebpackPlugin";
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
import TerserPlugin from "terser-webpack-plugin";
import CopyWebpackPlugin from "copy-webpack-plugin";
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
@ -22,33 +25,57 @@ const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
export let isDevelopment = process.env.NODE_ENV === 'development';
console.log("Webpacking for %s (%s)", isDevelopment ? "development" : "production", process.env.NODE_ENV || "NODE_ENV not specified");
const generateDefinitions = async (target: string) => {
const gitRevision = fs.readFileSync(path.join(__dirname, ".git", "HEAD")).toString();
let version;
if(gitRevision.indexOf("/") === -1) {
version = (gitRevision || "0000000").substr(0, 7);
} else {
version = fs.readFileSync(path.join(__dirname, ".git", gitRevision.substr(5).trim())).toString().substr(0, 7);
interface LocalBuildInfo {
target: "client" | "web",
mode: "debug" | "release",
gitVersion: string,
gitTimestamp: number,
unixTimestamp: number,
localTimestamp: string
}
let localBuildInfo: LocalBuildInfo;
const generateLocalBuildInfo = async (target: string): Promise<LocalBuildInfo> => {
let info: LocalBuildInfo = {} as any;
info.target = target as any;
info.mode = isDevelopment ? "debug" : "release";
{
const gitRevision = fs.readFileSync(path.join(__dirname, ".git", "HEAD")).toString();
if(gitRevision.indexOf("/") === -1) {
info.gitVersion = (gitRevision || "0000000").substr(0, 7);
} else {
info.gitVersion = fs.readFileSync(path.join(__dirname, ".git", gitRevision.substr(5).trim())).toString().substr(0, 7);
}
let timestamp;
try {
const { stdout } = await util.promisify(child_process.exec)("git show -s --format=%ct");
timestamp = parseInt(stdout.toString());
if(isNaN(timestamp)) {
info.gitTimestamp = parseInt(stdout.toString());
if(isNaN(info.gitTimestamp)) {
throw "failed to parse timestamp '" + stdout.toString() + "'";
}
} catch (error) {
console.error("Failed to get commit timestamp: %o", error);
throw "failed to get commit timestamp";
}
}
info.unixTimestamp = Date.now();
info.localTimestamp = new Date().toString();
return info;
};
const generateDefinitions = async (target: string) => {
return {
"__build": {
target: JSON.stringify(target),
mode: JSON.stringify(isDevelopment ? "debug" : "release"),
version: JSON.stringify(version),
timestamp: timestamp,
version: JSON.stringify(localBuildInfo.gitVersion),
timestamp: localBuildInfo.gitTimestamp,
entry_chunk_name: JSON.stringify(target === "web" ? "shared-app" : "client-app")
} as BuildDefinitions
} as any;
@ -83,7 +110,9 @@ const generateIndexPlugin = (target: "web" | "client"): HtmlWebpackPlugin => {
return new HtmlWebpackPlugin(options);
}
export const config = async (target: "web" | "client"): Promise<Configuration & { devServer: any }> => {
export const config = async (env: any, target: "web" | "client"): Promise<Configuration & { devServer: any }> => {
localBuildInfo = await generateLocalBuildInfo(target);
const translateablePlugin = new TranslateableWebpackPlugin({ assetName: "translations.json" });
return {
@ -97,7 +126,20 @@ export const config = async (target: "web" | "client"): Promise<Configuration &
mode: isDevelopment ? "development" : "production",
plugins: [
new CleanWebpackPlugin(),
new DefinePlugin(await generateDefinitions(target)),
new GeneratedAssetPlugin({
customFiles: [
{
assetName: "buildInfo.json",
content: JSON.stringify(localBuildInfo)
}
]
}),
new ManifestGenerator({
outputFileName: "manifest.json",
context: __dirname
}),
new CopyWebpackPlugin({
patterns: [
@ -107,6 +149,7 @@ export const config = async (target: "web" | "client"): Promise<Configuration &
globOptions: {
ignore: [
'**/client-icons/**',
'**/style/**',
]
}
},
@ -121,14 +164,9 @@ export const config = async (target: "web" | "client"): Promise<Configuration &
ignoreOrder: true,
}),
new ManifestGenerator({
outputFileName: "manifest.json",
context: __dirname
}),
new SvgSpriteGenerator({
dtsOutputFolder: path.join(__dirname, "shared", "svg-sprites"),
publicPath: "/assets/",
publicPath: "/",
configurations: {
"client-icons": {
folder: path.join(__dirname, "shared", "img", "client-icons"),
@ -169,6 +207,11 @@ export const config = async (target: "web" | "client"): Promise<Configuration &
translateablePlugin,
//new BundleAnalyzerPlugin(),
env.package ? new ZipWebpackPlugin({
path: path.join(__dirname, "dist-package"),
filename: `TeaWeb-${isDevelopment ? "development" : "release"}-${localBuildInfo.gitVersion}.zip`,
}) : undefined
].filter(e => !!e),
module: {

View File

@ -0,0 +1,43 @@
import * as webpack from "webpack";
import {Compilation} from "webpack";
export interface GeneratedAsset {
assetName: string,
content: string | (() => string)
}
export interface GeneratedAssetPluginConfig {
customFiles: GeneratedAsset[]
}
export class GeneratedAssetPlugin {
readonly options: GeneratedAssetPluginConfig;
constructor(options: GeneratedAssetPluginConfig) {
this.options = options;
}
apply(compiler: webpack.Compiler) {
compiler.hooks.thisCompilation.tap({
name: "GeneratedAssetPlugin",
stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
}, compilation => {
compilation.hooks.processAssets.tap("GeneratedAssetPlugin", () => {
for(const asset of this.options.customFiles) {
let content: string;
if(typeof asset.content === "string") {
content = asset.content;
} else {
content = asset.content();
}
compilation.emitAsset(asset.assetName, new webpack.sources.RawSource(content), {
immutable: true,
hotModuleReplacement: true,
size: content.length
});
}
});
});
}
}

View File

@ -135,4 +135,4 @@ function getAssetByName (assests, assetName) {
}
}
module.exports = HtmlWebpackInlineSourcePlugin;
export = HtmlWebpackInlineSourcePlugin;