Refactor extension to webpack

This change is the biggest in the history of the project. The entire
project has been refactored so it is built with webpack.

This involves:
- Creating webpack and npm config files.
- Fixing some bugs in the code due to the fact that webpack uses strict
mode.
- Merging some pieces of code which were shared throughout the codebase
(not exhaustive, more work should be done in this direction).
- Splitting the console_inject.js file into separate files (it had 1000+
lines).
- Adapting all the build-related files (Makefile, bash scripts, etc.)
- Changing the docs to explain the new build process.
- Changing the Zuul playbook/roles to adapt to the new build process.

Change-Id: I16476d47825461c3a318b3f1a1eddb06b2df2e89
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..6843f0d
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,83 @@
+const {CleanWebpackPlugin} = require('clean-webpack-plugin');
+const path = require('path');
+const json5 = require('json5');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const WebpackShellPluginNext = require('webpack-shell-plugin-next');
+
+module.exports = (env, args) => {
+  let entry = {
+    // Content scripts
+    communityConsoleMain: './src/contentScripts/communityConsole/main.js',
+    communityConsoleStart: './src/contentScripts/communityConsole/start.js',
+    publicForum: './src/contentScripts/publicForum.js',
+    publicThread: './src/contentScripts/publicThread.js',
+    profile: './src/contentScripts/profile.js',
+    profileIndicator: './src/contentScripts/profileIndicator.js',
+
+    // Injected JS
+    profileIndicatorInject: './src/injections/profileIndicator.js',
+    batchLockInject: './src/injections/batchLock.js',
+
+    // Options page
+    optionsCommon: './src/optionsCommon.js',
+  };
+
+  // Background script (or service worker for MV3)
+  if (env.browser_target == 'chromium_mv3')
+    entry.sw = './src/sw.js';
+  else
+    entry.background = './src/background.js';
+
+  let outputPath = path.join(__dirname, 'dist', env.browser_target);
+
+  return {
+    entry,
+    output: {
+      filename: '[name].bundle.js',
+      path: outputPath,
+      clean: {
+        keep(asset) {
+          return asset.includes('static/') || asset.includes('manifest.json') ||
+              asset.includes('LICENSE') || asset.includes('_locales');
+        },
+      },
+    },
+    plugins: [
+      new CleanWebpackPlugin(),
+      new WebpackShellPluginNext({
+        onBuildEnd: {
+          scripts:
+              ['go run tools/generateManifest.go -dest=' +
+               path.join(outputPath, 'manifest.json') + ' ' +
+               env.browser_target]
+        }
+      }),
+      new CopyWebpackPlugin({
+        patterns: [
+          {
+            from: path.join(__dirname, 'src/static'),
+            to: outputPath,
+            globOptions: {
+              ignore: ['**/OWNERS'],
+            }
+          },
+        ]
+      }),
+    ],
+    // NOTE: Change to
+    //   (args.mode == 'production' ? 'source-map' : 'inline-source-map')
+    // once https://crbug.com/212374 is fixed.
+    devtool: 'inline-source-map',
+    module: {
+      rules: [
+        {
+          test: /\.json5$/,
+          type: 'json',
+          parser: {
+            parse: json5.parse,
+          },
+        },
+      ]
+    },
+  };
+};