Преглед на файлове

Switch from Browserify to Webpack (#790)

Danilo Bargen преди 6 години
родител
ревизия
854f1f9e5b
променени са 25 файла, в които са добавени 643 реда и са изтрити 601 реда
  1. 4 0
      .editorconfig
  2. 1 0
      .gitignore
  3. 0 240
      LICENSE-3RD-PARTY.txt
  4. 1 1
      README.md
  5. 0 22
      dist/babelify-config.js
  6. 0 60
      dist/browserify.js
  7. 0 27
      dist/devserver.js
  8. 3 3
      dist/package.sh
  9. 0 6
      gather-licenses.sh
  10. 0 18
      header.js
  11. 1 1
      index.html
  12. 2 2
      karma.conf.js
  13. 481 194
      package-lock.json
  14. 18 14
      package.json
  15. 0 2
      src/app.ts
  16. 1 1
      src/helpers/emoji.ts
  17. 2 2
      tests/testsuite.html
  18. 0 2
      tests/ts/main.ts
  19. 1 1
      tests/ui/compose_area.html
  20. 0 3
      tests/ui/compose_area.ts
  21. 0 2
      tests/ui/main.ts
  22. 59 0
      webpack.common.js
  23. 18 0
      webpack.dev.js
  24. 39 0
      webpack.prod.js
  25. 12 0
      webpack.tests.js

+ 4 - 0
.editorconfig

@@ -12,6 +12,10 @@ charset = utf-8
 indent_style = space
 indent_size = 4
 
+[webpack.*.js]
+indent_style = space
+indent_size = 2
+
 [*.yml]
 indent_style = space
 indent_size = 2

+ 1 - 0
.gitignore

@@ -7,6 +7,7 @@
 # Generated files
 js/
 dist/*.js
+dist/*.js.map
 dist/*.tar.gz
 public/css/*.css
 public/css/*.map

+ 0 - 240
LICENSE-3RD-PARTY.txt

@@ -366,246 +366,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
-----------
-License for babel
-----------
-
-MIT License
-
-Copyright (c) 2014-2018 Sebastian McKenzie and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
-----------
-License for babel-polyfill
-----------
-
-MIT License
-
-Copyright (c) 2014-2018 Sebastian McKenzie and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
-----------
-License for babel-preset-env
-----------
-
-MIT License
-
-Copyright (c) 2014-2018 Sebastian McKenzie and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
-----------
-License for babelify
-----------
-
-Copyright (c) 2015 Sebastian McKenzie
-
-MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
-----------
-License for browserify
-----------
-
-This software is released under the MIT license:
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
----
-
-Some pieces from builtins/ taken from node core under this license:
-
-----
-
-Copyright Joyent, Inc. and other Node contributors.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to permit
-persons to whom the Software is furnished to do so, subject to the
-following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-----
-
-buffer_ieee754.js has this license in it:
-
-----
-
-Copyright (c) 2008-2015, Fair Oaks Labs, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
- * Neither the name of Fair Oaks Labs, Inc. nor the names of its contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-Modifications to writeIEEE754 to support negative zeroes made by Brian White
-
-----
-
-
-
-
-----------
-License for browserify-header
-----------
-
-Copyright (c) 2014 Ralf S. Engelschall (http://engelschall.com/)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-
-
 ----------
 License for croppie
 ----------

+ 1 - 1
README.md

@@ -73,7 +73,7 @@ Web on a server, please follow the instructions at
 
 To run unit tests:
 
-    npm run build && npm run build:unittests
+    npm run build:unittests
     firefox tests/testsuite.html
 
 To run UI tests:

+ 0 - 22
dist/babelify-config.js

@@ -1,22 +0,0 @@
-// Target a version without class support due to this issue:
-// https://stackoverflow.com/q/43307607
-// This does not mean that we support Firefox <60ESR!
-// We will increase the target again once FF52 has died out.
-const minFirefoxTarget = 44;
-
-const babelifyConfig = {
-    presets: [
-        ['@babel/preset-env', {
-            useBuiltIns: 'entry',
-            targets: {
-                firefox: minFirefoxTarget,
-                chrome: 65,
-                opera: 52,
-                safari: 11,
-            },
-        }],
-    ],
-    extensions: '.ts',
-}
-
-module.exports = babelifyConfig;

+ 0 - 60
dist/browserify.js

@@ -1,60 +0,0 @@
-/**
- * Bundle the application.
- */
-
-// Parse argument
-const requiredTargets = 'Must be one of "app", "tests:unit" or "tests:ui".';
-const target = process.argv[2];
-if (target === undefined) {
-    console.error('Missing target. ' + requiredTargets);
-    process.exit(1);
-}
-
-// Import libs
-const fs = require('fs');
-const browserify = require('browserify');
-const babelifyConfig = require('./babelify-config.js');
-
-// Choose target entry point
-let b;
-switch (target) {
-    case 'app':
-        b = browserify('./src/app.ts');
-        break;
-    case 'test:unit':
-        b = browserify('./tests/ts/main.ts');
-        break;
-    case 'test:ui':
-        b = browserify('./tests/ui/main.ts');
-        break;
-    default:
-        console.error(`Invalid target: ${target}. ${requiredTargets}`);
-        process.exit(2);
-        return;
-}
-
-// Convert TypeScript
-b.plugin('tsify');
-
-// Babelify
-b.transform('babelify', babelifyConfig);
-
-// Add header comment
-if (target === 'app') {
-    b.plugin('browserify-header', {
-        'file': 'header.js',
-    })
-}
-
-// Generate bundle
-switch (target) {
-    case 'app':
-        b.bundle().pipe(fs.createWriteStream('dist/app.js'));
-        break;
-    case 'test:unit':
-        b.bundle().pipe(fs.createWriteStream('dist/ts-tests.js'));
-        break;
-    case 'test:ui':
-        b.bundle().pipe(fs.createWriteStream('dist/ui-tests.js'));
-        break;
-}

+ 0 - 27
dist/devserver.js

@@ -1,27 +0,0 @@
-/**
- * Run the devserver.
- *
- * IMPORTANT: Configuration should match `dist/browserify.js`!
- */
-
-const budo = require('budo')
-const babelify = require('babelify')
-const babelifyConfig = require('./babelify-config.js');
-const tsify = require('tsify');
-
-budo('src/app.ts:dist/app.js', {
-    dir: ['public', '.', 'src'],
-    live: true,
-    stream: process.stdout,
-    port: 9966,
-    debug: true,
-    //browserify: {  // TODO: See #705
-    //    plugin: tsify,
-    //    transform: [babelify.configure(babelifyConfig)],
-    //},
-    browserifyArgs: ['-d', '-p', 'tsify', '-t', '[', 'babelify', '--presets', '[', '@babel/env', ']', '--extensions', '.ts', ']'],
-}).on('connect', (ev) => {
-    console.log('Server running on %s', ev.uri);
-}).on('update', (buffer) => {
-    console.log('Bundle update, %d bytes', buffer.length);
-});

+ 3 - 3
dist/package.sh

@@ -45,7 +45,7 @@ mkdir -p $DIR/{dist,partials,directives,components,node_modules,partials/messeng
 
 echo "+ Copy code..."
 cp -R index.html $DIR/
-cp -R dist/app.js $DIR/dist/
+cp -R dist/app.bundle.js $DIR/dist/
 cp -R public/* $DIR/
 cp -R troubleshoot/* $DIR/troubleshoot/
 cp -R src/partials/*.html $DIR/partials/
@@ -98,8 +98,8 @@ for target in "${targets[@]}"; do
 done
 
 echo "+ Update version number..."
-sed -i.bak -e "s/\[\[VERSION\]\]/${VERSION}/g" $DIR/index.html $DIR/troubleshoot/index.html $DIR/dist/app.js $DIR/manifest.webmanifest $DIR/browserconfig.xml $DIR/version.txt
-rm $DIR/index.html.bak $DIR/troubleshoot/index.html.bak $DIR/dist/app.js.bak $DIR/manifest.webmanifest.bak $DIR/browserconfig.xml.bak $DIR/version.txt.bak
+sed -i.bak -e "s/\[\[VERSION\]\]/${VERSION}/g" $DIR/index.html $DIR/troubleshoot/index.html $DIR/dist/app.bundle.js $DIR/manifest.webmanifest $DIR/browserconfig.xml $DIR/version.txt
+rm $DIR/index.html.bak $DIR/troubleshoot/index.html.bak $DIR/dist/app.bundle.js.bak $DIR/manifest.webmanifest.bak $DIR/browserconfig.xml.bak $DIR/version.txt.bak
 
 echo "+ Update permissions..."
 find $DIR/ -type f -exec chmod 644 {} \;

+ 0 - 6
gather-licenses.sh

@@ -16,12 +16,6 @@ LICENSE_FILES=(
     'angular-translate' 'node_modules/angular-translate/LICENSE'
     'angular-ui-router' 'node_modules/@uirouter/angularjs/LICENSE'
     'autolinker' 'node_modules/autolinker/LICENSE'
-    'babel' 'node_modules/@babel/core/LICENSE'
-    'babel-polyfill' 'node_modules/@babel/polyfill/LICENSE'
-    'babel-preset-env' 'node_modules/@babel/preset-env/LICENSE'
-    'babelify' 'node_modules/babelify/LICENSE'
-    'browserify' 'node_modules/browserify/LICENSE'
-    'browserify-header' '.licenses/browserify-header'
     'croppie' 'node_modules/croppie/LICENSE'
     'Twemoji' '.licenses/twemoji'
     'file-saver' 'node_modules/file-saver/LICENSE.md'

+ 0 - 18
header.js

@@ -1,18 +0,0 @@
-/*
-** Threema Web.
-**
-** Copyright © 2016-2019 Threema GmbH (https://threema.ch/).
-**
-** This program is free software: you can redistribute it and/or modify
-** it under the terms of the GNU Affero General Public License as
-** published by the Free Software Foundation, either version 3 of the
-** License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU Affero General Public License for more details.
-**
-** You should have received a copy of the GNU Affero General Public License
-** along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/

+ 1 - 1
index.html

@@ -138,7 +138,7 @@
     <script src="node_modules/croppie/croppie.min.js?v=[[VERSION]]"></script>
 
     <!-- App -->
-    <script src="dist/app.js?v=[[VERSION]]"></script>
+    <script src="dist/app.bundle.js?v=[[VERSION]]"></script>
 
 </body>
 </html>

+ 2 - 2
karma.conf.js

@@ -10,8 +10,8 @@ module.exports = function(config) {
             'node_modules/angular-animate/angular-animate.min.js',
             'node_modules/angular-material/angular-material.min.js',
             'node_modules/@saltyrtc/chunked-dc/dist/chunked-dc.es5.js',
-            'dist/app.js',
-            'dist/ts-tests.js',
+            'dist/app.bundle.js',
+            'dist/unittests.bundle.js',
             'tests/filters.js',
             'tests/service/message.js',
             'tests/service/mime.js',

Файловите разлики са ограничени, защото са твърде много
+ 481 - 194
package-lock.json


+ 18 - 14
package.json

@@ -4,16 +4,16 @@
   "description": "Threema Webclient",
   "scripts": {
     "build": "npm run build:js && npm run build:css",
-    "build:js": "node dist/browserify.js app",
+    "build:js": "webpack --config webpack.prod.js",
     "build:css": "node-sass -o public/css/ --output-style compressed src/sass/",
     "build:css:watch": "node-sass -w -r --source-map true --source-map-embed true -o public/css/ --output-style compressed src/sass/",
     "build:tests": "echo -e 'NOTE: Use either \"npm build:unittests\" or \"npm build:uitests\"\n' && exit 1",
-    "build:unittests": "node dist/browserify.js test:unit",
-    "build:uitests": "npm run build:css && node dist/browserify.js test:ui",
+    "build:unittests": "webpack --config webpack.tests.js",
+    "build:uitests": "npm run build:css && webpack --config webpack.tests.js",
     "dist": "npm run build && echo \"\" && node dist/build-package.js",
     "serve:live": "echo 'NOTE: serve:live command has been renamed to devserver'",
-    "devserver": "npm run build:css && concurrently --kill-others --names \"css,server\" -p name \"npm run build:css:watch\" \"node dist/devserver.js\"",
-    "testserver": "budo -d public -d . -d src -p 7777",
+    "devserver": "npm run build:css && concurrently --kill-others --names \"css,server\" -p name \"npm run build:css:watch\" \"npx webpack-dev-server --config webpack.dev.js\"",
+    "testserver": "npx webpack-dev-server --config webpack.tests.js",
     "test": "echo -e 'NOTE: Use either \"npm run test:unit\" or \"npm run test:ui\"\n' && exit 1",
     "test:unit": "npm run build:unittests && karma start --single-run --log-level=debug --colors",
     "test:ui": "npm run build:uitests && bash tests/ui/run.sh",
@@ -34,9 +34,10 @@
   "private": true,
   "homepage": "https://threema.ch/",
   "dependencies": {
-    "@babel/core": "^7.2.2",
-    "@babel/polyfill": "^7.2.5",
-    "@babel/preset-env": "^7.2.3",
+    "@babel/core": "^7.4.3",
+    "@babel/plugin-transform-runtime": "^7.4.3",
+    "@babel/preset-env": "^7.4.3",
+    "@babel/runtime": "^7.4.3",
     "@saltyrtc/client": "^0.13.2",
     "@saltyrtc/task-relayed-data": "^0.3.1",
     "@saltyrtc/task-webrtc": "^0.13.0",
@@ -60,9 +61,8 @@
     "angular-translate": "~2.18",
     "angularjs-scroll-glue": "~2.1.0",
     "autolinker": "~2.2.1",
-    "babelify": "~10.0.0",
-    "browserify": "^16.2.3",
-    "browserify-header": "^1.0.0",
+    "babel-loader": "^8.0.5",
+    "core-js": "^3.0.1",
     "croppie": "^2.6.3",
     "file-saver": "2.0.0",
     "messageformat": "^2.0.5",
@@ -70,10 +70,14 @@
     "node-sass": "^4.11.0",
     "sdp": "~2.9.0",
     "ts-events": "^3.1.5",
+    "ts-loader": "^5.3.3",
     "tsify": "^4.0.1",
     "tweetnacl": "^1.0.0",
     "twemoji": "^11.2.0",
-    "typescript": "^3.2.2",
+    "typescript": "^3.4.3",
+    "webpack": "^4.30.0",
+    "webpack-cli": "^3.3.0",
+    "webpack-merge": "^4.2.1",
     "webrtc-adapter": "^7.1.1"
   },
   "devDependencies": {
@@ -81,7 +85,6 @@
     "@types/jasmine": "^3.3.5",
     "@types/selenium-webdriver": "^3.0.14",
     "angular-mocks": "^1.7.5",
-    "budo": "^11.5.0",
     "chai": "^4.2.0",
     "concurrently": "~4.1.0",
     "geckodriver": "^1.14.1",
@@ -96,6 +99,7 @@
     "selenium-webdriver": "^4.0.0-alpha.1",
     "term-color": "^1.0.1",
     "ts-node": "^7.0.1",
-    "tslint": "~5.12"
+    "tslint": "~5.12",
+    "webpack-dev-server": "^3.3.1"
   }
 }

+ 0 - 2
src/app.ts

@@ -17,8 +17,6 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import 'regenerator-runtime/runtime';
-
 import {AsyncEvent} from 'ts-events';
 
 import './components';

+ 1 - 1
src/helpers/emoji.ts

@@ -15,7 +15,7 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import * as twemoji from 'twemoji';
+import twemoji from 'twemoji';
 
 // This file contains helper functions related to emoji.
 // Try to keep all functions pure!

+ 2 - 2
tests/testsuite.html

@@ -20,8 +20,8 @@
 
         <script src="../node_modules/@saltyrtc/chunked-dc/dist/chunked-dc.es5.js"></script>
 
-        <script src="../dist/app.js"></script>
-        <script src="../dist/ts-tests.js"></script>
+        <script src="../dist/app.bundle.js"></script>
+        <script src="../dist/unittests.bundle.js"></script>
 
         <script src="filters.js"></script>
         <script src="service/message.js"></script>

+ 0 - 2
tests/ts/main.ts

@@ -20,8 +20,6 @@
 // tslint:disable:no-reference
 /// <reference path="../../src/threema.d.ts" />
 
-import '@babel/polyfill';
-
 import './containers';
 import './crypto_helpers';
 import './emoji_helpers';

+ 1 - 1
tests/ui/compose_area.html

@@ -23,7 +23,7 @@
     <link rel="stylesheet" href="../../public/css/app.css?v=[[VERSION]]">
 
     <!-- Scripts -->
-    <script src="../../dist/ui-tests.js"></script>
+    <script src="../../dist/uitest.bundle.js"></script>
     <script>window.uiTests.initComposeArea();</script>
 </head>
 <body ng-app="uitest">

+ 0 - 3
tests/ui/compose_area.ts

@@ -12,9 +12,6 @@ import * as angular from 'angular';
 import 'angular-material';
 import 'angular-translate';
 
-// Import types
-import '../../src/threema.d';
-
 // Import dependencies
 import config from '../../src/config';
 import '../../src/directives';

+ 0 - 2
tests/ui/main.ts

@@ -3,8 +3,6 @@
  *
  * This file is part of Threema Web.
  */
-import '@babel/polyfill';
-
 import {init as initComposeArea} from './compose_area';
 
 // Expose global functions

+ 59 - 0
webpack.common.js

@@ -0,0 +1,59 @@
+const path = require('path');
+const webpack = require('webpack');
+
+// Target a version without class support due to this issue:
+// https://stackoverflow.com/q/43307607
+// This does not mean that we support Firefox <60ESR!
+// We will increase the target again once FF52 has died out.
+const minFirefoxTarget = 44;
+const babelOptions = {
+  presets: [
+    ['@babel/preset-env', {
+      corejs: 3,
+      useBuiltIns: 'entry',
+      targets: {
+        firefox: minFirefoxTarget,
+        chrome: 65,
+        opera: 52,
+        safari: 11,
+      },
+    }],
+  ],
+  plugins: [
+    ['@babel/plugin-transform-runtime', {
+      regenerator: true,
+    }],
+  ],
+};
+
+module.exports = {
+  entry: {
+    app: './src/app.ts',
+  },
+  module: {
+    rules: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        use: [
+          {loader: 'babel-loader', options: babelOptions},
+          {loader: 'ts-loader'},
+        ],
+      },
+      {
+        test: /\.js$/,
+        exclude: /node_modules/,
+        use: [
+          {loader: 'babel-loader', options: babelOptions},
+        ],
+      },
+    ],
+  },
+  resolve: {
+    extensions: ['.js', '.ts'],
+  },
+  output: {
+    path: path.resolve(__dirname, 'dist'),
+    filename: '[name].bundle.js',
+  },
+};

+ 18 - 0
webpack.dev.js

@@ -0,0 +1,18 @@
+const common = require('./webpack.common.js');
+const merge = require('webpack-merge');
+const path = require('path');
+
+module.exports = merge(common, {
+  mode: 'development',
+  devtool: 'inline-source-map',
+  devServer: {
+    contentBase: [
+      path.join(__dirname),
+      path.join(__dirname, 'public'),
+      path.join(__dirname, 'src'),
+    ],
+    publicPath: '/dist/',
+    compress: true,
+    port: 9966,
+  },
+});

+ 39 - 0
webpack.prod.js

@@ -0,0 +1,39 @@
+const common = require('./webpack.common.js');
+const merge = require('webpack-merge');
+const webpack = require('webpack');
+
+const banner = `
+Threema Web.
+
+Copyright © 2016-2019 Threema GmbH (https://threema.ch/).
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+`;
+
+module.exports = merge(common, {
+  mode: 'production',
+  devtool: 'source-map',
+  performance: {
+    hints: 'warning'
+  },
+  output: {
+    pathinfo: false
+  },
+  plugins: [
+    new webpack.DefinePlugin({"process.env.NODE_ENV": JSON.stringify("production")}),
+    new webpack.optimize.ModuleConcatenationPlugin(),
+    new webpack.NoEmitOnErrorsPlugin(),
+    new webpack.BannerPlugin({banner: banner}),
+  ],
+});

+ 12 - 0
webpack.tests.js

@@ -0,0 +1,12 @@
+const dev = require('./webpack.dev.js');
+const merge = require('webpack-merge');
+
+module.exports = merge(dev, {
+    entry: {
+        unittest: './tests/ts/main.ts',
+        uitest: './tests/ui/main.ts',
+    },
+    devServer: {
+        port: 7777,
+    },
+});

Някои файлове не бяха показани, защото твърде много файлове са промени