text: "use strict";
  
  const gulp = require("gulp");
  
  const NODE_SRC = "./src/**/*.js";
  const NODE_DEST = "./lib";
  
  const cli = require("commander")
    .usage("<task> [options]")
    .option(
      "-e, --env <environment>",
      "Can be `prod` or `dev`. Default is `dev`",
      /^(dev|prod)$/u,
      "dev"
    )
    .option(
      "-a, --analyze",
      "Analyze client bundle. If set, `env` will be set to `prod`."
    )
    .parse(process.argv);
  
  const task = cli.args[0] || "watch";
  
  gulp.task("clean", gulp.parallel(cleanNodeScripts, cleanViewerScripts));
  gulp.task(
    "build",
    gulp.series("clean", compileNodeScripts, compileViewerScripts)
  );
  gulp.task("watch", gulp.series("build", watch));
  gulp.task("default", gulp.task("watch"));
  
  class TaskError extends Error {
    constructor(message) {
      super(message);
      this.name = "TaskError";
      // Internal Gulp flag that says "don't display error stack trace"
      this.showStack = false;
    }
  }
  
  function watch() {
    gulp
      .watch(NODE_SRC, gulp.series(cleanNodeScripts, compileNodeScripts))
      // TODO: replace with `emitErrors: false` option after https://github.com/gulpjs/glob-watcher/pull/34 will be merged
      .on("error", () => {});
  }
  
  function cleanViewerScripts() {
    const del = require("del");
    return del("public");
  }
  
  function cleanNodeScripts() {
    const del = require("del");
    return del(NODE_DEST);
  }
  
  function compileNodeScripts() {
    const babel = require("gulp-babel");
  
    return gulp.src(NODE_SRC).pipe(babel()).pipe(gulp.dest(NODE_DEST));
  }
  
  function compileViewerScripts() {
    const webpack = require("webpack");
    const config = require("./webpack.config")({
      env: cli.env,
      analyze: cli.analyze,
      watch: task === `dev`,
    });
  
    return new Promise((resolve, reject) => {
      webpack(config, (err, stats) => {
        if (cli.env === "dev") {
          if (err) {
            console.error(err);
          } else {
            console.log(stats.toString({ colors: true }));
          }
          resolve();
        } else {
          if (err) return reject(err);
  
          if (stats.hasErrors()) {
            reject(new TaskError("Webpack compilation error"));
          }
  
          console.log(stats.toString({ colors: true }));
          resolve();
        }
      });
    });
  }
  