From 39d109e9afe52e7a4d7db64354e7f2af2f30070f Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Wed, 1 Apr 2020 15:36:37 +0200 Subject: [PATCH] Made the shared app workable for the native client --- client/js/index.ts | 4 + file.ts | 405 ++++++++++--------------- loader/app/index.ts | 5 +- loader/app/loader/loader.ts | 15 +- loader/app/{ => targets}/app.ts | 83 +++-- loader/app/{ => targets}/certaccept.ts | 2 +- loader/webpack.config.js | 11 +- package.json | 6 +- shared/backend.d/audio/player.d.ts | 4 - shared/js/main.ts | 3 +- web/js/index.ts | 4 +- webpack-client.config.ts | 28 ++ webpack-web.config.ts | 115 +++++++ webpack.config.ts | 21 +- 14 files changed, 378 insertions(+), 328 deletions(-) create mode 100644 client/js/index.ts rename loader/app/{ => targets}/app.ts (86%) rename loader/app/{ => targets}/certaccept.ts (98%) create mode 100644 webpack-client.config.ts create mode 100644 webpack-web.config.ts diff --git a/client/js/index.ts b/client/js/index.ts new file mode 100644 index 00000000..6805f46c --- /dev/null +++ b/client/js/index.ts @@ -0,0 +1,4 @@ +declare const __webpack_require__; +window["shared-require"] = __webpack_require__; +/* firstly assign the shared-require */ +setTimeout(() => require("tc-shared/main"), 0); \ No newline at end of file diff --git a/file.ts b/file.ts index 5a0a578f..c355595f 100644 --- a/file.ts +++ b/file.ts @@ -38,60 +38,24 @@ const APP_FILE_LIST_SHARED_SOURCE: ProjectResource[] = [ "local-path": "./shared/html/" }, - { /* javascript loader */ - "type": "js", - "search-pattern": /.*\.js$/, - "build-target": "dev", - "path": "loader/", - "local-path": "./shared/loader/" - }, - { /* javascript loader for releases */ + { /* javascript files as manifest.json */ "type": "js", - "search-pattern": /.*loader_[\S]+.min.js$/, - "build-target": "rel", - - "path": "loader/", - "local-path": "./shared/generated/" - }, - - { /* shared javascript files (WebRTC adapter) */ - "type": "js", - "search-pattern": /.*\.js$/, + "search-pattern": /.*$/, "build-target": "dev|rel", - "path": "adapter/", - "local-path": "./shared/adapter/" - }, - - { /* shared javascript files (development mode only) */ - "type": "js", - "search-pattern": /.*\.js$/, - "search-exclude": /(.*\/)?workers\/.*/, - "build-target": "dev", - "path": "js/", - "local-path": "./shared/js/" + "local-path": "./dist/" }, - { /* shared javascript mapping files (development mode only) */ + { /* loader javascript file */ "type": "js", - "search-pattern": /.*\.(js.map|ts)$/, - "search-exclude": /(.*\/)?workers\/.*/, - "build-target": "dev", - - "path": "js/", - "local-path": "./shared/js/", - "req-parm": ["--mappings"] - }, - - { /* shared generated worker codec */ - "type": "js", - "search-pattern": /(WorkerPOW.js)$/, + "search-pattern": /.*$/, "build-target": "dev|rel", - "path": "js/workers/", - "local-path": "./shared/js/workers/" + "path": "js/", + "local-path": "./loader/dist/" }, + { /* shared developer single css files */ "type": "css", "search-pattern": /.*\.css$/, @@ -156,14 +120,6 @@ const APP_FILE_LIST_SHARED_SOURCE: ProjectResource[] = [ "path": "img/", "local-path": "./shared/img/" - }, - { /* own webassembly files */ - "type": "wasm", - "search-pattern": /.*\.(wasm)/, - "build-target": "dev|rel", - - "path": "wat/", - "local-path": "./shared/wat/" } ]; @@ -204,28 +160,7 @@ const APP_FILE_LIST_CLIENT_SOURCE: ProjectResource[] = [ "path": "js/", "local-path": "./client/js/" - }, - - /* release specific */ - { /* web merged javascript files (shared inclusive) */ - "client-only": true, - "type": "js", - "search-pattern": /.*\.js$/, - "build-target": "rel", - - "path": "js/", - "local-path": "./client/generated/" - }, - { /* Add the shared generated files. Exclude the shared file because we're including it already */ - "client-only": true, - "type": "js", - "search-pattern": /.*\.js$/, - "search-exclude": /shared\.js(.map)?$/, - "build-target": "rel", - - "path": "js/", - "local-path": "./shared/generated/" - }, + } ]; const APP_FILE_LIST_WEB_SOURCE: ProjectResource[] = [ @@ -238,42 +173,6 @@ const APP_FILE_LIST_WEB_SOURCE: ProjectResource[] = [ "path": "wasm/", "local-path": "./asm/generated/" }, - { /* generated assembly javascript files */ - "web-only": true, - "type": "js", - "search-pattern": /.*\.(js)/, - "build-target": "dev|rel", - - "path": "wasm/", - "local-path": "./asm/generated/" - }, - { /* web generated worker codec */ - "web-only": true, - "type": "js", - "search-pattern": /(WorkerCodec.js)$/, - "build-target": "dev|rel", - - "path": "js/workers/", - "local-path": "./web/js/workers/" - }, - { /* web javascript files (development mode only) */ - "web-only": true, - "type": "js", - "search-pattern": /.*\.js$/, - "build-target": "dev", - - "path": "js/", - "local-path": "./web/js/" - }, - { /* web merged javascript files (shared inclusive) */ - "web-only": true, - "type": "js", - "search-pattern": /client(\.min)?\.js$/, - "build-target": "rel", - - "path": "js/", - "local-path": "./web/generated/" - }, { /* web css files */ "web-only": true, "type": "css", @@ -303,6 +202,7 @@ const APP_FILE_LIST_WEB_SOURCE: ProjectResource[] = [ } ]; +//TODO: This isn't needed anymore const APP_FILE_LIST_WEB_TEASPEAK: ProjectResource[] = [ /* special web.teaspeak.de only auth files */ { /* login page and api */ @@ -347,6 +247,7 @@ const APP_FILE_LIST_WEB_TEASPEAK: ProjectResource[] = [ } ]; +//FIXME: This isn't working right now const CERTACCEPT_FILE_LIST: ProjectResource[] = [ { /* html files */ "type": "html", @@ -444,7 +345,6 @@ const CLIENT_APP_FILE_LIST = [ ...APP_FILE_LIST_CLIENT_SOURCE ]; -/* const WEB_APP_FILE_LIST = [ ...APP_FILE_LIST_SHARED_SOURCE, ...APP_FILE_LIST_SHARED_VENDORS, @@ -452,146 +352,147 @@ const WEB_APP_FILE_LIST = [ ...APP_FILE_LIST_WEB_TEASPEAK, ...CERTACCEPT_FILE_LIST, ]; -*/ -const WEB_APP_FILE_LIST = [ - ...APP_FILE_LIST_SHARED_VENDORS, - { /* shared html and php files */ - "type": "html", - "search-pattern": /^.*([a-zA-Z]+)\.(html|php|json)$/, - "build-target": "dev|rel", - - "path": "./", - "local-path": "./shared/html/" - }, - { /* javascript files as manifest.json */ - "type": "js", - "search-pattern": /.*$/, - "build-target": "dev|rel", - - "path": "js/", - "local-path": "./dist/" - }, - { /* loader javascript file */ - "type": "js", - "search-pattern": /.*$/, - "build-target": "dev|rel", - - "path": "js/", - "local-path": "./loader/dist/" - }, - { /* shared developer single css files */ - "type": "css", - "search-pattern": /.*\.css$/, - "build-target": "dev", - - "path": "css/", - "local-path": "./shared/css/" - }, - { /* shared css mapping files (development mode only) */ - "type": "css", - "search-pattern": /.*\.(css.map|scss)$/, - "build-target": "dev", - - "path": "css/", - "local-path": "./shared/css/", - "req-parm": ["--mappings"] - }, - { /* shared release css files */ - "type": "css", - "search-pattern": /.*\.css$/, - "build-target": "rel", - - "path": "css/", - "local-path": "./shared/generated/" - }, - { /* shared release css files */ - "type": "css", - "search-pattern": /.*\.css$/, - "build-target": "rel", - - "path": "css/loader/", - "local-path": "./shared/css/loader/" - }, - { /* shared release css files */ - "type": "css", - "search-pattern": /.*\.css$/, - "build-target": "dev|rel", - - "path": "css/theme/", - "local-path": "./shared/css/theme/" - }, - { /* shared sound files */ - "type": "wav", - "search-pattern": /.*\.wav$/, - "build-target": "dev|rel", - - "path": "audio/", - "local-path": "./shared/audio/" - }, - { /* shared data sound files */ - "type": "json", - "search-pattern": /.*\.json/, - "build-target": "dev|rel", - - "path": "audio/", - "local-path": "./shared/audio/" - }, - { /* shared image files */ - "type": "img", - "search-pattern": /.*\.(svg|png)/, - "build-target": "dev|rel", - - "path": "img/", - "local-path": "./shared/img/" - }, - { /* own webassembly files */ - "type": "wasm", - "search-pattern": /.*\.(wasm)/, - "build-target": "dev|rel", - - "path": "wat/", - "local-path": "./shared/wat/" - }, - /* web specific */ - { /* generated assembly files */ - "web-only": true, - "type": "wasm", - "search-pattern": /.*\.(wasm)/, - "build-target": "dev|rel", - - "path": "wasm/", - "local-path": "./asm/generated/" - }, - { /* web css files */ - "web-only": true, - "type": "css", - "search-pattern": /.*\.css$/, - "build-target": "dev|rel", - - "path": "css/", - "local-path": "./web/css/" - }, - { /* web html files */ - "web-only": true, - "type": "html", - "search-pattern": /.*\.(php|html)/, - "build-target": "dev|rel", - - "path": "./", - "local-path": "./web/html/" - }, - { /* translations */ - "web-only": true, /* Only required for the web client */ - "type": "i18n", - "search-pattern": /.*\.(translation|json)/, - "build-target": "dev|rel", - - "path": "i18n/", - "local-path": "./shared/i18n/" - } -] as any; +//const WEB_APP_FILE_LIST = [ +// ...APP_FILE_LIST_SHARED_VENDORS, +// { /* shared html and php files */ +// "type": "html", +// "search-pattern": /^.*([a-zA-Z]+)\.(html|php|json)$/, +// "build-target": "dev|rel", +// +// "path": "./", +// "local-path": "./shared/html/" +// }, +// { /* javascript files as manifest.json */ +// "type": "js", +// "search-pattern": /.*$/, +// "build-target": "dev|rel", +// +// "path": "js/", +// "local-path": "./dist/" +// }, +// { /* loader javascript file */ +// "type": "js", +// "search-pattern": /.*$/, +// "build-target": "dev|rel", +// +// "path": "js/", +// "local-path": "./loader/dist/" +// }, +// { /* shared developer single css files */ +// "type": "css", +// "search-pattern": /.*\.css$/, +// "build-target": "dev", +// +// "path": "css/", +// "local-path": "./shared/css/" +// }, +// { /* shared css mapping files (development mode only) */ +// "type": "css", +// "search-pattern": /.*\.(css.map|scss)$/, +// "build-target": "dev", +// +// "path": "css/", +// "local-path": "./shared/css/", +// "req-parm": ["--mappings"] +// }, +// { /* shared release css files */ +// "type": "css", +// "search-pattern": /.*\.css$/, +// "build-target": "rel", +// +// "path": "css/", +// "local-path": "./shared/generated/" +// }, +// { /* shared release css files */ +// "type": "css", +// "search-pattern": /.*\.css$/, +// "build-target": "rel", +// +// "path": "css/loader/", +// "local-path": "./shared/css/loader/" +// }, +// { /* shared release css files */ +// "type": "css", +// "search-pattern": /.*\.css$/, +// "build-target": "dev|rel", +// +// "path": "css/theme/", +// "local-path": "./shared/css/theme/" +// }, +// { /* shared sound files */ +// "type": "wav", +// "search-pattern": /.*\.wav$/, +// "build-target": "dev|rel", +// +// "path": "audio/", +// "local-path": "./shared/audio/" +// }, +// { /* shared data sound files */ +// "type": "json", +// "search-pattern": /.*\.json/, +// "build-target": "dev|rel", +// +// "path": "audio/", +// "local-path": "./shared/audio/" +// }, +// { /* shared image files */ +// "type": "img", +// "search-pattern": /.*\.(svg|png)/, +// "build-target": "dev|rel", +// +// "path": "img/", +// "local-path": "./shared/img/" +// }, +// { /* own webassembly files */ +// "type": "wasm", +// "search-pattern": /.*\.(wasm)/, +// "build-target": "dev|rel", +// +// "path": "wat/", +// "local-path": "./shared/wat/" +// }, +// +// +// /* web specific */ +// { /* generated assembly files */ +// "web-only": true, +// "type": "wasm", +// "search-pattern": /.*\.(wasm)/, +// "build-target": "dev|rel", +// +// "path": "wasm/", +// "local-path": "./asm/generated/" +// }, +// { /* web css files */ +// "web-only": true, +// "type": "css", +// "search-pattern": /.*\.css$/, +// "build-target": "dev|rel", +// +// "path": "css/", +// "local-path": "./web/css/" +// }, +// { /* web html files */ +// "web-only": true, +// "type": "html", +// "search-pattern": /.*\.(php|html)/, +// "build-target": "dev|rel", +// +// "path": "./", +// "local-path": "./web/html/" +// }, +// { /* translations */ +// "web-only": true, /* Only required for the web client */ +// "type": "i18n", +// "search-pattern": /.*\.(translation|json)/, +// "build-target": "dev|rel", +// +// "path": "i18n/", +// "local-path": "./shared/i18n/" +// } +//] as any; //@ts-ignore declare module "fs-extra" { @@ -857,9 +758,11 @@ namespace server { return; } else if(url.query["type"] === "file") { let p = path.join(url.query["path"] as string, url.query["name"] as string).replace(/\\/g, "/"); + if(!p.startsWith("/")) p = "/" + p; if(p.endsWith(".html")) { - const np = await generator.search_http_file(files, p, options.search_options); - if(np) p = np; + const np = await generator.search_http_file(files, p.substr(0, p.length - 5) + ".php", options.search_options); + console.log("%s => %s", p, np); + if(np) p = p.substr(0, p.length - 5) + ".php"; } serve_file(p, url.query, response); return; diff --git a/loader/app/index.ts b/loader/app/index.ts index 403f20b7..31333ab9 100644 --- a/loader/app/index.ts +++ b/loader/app/index.ts @@ -1,5 +1,6 @@ -import * as loader from "./app"; +import * as loader from "./targets/app"; import * as loader_base from "./loader/loader"; export = loader_base; -loader.run(); \ No newline at end of file +/* let the loader register himself at the window first */ +setTimeout(loader.run, 0); \ No newline at end of file diff --git a/loader/app/loader/loader.ts b/loader/app/loader/loader.ts index 4faaebcc..2b45ace1 100644 --- a/loader/app/loader/loader.ts +++ b/loader/app/loader/loader.ts @@ -118,7 +118,13 @@ export function register_task(stage: Stage, task: Task) { if(current_stage > stage) { if(config.error) console.warn("Register loading task, but it had already been finished. Executing task anyways!"); - task.function().catch(error => { + + const promise = task.function(); + if(!promise) { + console.error("Loading task %s hasn't returned a promise!", task.name); + return; + } + promise.catch(error => { if(config.error) { console.error("Failed to execute delayed loader task!"); console.log(" - %s: %o", task.name, error); @@ -160,7 +166,12 @@ export async function execute() { for(const task of current_tasks) { try { if(config.verbose) console.debug("Executing loader %s (%d)", task.name, task.priority); - promises.push(task.function().catch(error => { + const promise = task.function(); + if(!promise) { + console.error("Loading task %s hasn't returned a promise!", task.name); + continue; + } + promises.push(promise.catch(error => { errors.push({ task: task, error: error diff --git a/loader/app/app.ts b/loader/app/targets/app.ts similarity index 86% rename from loader/app/app.ts rename to loader/app/targets/app.ts index 40966be4..17e4f95a 100644 --- a/loader/app/app.ts +++ b/loader/app/targets/app.ts @@ -1,4 +1,4 @@ -import * as loader from "./loader/loader"; +import * as loader from "../loader/loader"; declare global { interface Window { @@ -36,51 +36,30 @@ interface Manifest { }[]}; } +interface BuildDefinitions { + development: boolean, + version: string +} +declare global { + const __build: BuildDefinitions; +} + /* all javascript loaders */ const loader_javascript = { detect_type: async () => { - //TODO: Detect real version! - loader.set_version({ - backend: "-", - ui: ui_version(), - debug_mode: true, - type: "web" - }); - window.native_client = false; - return; - if(window.require) { - const request = new Request("js/proto.js"); - let file_path = request.url; - if(!file_path.startsWith("file://")) - throw "Invalid file path (" + file_path + ")"; - file_path = file_path.substring(process.platform === "win32" ? 8 : 7); - - const fs = node_require('fs'); - if(fs.existsSync(file_path)) { - //type = Type.CLIENT_DEBUG; - } else { - //type = Type.CLIENT_RELEASE; - } + if(window.native_client) { + loader.set_version({ + backend: "-", + ui: ui_version(), + debug_mode: __build.development, + type: "native" + }); } else { - /* test if js/proto.js is available. If so we're in debug mode */ - const request = new XMLHttpRequest(); - request.open('GET', "js/proto.js?_ts=" + Date.now(), true); - - await new Promise((resolve, reject) => { - request.onreadystatechange = () => { - if (request.readyState === 4){ - if (request.status === 404) { - //type = Type.WEB_RELEASE; - } else { - //type = Type.WEB_DEBUG; - } - resolve(); - } - }; - request.onerror = () => { - reject("Failed to detect app type"); - }; - request.send(); + loader.set_version({ + backend: "-", + ui: ui_version(), + debug_mode: __build.development, + type: "web" }); } }, @@ -125,7 +104,12 @@ const loader_javascript = { if(manifest.version !== 1) throw "invalid manifest version"; - await loader.scripts.load_multiple(manifest.chunks["shared-app"].map(e => "js/" + e.file), { + const chunk_name = loader.version().type === "web" ? "shared-app" : "client-app"; + if(!Array.isArray(manifest.chunks[chunk_name])) { + loader.critical_error("Missing entry chunk in manifest.json", "Chunk " + chunk_name + " is missing."); + throw "missing entry chunk"; + } + await loader.scripts.load_multiple(manifest.chunks[chunk_name].map(e => "js/" + e.file), { cache_tag: undefined, max_parallel_requests: -1 }); @@ -417,18 +401,21 @@ export function run() { window["Module"] = (window["Module"] || {}) as any; /* TeaClient */ if(node_require) { + window.native_client = true; + const path = node_require("path"); const remote = node_require('electron').remote; - module.paths.push(path.join(remote.app.getAppPath(), "/modules")); - module.paths.push(path.join(path.dirname(remote.getGlobal("browser-root")), "js")); - //TODO: HERE! - const connector = node_require("renderer"); + const render_entry = path.join(remote.app.getAppPath(), "/modules/", "renderer"); + const render = node_require(render_entry); + loader.register_task(loader.Stage.INITIALIZING, { name: "teaclient initialize", - function: connector.initialize, + function: render.initialize, priority: 40 }); + } else { + window.native_client = false; } if(!loader.running()) { diff --git a/loader/app/certaccept.ts b/loader/app/targets/certaccept.ts similarity index 98% rename from loader/app/certaccept.ts rename to loader/app/targets/certaccept.ts index f3da64e9..794240c6 100644 --- a/loader/app/certaccept.ts +++ b/loader/app/targets/certaccept.ts @@ -1,4 +1,4 @@ -import * as loader from "./loader/loader"; +import * as loader from "../loader/loader"; let is_debug = false; diff --git a/loader/webpack.config.js b/loader/webpack.config.js index baddf2d6..660424df 100644 --- a/loader/webpack.config.js +++ b/loader/webpack.config.js @@ -1,7 +1,9 @@ +const webpack = require("webpack"); const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const isDevelopment = process.env.NODE_ENV === 'development'; +let isDevelopment = process.env.NODE_ENV === 'development'; +isDevelopment = true; module.exports = { entry: path.join(__dirname, "app/index.ts"), devtool: 'inline-source-map', @@ -10,6 +12,12 @@ module.exports = { new MiniCssExtractPlugin({ filename: isDevelopment ? '[name].css' : '[name].[hash].css', chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css' + }), + new webpack.DefinePlugin({ + __build: { + development: isDevelopment, + version: '0000' //TODO! + } }) ], module: { @@ -51,6 +59,7 @@ module.exports = { }, resolve: { extensions: ['.tsx', '.ts', '.js', ".scss"], + alias: { } }, output: { filename: 'loader.js', diff --git a/package.json b/package.json index 6ea49564..be69b873 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "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-file-helper && node file.js ndevelop", - "build": "webpack --config webpack.config.js", + "build-web": "webpack --config webpack-web.config.js", + "watch-web": "webpack --watch --config webpack-web.config.js", + "build-client": "webpack --config webpack-client.config.js", + "watch-client": "webpack --watch --config webpack-client.config.js", "build-loader": "webpack --config loader/webpack.config.js", - "watch": "webpack --watch", "watch-loader": "webpack --watch --config loader/webpack.config.js" }, "author": "TeaSpeak (WolverinDEV)", diff --git a/shared/backend.d/audio/player.d.ts b/shared/backend.d/audio/player.d.ts index ef63390d..13bf0c60 100644 --- a/shared/backend.d/audio/player.d.ts +++ b/shared/backend.d/audio/player.d.ts @@ -3,17 +3,13 @@ import {Device} from "tc-shared/audio/player"; export function initialize() : boolean; export function initialized() : boolean; -export function context() : AudioContext; export function get_master_volume() : number; export function set_master_volume(volume: number); -export function destination() : AudioNode; - export function on_ready(cb: () => any); export function available_devices() : Promise; export function set_device(device_id: string) : Promise; - export function current_device() : Device; export function initializeFromGesture(); \ No newline at end of file diff --git a/shared/js/main.ts b/shared/js/main.ts index 8895e7f6..995aa23e 100644 --- a/shared/js/main.ts +++ b/shared/js/main.ts @@ -29,6 +29,7 @@ import * as ppt from "tc-backend/ppt"; /* required import for init */ require("./proto").initialize(); require("./ui/elements/ContextDivider").initialize(); +require("./connection/CommandHandler"); /* else it might not get bundled because only the backends are accessing it */ const js_render = window.jsrender || $; const native_client = window.require !== undefined; @@ -233,7 +234,7 @@ interface Window { } */ -function handle_connect_request(properties: bipc.connect.ConnectRequestData, connection: ConnectionHandler) { +export function handle_connect_request(properties: bipc.connect.ConnectRequestData, connection: ConnectionHandler) { const profile_uuid = properties.profile || (profiles.default_profile() || {id: 'default'}).id; const profile = profiles.find_profile(profile_uuid) || profiles.default_profile(); const username = properties.username || profile.connect_username(); diff --git a/web/js/index.ts b/web/js/index.ts index ab15445c..9ba3f4c6 100644 --- a/web/js/index.ts +++ b/web/js/index.ts @@ -1,4 +1,4 @@ const webrtc_adapter = require("webrtc-adapter"); +/* typescript keep alive */ let _x = (webrtc_adapter || "").toString(); const tc = require("tc-shared/main"); - -console.log(webrtc_adapter); \ No newline at end of file +export = tc; \ No newline at end of file diff --git a/webpack-client.config.ts b/webpack-client.config.ts new file mode 100644 index 00000000..279fd6b1 --- /dev/null +++ b/webpack-client.config.ts @@ -0,0 +1,28 @@ +import * as path from "path"; +const config = require("./webpack.config"); + +let isDevelopment = process.env.NODE_ENV === 'development'; +isDevelopment = true; + +config.entry = { + "client-app": "./client/js/index.ts" +}; + +config.resolve.alias = { + "tc-shared": path.resolve(__dirname, "shared/js"), + /* backend hasn't declared but its available via "require()" */ + "tc-backend": path.resolve(__dirname, "shared/backend.d"), +}; + +config.externals = [ + { + "tc-loader": "window loader" + }, + (context, request: string, callback) => { + if (request.startsWith("tc-backend/")) + return callback(null, `window["backend-loader"].require("${request}")`); + callback(); + } +]; + +export = config; \ No newline at end of file diff --git a/webpack-web.config.ts b/webpack-web.config.ts new file mode 100644 index 00000000..a5b51b30 --- /dev/null +++ b/webpack-web.config.ts @@ -0,0 +1,115 @@ +import * as ts from "typescript"; +import trtransformer, {Config} from "./tools/trgen/ts_transformer"; + +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'); + +let isDevelopment = process.env.NODE_ENV === 'development'; +isDevelopment = true; +module.exports = { + entry: { + "shared-app": "./web/js/index.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") + }), + new WorkerPlugin(), + //new BundleAnalyzerPlugin() + /* + new CircularDependencyPlugin({ + //exclude: /a\.js|node_modules/, + failOnError: true, + allowAsyncCycles: false, + cwd: process.cwd(), + }) + */ + new webpack.optimize.AggressiveSplittingPlugin({ + minSize: 1024 * 8, + maxSize: 1024 * 128 + }) + ], + module: { + rules: [ + { + test: /\.s[ac]ss$/, + loader: [ + isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, + { + loader: 'css-loader', + options: { + modules: true, + sourceMap: isDevelopment + } + }, + { + loader: 'sass-loader', + options: { + sourceMap: isDevelopment + } + } + ] + }, + { + test: /\.tsx?$/, + exclude: /node_modules/, + + loader: [ + { + loader: 'ts-loader', + options: { + transpileOnly: true, + getCustomTransformers: (prog: ts.Program) => { + return { + before: [trtransformer(prog, {})] + }; + } + } + } + ] + }, + { + test: /\.was?t$/, + loader: [ + "./webpack/WatLoader.js" + ] + } + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js', ".scss"], + alias: { + "tc-shared": path.resolve(__dirname, "shared/js"), + "tc-backend/web": path.resolve(__dirname, "web/js"), + "tc-backend": path.resolve(__dirname, "web/js"), + "tc-generated/codec/opus": path.resolve(__dirname, "asm/generated/TeaWeb-Worker-Codec-Opus.js"), + //"tc-backend": path.resolve(__dirname, "shared/backend.d"), + }, + }, + externals: { + "tc-loader": "window loader" + }, + output: { + filename: '[contenthash].js', + path: path.resolve(__dirname, 'dist'), + publicPath: "js/" + }, + optimization: { + splitChunks: { }, + minimize: !isDevelopment, + minimizer: [new TerserPlugin()] + } +}; \ No newline at end of file diff --git a/webpack.config.ts b/webpack.config.ts index a5b51b30..e3719ab2 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -12,10 +12,9 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin'); let isDevelopment = process.env.NODE_ENV === 'development'; isDevelopment = true; -module.exports = { - entry: { - "shared-app": "./web/js/index.ts" - }, +export = { + entry: {}, /* will be individually set */ + devtool: isDevelopment ? "inline-source-map" : undefined, mode: isDevelopment ? "development" : "production", plugins: [ @@ -37,11 +36,11 @@ module.exports = { cwd: process.cwd(), }) */ - new webpack.optimize.AggressiveSplittingPlugin({ + isDevelopment ? undefined : new webpack.optimize.AggressiveSplittingPlugin({ minSize: 1024 * 8, maxSize: 1024 * 128 }) - ], + ].filter(e => !!e), module: { rules: [ { @@ -91,19 +90,13 @@ module.exports = { }, resolve: { extensions: ['.tsx', '.ts', '.js', ".scss"], - alias: { - "tc-shared": path.resolve(__dirname, "shared/js"), - "tc-backend/web": path.resolve(__dirname, "web/js"), - "tc-backend": path.resolve(__dirname, "web/js"), - "tc-generated/codec/opus": path.resolve(__dirname, "asm/generated/TeaWeb-Worker-Codec-Opus.js"), - //"tc-backend": path.resolve(__dirname, "shared/backend.d"), - }, + alias: { }, /* will be individually set */ }, externals: { "tc-loader": "window loader" }, output: { - filename: '[contenthash].js', + filename: isDevelopment ? '[name].js' : '[contenthash].js', path: path.resolve(__dirname, 'dist'), publicPath: "js/" },