Added WebPack to the default `npm start web` starter.

App could not be started out of the box (only PHP is required)
canary
WolverinDEV 2020-04-09 19:26:56 +02:00
parent 2ef80ef84f
commit 479168c26e
5 changed files with 110 additions and 62 deletions

89
file.ts
View File

@ -753,8 +753,15 @@ namespace watcher {
const data = buffer.toString(); const data = buffer.toString();
if(this.verbose) { if(this.verbose) {
for(const line of data.split("\n")) const lines = data.split("\n");
for(let index = 0; index < lines.length; index++) {
let line = lines[index];
if(line.charAt(0) === "\r")
line = line.substr(1);
if(line === "" && index + 1 === lines.length)
break;
console.log("%s: %s", this.name, line); console.log("%s: %s", this.name, line);
}
} }
} }
@ -783,20 +790,31 @@ namespace watcher {
} }
protected start_command(): string[] { protected start_command(): string[] {
return ["npm", "run", "ttsc", "--", "-w"]; return ["npm", "run", "tsc", "--", "-w"];
} }
} }
export class SASSWatcher extends Watcher { export class SASSWatcher extends Watcher {
constructor() { constructor() {
super("SASS Watcher"); super("SASS Watcher");
this.verbose = true; this.verbose = false;
} }
protected start_command(): string[] { protected start_command(): string[] {
return ["npm", "run", "sass", "--", "--watch", ".:."]; return ["npm", "run", "sass", "--", "--watch", ".:."];
} }
} }
export class WebPackWatcher extends Watcher {
constructor() {
super("WebPack Watcher");
this.verbose = true;
}
protected start_command(): string[] {
return ["npm", "run", "watch-web"];
}
}
} }
function php_exe() : string { function php_exe() : string {
@ -836,33 +854,48 @@ async function main_develop(node: boolean, target: "client" | "web", port: numbe
if(flags.indexOf("--no-sass") == -1) if(flags.indexOf("--no-sass") == -1)
await sasswatcher.start(); await sasswatcher.start();
try { const webpackwatcher = new watcher.WebPackWatcher();
await server.launch(target === "client" ? CLIENT_APP_FILE_LIST : WEB_APP_FILE_LIST, {
port: port,
php: php_exe(),
search_options: {
source_path: __dirname,
parameter: [],
target: target,
mode: "dev",
serving: true
}
});
} catch(error) {
console.error("Failed to start server: %o", error instanceof Error ? error.message : error);
return;
}
console.log("Server started on %d", port);
console.log("To stop the session press ^K^C.");
await new Promise(resolve => process.once('SIGINT', resolve));
console.log("Stopping session.");
try { try {
await server.shutdown(); if(flags.indexOf("--no-webpack") == -1)
} catch(error) { await webpackwatcher.start();
console.warn("Failed to stop web server: %o", error instanceof Error ? error.message : error);
try {
await server.launch(target === "client" ? CLIENT_APP_FILE_LIST : WEB_APP_FILE_LIST, {
port: port,
php: php_exe(),
search_options: {
source_path: __dirname,
parameter: [],
target: target,
mode: "dev",
serving: true
}
});
} catch(error) {
console.error("Failed to start server: %o", error instanceof Error ? error.message : error);
return;
}
console.log("Server started on %d", port);
console.log("To stop the session press ^K^C.");
await new Promise(resolve => process.once('SIGINT', resolve));
console.log("Stopping session.");
try {
await server.shutdown();
} catch(error) {
console.warn("Failed to stop web server: %o", error instanceof Error ? error.message : error);
}
} catch (error) {
console.error("Failed to start WebPack watcher: %o", error instanceof Error ? error.message : error);
} finally {
try {
await webpackwatcher.stop();
} catch(error) {
console.warn("Failed to stop WebPack watcher: %o", error instanceof Error ? error.message : error);
}
} }
} catch(error) { } catch(error) {
console.error("Failed to start SASS watcher: %o", error instanceof Error ? error.message : error); console.error("Failed to start SASS watcher: %o", error instanceof Error ? error.message : error);

View File

@ -7,17 +7,19 @@
"scripts": { "scripts": {
"compile-sass": "sass --update shared/css/:shared/css/ web/css/:web/css/ client/css/:client/css/ vendor/:vendor/", "compile-sass": "sass --update shared/css/:shared/css/ web/css/:web/css/ client/css/:client/css/ vendor/:vendor/",
"compile-project-base": "tsc -p tsbaseconfig.json", "compile-project-base": "tsc -p tsbaseconfig.json",
"dtsgen": "node tools/dtsgen/index.js", "dtsgen": "node tools/dtsgen/index.js",
"trgen": "node tools/trgen/index.js", "trgen": "node tools/trgen/index.js",
"sass": "sass", "sass": "sass",
"csso": "csso", "tsc": "tsc",
"rebuild-structure-web-dev": "php files.php generate web dev",
"minify-web-rel-file": "terser --compress --mangle --ecma 6 --keep_classnames --keep_fnames --output", "start": "npm run compile-project-base && node file.js ndevelop",
"start": "npm run compile-file-helper && node file.js ndevelop",
"build-web": "webpack --config webpack-web.config.js", "build-web": "webpack --config webpack-web.config.js",
"watch-web": "webpack --watch --config webpack-web.config.js", "watch-web": "webpack --watch --config webpack-web.config.js",
"build-client": "webpack --config webpack-client.config.js", "build-client": "webpack --config webpack-client.config.js",
"watch-client": "webpack --watch --config webpack-client.config.js", "watch-client": "webpack --watch --config webpack-client.config.js",
"generate-i18n-gtranslate": "node shared/generate_i18n_gtranslate.js" "generate-i18n-gtranslate": "node shared/generate_i18n_gtranslate.js"
}, },
"author": "TeaSpeak (WolverinDEV)", "author": "TeaSpeak (WolverinDEV)",

View File

@ -1,21 +1,22 @@
import * as path from "path"; import * as path from "path";
import * as config_base from "./webpack.config"; import * as config_base from "./webpack.config";
const config = config_base.config("client"); export = () => config_base.config("client").then(config => {
Object.assign(config.entry, { Object.assign(config.entry, {
"client-app": "./client/js/index.ts" "client-app": "./client/js/index.ts"
}); });
Object.assign(config.resolve.alias, { Object.assign(config.resolve.alias, {
"tc-shared": path.resolve(__dirname, "shared/js"), "tc-shared": path.resolve(__dirname, "shared/js"),
/* backend hasn't declared but its available via "require()" */ /* backend hasn't declared but its available via "require()" */
"tc-backend": path.resolve(__dirname, "shared/backend.d"), "tc-backend": path.resolve(__dirname, "shared/backend.d"),
}); });
config.externals.push((context, request: string, callback) => { config.externals.push((context, request: string, callback) => {
if (request.startsWith("tc-backend/")) if (request.startsWith("tc-backend/"))
return callback(null, `window["backend-loader"].require("${request}")`); return callback(null, `window["backend-loader"].require("${request}")`);
callback(); callback();
}); });
export = config; return Promise.resolve(config);
});

View File

@ -1,16 +1,17 @@
import * as path from "path"; import * as path from "path";
import * as config_base from "./webpack.config"; import * as config_base from "./webpack.config";
const config = config_base.config("web"); export = () => config_base.config("web").then(config => {
Object.assign(config.entry, { Object.assign(config.entry, {
"shared-app": "./web/js/index.ts" "shared-app": "./web/js/index.ts"
}); });
Object.assign(config.resolve.alias, { Object.assign(config.resolve.alias, {
"tc-shared": path.resolve(__dirname, "shared/js"), "tc-shared": path.resolve(__dirname, "shared/js"),
"tc-backend/web": path.resolve(__dirname, "web/js"), "tc-backend/web": path.resolve(__dirname, "web/js"),
"tc-backend": path.resolve(__dirname, "web/js"), "tc-backend": path.resolve(__dirname, "web/js"),
"tc-generated/codec/opus": path.resolve(__dirname, "web/native-codec/generated/TeaWeb-Worker-Codec-Opus.js"), "tc-generated/codec/opus": path.resolve(__dirname, "web/native-codec/generated/TeaWeb-Worker-Codec-Opus.js"),
}); });
export = config; return Promise.resolve(config);
});

View File

@ -1,6 +1,8 @@
import * as ts from "typescript"; import * as ts from "typescript";
import * as fs from "fs"; import * as fs from "fs";
import trtransformer from "./tools/trgen/ts_transformer"; import trtransformer from "./tools/trgen/ts_transformer";
import {exec} from "child_process";
import * as util from "util";
const path = require('path'); const path = require('path');
const webpack = require("webpack"); const webpack = require("webpack");
@ -13,7 +15,7 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
export let isDevelopment = process.env.NODE_ENV === 'development'; 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"); console.log("Webpacking for %s (%s)", isDevelopment ? "development" : "production", process.env.NODE_ENV || "NODE_ENV not specified");
const generate_definitions = (target: string) => { const generate_definitions = async (target: string) => {
const git_rev = fs.readFileSync(path.join(__dirname, ".git", "HEAD")).toString(); const git_rev = fs.readFileSync(path.join(__dirname, ".git", "HEAD")).toString();
let version; let version;
if(git_rev.indexOf("/") === -1) if(git_rev.indexOf("/") === -1)
@ -21,18 +23,27 @@ const generate_definitions = (target: string) => {
else else
version = fs.readFileSync(path.join(__dirname, ".git", git_rev.substr(5).trim())).toString().substr(0, 7); 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 { return {
"__build": { "__build": {
target: JSON.stringify(target), target: JSON.stringify(target),
mode: JSON.stringify(isDevelopment ? "debug" : "release"), mode: JSON.stringify(isDevelopment ? "debug" : "release"),
version: JSON.stringify(version), version: JSON.stringify(version),
timestamp: Date.now(), timestamp: timestamp,
entry_chunk_name: JSON.stringify(target === "web" ? "shared-app" : "client-app") entry_chunk_name: JSON.stringify(target === "web" ? "shared-app" : "client-app")
} as BuildDefinitions } as BuildDefinitions
} as any; } as any;
}; };
export const config = (target: "web" | "client") => { return { export const config = async (target: "web" | "client") => { return {
entry: { entry: {
"loader": "./loader/app/index.ts" "loader": "./loader/app/index.ts"
}, },
@ -63,7 +74,7 @@ export const config = (target: "web" | "client") => { return {
minSize: 1024 * 8, minSize: 1024 * 8,
maxSize: 1024 * 128 maxSize: 1024 * 128
}), }),
new webpack.DefinePlugin(generate_definitions(target)) new webpack.DefinePlugin(await generate_definitions(target))
].filter(e => !!e), ].filter(e => !!e),
module: { module: {
rules: [ rules: [