255 lines
9.0 KiB
TypeScript
255 lines
9.0 KiB
TypeScript
import * as ts from "typescript";
|
|
import * as fs from "fs";
|
|
import trtransformer from "./tools/trgen/ts_transformer";
|
|
import {exec} from "child_process";
|
|
import * as util from "util";
|
|
import { Plugin as SvgSpriteGenerator } from "webpack-svg-sprite-generator";
|
|
|
|
import LoaderIndexGenerator = require("./loader/IndexGenerator");
|
|
import {Configuration} from "webpack";
|
|
|
|
const path = require('path');
|
|
const webpack = require("webpack");
|
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
const ManifestGenerator = require("./webpack/ManifestPlugin");
|
|
const WorkerPlugin = require('worker-plugin');
|
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
|
|
|
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 generate_definitions = async (target: string) => {
|
|
const git_rev = fs.readFileSync(path.join(__dirname, ".git", "HEAD")).toString();
|
|
let version;
|
|
if(git_rev.indexOf("/") === -1)
|
|
version = (git_rev || "0000000").substr(0, 7);
|
|
else
|
|
version = fs.readFileSync(path.join(__dirname, ".git", git_rev.substr(5).trim())).toString().substr(0, 7);
|
|
|
|
let timestamp;
|
|
try {
|
|
const { stdout } = await util.promisify(exec)("git show -s --format=%ct");
|
|
timestamp = parseInt(stdout.toString());
|
|
if(isNaN(timestamp)) throw "failed to parse timestamp '" + stdout.toString() + "'";
|
|
} catch (error) {
|
|
console.error("Failed to get commit timestamp: %o", error);
|
|
throw "failed to get commit timestamp";
|
|
}
|
|
return {
|
|
"__build": {
|
|
target: JSON.stringify(target),
|
|
mode: JSON.stringify(isDevelopment ? "debug" : "release"),
|
|
version: JSON.stringify(version),
|
|
timestamp: timestamp,
|
|
entry_chunk_name: JSON.stringify(target === "web" ? "shared-app" : "client-app")
|
|
} as BuildDefinitions
|
|
} as any;
|
|
};
|
|
|
|
const isLoaderFile = (file: string) => {
|
|
if(file.startsWith(__dirname)) {
|
|
const path = file.substr(__dirname.length).replace(/\\/g, "/");
|
|
if(path.startsWith("/loader/")) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
export const config = async (target: "web" | "client"): Promise<Configuration> => { return {
|
|
entry: {
|
|
"loader": "./loader/app/index.ts",
|
|
"modal-external": "./shared/js/ui/react-elements/external-modal/PopoutEntrypoint.ts",
|
|
"devel-main": "./shared/js/devel_main.ts"
|
|
},
|
|
|
|
devtool: isDevelopment ? "inline-source-map" : undefined,
|
|
mode: isDevelopment ? "development" : "production",
|
|
plugins: [
|
|
//new CleanWebpackPlugin(),
|
|
new MiniCssExtractPlugin({
|
|
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
|
|
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
|
|
}),
|
|
new ManifestGenerator({
|
|
file: path.join(__dirname, "dist/manifest.json"),
|
|
base: __dirname
|
|
}),
|
|
new WorkerPlugin(),
|
|
//new BundleAnalyzerPlugin(),
|
|
isDevelopment ? undefined : new webpack.optimize.AggressiveSplittingPlugin({
|
|
minSize: 1024 * 8,
|
|
maxSize: 1024 * 128
|
|
}),
|
|
new webpack.DefinePlugin(await generate_definitions(target)),
|
|
new SvgSpriteGenerator({
|
|
dtsOutputFolder: path.join(__dirname, "shared", "svg-sprites"),
|
|
configurations: {
|
|
"client-icons": {
|
|
folder: path.join(__dirname, "shared", "img", "client-icons"),
|
|
cssClassPrefix: "client-",
|
|
cssOptions: [
|
|
{
|
|
scale: 1,
|
|
selector: ".icon",
|
|
unit: "px"
|
|
},
|
|
{
|
|
scale: 1.5,
|
|
selector: ".icon_x24",
|
|
unit: "px"
|
|
},
|
|
{
|
|
scale: 2,
|
|
selector: ".icon_x32",
|
|
unit: "px"
|
|
},
|
|
{
|
|
scale: 1,
|
|
selector: ".icon_em",
|
|
unit: "em"
|
|
}
|
|
],
|
|
dtsOptions: {
|
|
enumName: "ClientIcon",
|
|
classUnionName: "ClientIconClass",
|
|
module: false
|
|
}
|
|
}
|
|
}
|
|
}),
|
|
|
|
new LoaderIndexGenerator({
|
|
buildTarget: target,
|
|
output: path.join(__dirname, "dist/index.html"),
|
|
isDevelopment: isDevelopment
|
|
})
|
|
].filter(e => !!e),
|
|
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.(s[ac]|c)ss$/,
|
|
loader: [
|
|
'style-loader',
|
|
/*
|
|
{
|
|
loader: MiniCssExtractPlugin.loader,
|
|
options: {
|
|
esModule: true,
|
|
},
|
|
},
|
|
*/
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
modules: {
|
|
mode: "local",
|
|
localIdentName: isDevelopment ? "[path][name]__[local]--[hash:base64:5]" : "[hash:base64]",
|
|
},
|
|
sourceMap: isDevelopment
|
|
}
|
|
},
|
|
{
|
|
loader: 'sass-loader',
|
|
options: {
|
|
sourceMap: isDevelopment
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
test: (module: string) => module.match(/\.tsx?$/) && !isLoaderFile(module),
|
|
exclude: /node_modules/,
|
|
|
|
loader: [
|
|
{
|
|
loader: 'ts-loader',
|
|
options: {
|
|
context: __dirname,
|
|
colors: true,
|
|
getCustomTransformers: (prog: ts.Program) => {
|
|
return {
|
|
before: [trtransformer(prog, {
|
|
optimized: false,
|
|
verbose: true,
|
|
target_file: path.join(__dirname, "dist", "translations.json")
|
|
})]
|
|
};
|
|
},
|
|
transpileOnly: isDevelopment
|
|
}
|
|
},
|
|
{
|
|
loader: "./webpack/DevelBlocks.js",
|
|
options: {
|
|
enabled: true
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
test: (module: string) => module.match(/\.tsx?$/) && isLoaderFile(module),
|
|
exclude: /(node_modules|bower_components)/,
|
|
|
|
loader: [
|
|
{
|
|
loader: "babel-loader",
|
|
options: {
|
|
presets: ["@babel/preset-env"] //Preset used for env setup
|
|
}
|
|
},
|
|
{
|
|
loader: "ts-loader",
|
|
options: {
|
|
transpileOnly: true
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
test: /\.was?t$/,
|
|
loader: [
|
|
"./webpack/WatLoader.js"
|
|
]
|
|
},
|
|
{
|
|
test: /\.svg$/,
|
|
loader: 'svg-inline-loader'
|
|
},
|
|
{
|
|
test: /ChangeLog\.md$/i,
|
|
loader: "raw-loader",
|
|
options: {
|
|
esModule: false
|
|
}
|
|
}
|
|
]
|
|
} as any,
|
|
resolve: {
|
|
extensions: ['.tsx', '.ts', '.js', ".scss", ".css", ".wasm"],
|
|
alias: {
|
|
"vendor/xbbcode": path.resolve(__dirname, "vendor/xbbcode/src")
|
|
},
|
|
},
|
|
externals: [
|
|
{"tc-loader": "window loader"}
|
|
],
|
|
output: {
|
|
filename: isDevelopment ? "[name].[contenthash].js" : "[contenthash].js",
|
|
chunkFilename: isDevelopment ? "[name].[contenthash].js" : "[contenthash].js",
|
|
path: path.resolve(__dirname, 'dist'),
|
|
publicPath: "js/"
|
|
},
|
|
performance: {
|
|
hints: false
|
|
},
|
|
optimization: {
|
|
splitChunks: {
|
|
chunks: "all"
|
|
},
|
|
minimize: !isDevelopment,
|
|
minimizer: [new TerserPlugin()]
|
|
}
|
|
}}; |