diff --git a/builder/dockerfile.www.build b/builder/dockerfile.www.build
new file mode 100644
index 0000000..ec2c984
--- /dev/null
+++ b/builder/dockerfile.www.build
@@ -0,0 +1,7 @@
+FROM node:15-buster
+
+COPY kasmweb/ /src/
+
+WORKDIR /src
+
+RUN npm install
diff --git a/kasmweb/app/ui.js b/kasmweb/app/ui.js
index 3f42a24..42e1f28 100644
--- a/kasmweb/app/ui.js
+++ b/kasmweb/app/ui.js
@@ -5,6 +5,16 @@
*
* See README.md for usage and integration instructions.
*/
+window._noVNC_has_module_support = true;
+window.addEventListener("load", function() {
+ if (window._noVNC_has_module_support) return;
+ var loader = document.createElement("script");
+ loader.src = "vendor/browser-es-module-loader/dist/browser-es-module-loader.js";
+ document.head.appendChild(loader);
+});
+window.addEventListener("load", function() {
+ document.getElementById("noVNC_connect_button").click();
+});
import * as Log from '../core/util/logging.js';
import _, { l10n } from './localization.js';
diff --git a/kasmweb/load.html b/kasmweb/load.html
new file mode 100644
index 0000000..c294eea
--- /dev/null
+++ b/kasmweb/load.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+ KasmVNC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Kasm encountered an error:
+
+
+
+
+
+
+ Loading statistics...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/kasmweb/package.json b/kasmweb/package.json
index 0acf78b..266a5a0 100644
--- a/kasmweb/package.json
+++ b/kasmweb/package.json
@@ -21,7 +21,9 @@
"scripts": {
"lint": "eslint app core po tests utils",
"test": "karma start karma.conf.js",
- "prepublish": "node ./utils/use_require.js --as commonjs --clean"
+ "prepublish": "node ./utils/use_require.js --as commonjs --clean",
+ "build": "webpack --config webpack.config.js",
+ "build-production": "cross-env NODE_ENV=production webpack --config webpack.config.js"
},
"repository": {
"type": "git",
@@ -40,7 +42,10 @@
},
"homepage": "https://github.com/novnc/noVNC",
"devDependencies": {
+ "@babel/core": "^7.12.10",
+ "@babel/preset-env": "^7.12.11",
"babel-core": "^6.22.1",
+ "babel-loader": "^8.2.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-import-redirect": "*",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
@@ -52,24 +57,39 @@
"babelify": "^7.3.0",
"browserify": "^13.1.0",
"chai": "^3.5.0",
+ "clean-webpack-plugin": "^3.0.0",
"commander": "^2.9.0",
+ "css-loader": "^5.0.1",
+ "css-minimizer-webpack-plugin": "^1.1.5",
"es-module-loader": "^2.1.0",
"eslint": "^4.16.0",
+ "file-loader": "^6.2.0",
"fs-extra": "^1.0.0",
+ "html-loader": "^1.3.2",
+ "html-webpack-inline-svg-plugin": "^2.3.0",
+ "html-webpack-plugin": "^4.5.0",
"jsdom": "*",
"karma": "^1.3.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.0",
"karma-sauce-launcher": "^1.0.0",
"karma-sinon-chai": "^2.0.0",
+ "mini-css-extract-plugin": "^1.3.3",
"mocha": "^3.1.2",
"node-getopt": "*",
"po2json": "*",
+ "postcss-loader": "^4.1.0",
+ "preload-webpack-plugin": "^3.0.0-beta.4",
"requirejs": "^2.3.2",
"rollup": "^0.41.4",
"rollup-plugin-node-resolve": "^2.0.0",
+ "sass": "^1.30.0",
+ "sass-loader": "^10.1.0",
"sinon": "^4.0.0",
- "sinon-chai": "^2.8.0"
+ "sinon-chai": "^2.8.0",
+ "svg-sprite-html-webpack": "^2.3.0",
+ "webpack": "^4.29.6",
+ "webpack-cli": "^3.2.3"
},
"dependencies": {},
"keywords": [
diff --git a/kasmweb/webpack.config.js b/kasmweb/webpack.config.js
new file mode 100644
index 0000000..e4f0749
--- /dev/null
+++ b/kasmweb/webpack.config.js
@@ -0,0 +1,138 @@
+const path = require('path');
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+
+const HtmlWebpackInlineSVGPlugin = require('html-webpack-inline-svg-plugin');
+const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+// const SvgSpriteHtmlWebpackPlugin = require('svg-sprite-html-webpack');
+const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
+
+module.exports = {
+ mode: "production",
+ entry: {
+ main: './app/ui.js',
+ error_handler: './app/error-handler.js',
+ promise: './vendor/promise.js',
+ style: './app/styles/base.css'
+ },
+ output: {
+ path: path.resolve(__dirname, 'dist'),
+ filename: '[name].bundle.js'
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /(node_modules)/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['@babel/preset-env']
+ }
+ }
+ },
+ {
+ test: /\.(sa|sc|c)ss$/,
+ use: [
+ {
+ loader: MiniCssExtractPlugin.loader
+ },
+ {
+ loader: "css-loader",
+ },
+ // {
+ // loader: "postcss-loader"
+ // },
+ {
+ loader: "sass-loader",
+ options: {
+ implementation: require("sass")
+ }
+ }
+ ]
+ },
+ {
+ // Now we apply rule for images
+ test: /\.(png|jpe?g|gif|svg)$/,
+ use: [
+ {
+ // Using file-loader for these files
+ loader: "file-loader",
+
+ // In options we can set different things like format
+ // and directory to save
+ options: {
+ outputPath: 'images'
+ }
+ }
+ ]
+ },
+ {
+ // Apply rule for fonts files
+ test: /\.(woff|woff2|ttf|otf|eot)$/,
+ use: [
+ {
+ // Using file-loader too
+ loader: "file-loader",
+ options: {
+ outputPath: 'fonts'
+ }
+ }
+ ]
+ },
+ // {
+ // test: /\.svg$/,
+ // exclude: /node_modules/,
+ // use: SvgSpriteHtmlWebpackPlugin.getLoader(),
+ // }
+ ]
+ },
+ optimization: {
+ minimize: true,
+ minimizer: [
+ new CssMinimizerPlugin(),
+ ],
+ runtimeChunk: 'single',
+ splitChunks: {
+ chunks: 'all',
+ },
+ },
+ plugins: [
+ new CleanWebpackPlugin(),
+ new HtmlWebpackPlugin({
+ filename: '../index.html',
+ template: 'load.html',
+ minify: {
+ html5: true,
+ collapseWhitespace: true,
+ minifyCSS: true,
+ minifyJS: true,
+ minifyURLs: false,
+ removeAttributeQuotes: true,
+ removeComments: true, // false for Vue SSR to find app placeholder
+ removeEmptyAttributes: true,
+ removeOptionalTags: true,
+ removeRedundantAttributes: true,
+ removeScriptTypeAttributes: true,
+ removeStyleLinkTypeAttributese: true,
+ useShortDoctype: true
+ }
+ }),
+ // new SvgSpriteHtmlWebpackPlugin({
+ // append: true,
+ // includeFiles: [
+ // 'app/images/*.svg',
+ // ],
+ // generateSymbolId: function(svgFilePath, svgHash, svgContent) {
+ // return svgHash.toString();
+ // },
+ // }),
+ new HtmlWebpackInlineSVGPlugin({
+ inlineAll: true,
+ runPreEmit: true,
+ }),
+ new MiniCssExtractPlugin({
+ filename: "[name].bundle.css"
+ }),
+ ],
+};
\ No newline at end of file