Skip to content
Snippets Groups Projects
webpack.config.js 7.62 KiB
Newer Older
// Variables in .env will be added to process.env
require("dotenv").config();

const fs = require("fs");
const path = require("path");
const selfsigned = require("selfsigned");
const webpack = require("webpack");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
Greg Fodor's avatar
Greg Fodor committed
const CopyWebpackPlugin = require("copy-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const _ = require("lodash");

function createHTTPSConfig() {
  // Generate certs for the local webpack-dev-server.
  if (fs.existsSync(path.join(__dirname, "certs"))) {
    const key = fs.readFileSync(path.join(__dirname, "certs", "key.pem"));
    const cert = fs.readFileSync(path.join(__dirname, "certs", "cert.pem"));

    return { key, cert };
  } else {
    const pems = selfsigned.generate(
      [
        {
          name: "commonName",
          value: "localhost"
        }
      ],
      {
        days: 365,
        algorithm: "sha256",
        extensions: [
          {
            name: "subjectAltName",
            altNames: [
              {
                type: 2,
                value: "localhost"
Greg Fodor's avatar
Greg Fodor committed
                value: "hubs.local"
              }
            ]
          }
        ]
      }
    );

    fs.mkdirSync(path.join(__dirname, "certs"));
    fs.writeFileSync(path.join(__dirname, "certs", "cert.pem"), pems.cert);
    fs.writeFileSync(path.join(__dirname, "certs", "key.pem"), pems.private);

    return {
      key: pems.private,
      cert: pems.cert
    };
  }
}

class LodashTemplatePlugin {
  constructor(options) {
    this.options = options;
  }

  apply(compiler) {
    compiler.plugin("compilation", compilation => {
      compilation.plugin("html-webpack-plugin-before-html-processing", async data => {
        data.html = _.template(data.html, this.options)();
        return data;
      });
    });
  }
}

module.exports = (env, argv) => ({
    index: path.join(__dirname, "src", "index.js"),
    hub: path.join(__dirname, "src", "hub.js"),
Greg Fodor's avatar
Greg Fodor committed
    link: path.join(__dirname, "src", "link.js"),
Greg Fodor's avatar
Greg Fodor committed
    "avatar-selector": path.join(__dirname, "src", "avatar-selector.js")
    path: path.join(__dirname, "public"),
    filename: "assets/js/[name]-[chunkhash].js",
    publicPath: process.env.BASE_ASSETS_PATH || ""
  devtool: argv.mode === "production" ? "source-map" : "inline-source-map",
  devServer: {
Greg Fodor's avatar
Greg Fodor committed
    open: false,
    https: createHTTPSConfig(),
Greg Fodor's avatar
Greg Fodor committed
    host: "0.0.0.0",
    useLocalIp: true,
Greg Fodor's avatar
Greg Fodor committed
    public: "hubs.local:8080",
    port: 8080,
    headers: { "Access-Control-Allow-Origin": "*" },
    before: function(app) {
      // networked-aframe makes HEAD requests to the server for time syncing. Respond with an empty body.
      app.head("*", function(req, res, next) {
        if (req.method === "HEAD") {
Greg Fodor's avatar
Greg Fodor committed
          res.append("Date", new Date().toGMTString());
          res.send("");
        } else {
          next();
        }
      });
    }
  },
  performance: {
    // Ignore media and sourcemaps when warning about file size.
    assetFilter(assetFilename) {
Greg Fodor's avatar
Greg Fodor committed
      return !/\.(map|png|jpg|gif|glb|webm)$/.test(assetFilename);
    }
  },
  module: {
    rules: [
      {
        test: /\.html$/,
        loader: "html-loader",
        options: {
          // <a-asset-item>'s src property is overwritten with the correct transformed asset url.
          attrs: ["img:src", "a-asset-item:src", "audio:src", "source:src"],
          // You can get transformed asset urls in an html template using ${require("pathToFile.ext")}
          interpolate: "require"
        }
      },
      {
        test: /\.worker\.js$/,
        loader: "worker-loader",
        options: {
          name: "assets/js/[name]-[hash].js",
netpro2k's avatar
netpro2k committed
          publicPath: "/",
          inline: true
      {
        test: /\.js$/,
        include: [path.resolve(__dirname, "src")],
        // Exclude JS assets in node_modules because they are already transformed and often big.
        exclude: [path.resolve(__dirname, "node_modules")],
Greg Fodor's avatar
Greg Fodor committed
        loader: "babel-loader",
        query: {
          plugins: ["transform-class-properties", "transform-object-rest-spread"]
        }
Greg Fodor's avatar
Greg Fodor committed
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: [
            {
              loader: "css-loader",
              options: {
Greg Fodor's avatar
Greg Fodor committed
                name: "[path][name]-[hash].[ext]",
                localIdentName: "[name]__[local]__[hash:base64:5]",
                camelCase: true
Greg Fodor's avatar
Greg Fodor committed
              }
            },
            "sass-loader"
          ]
        })
      },
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: {
            loader: "css-loader",
            options: {
Greg Fodor's avatar
Greg Fodor committed
              name: "[path][name]-[hash].[ext]",
              localIdentName: "[name]__[local]__[hash:base64:5]",
              camelCase: true
        test: /\.(png|jpg|gif|glb|ogg|mp3|mp4|wav|woff2|svg|webm)$/,
        use: {
          loader: "file-loader",
          options: {
            // move required assets to /public and add a hash for cache busting
            name: "[path][name]-[hash].[ext]",
            // Make asset paths relative to /src
            context: path.join(__dirname, "src")
          }
        }
      }
    ]
  },
  // necessary due to https://github.com/visionmedia/debug/issues/547
  optimization: {
    minimizer: [new UglifyJsPlugin({ uglifyOptions: { compress: { collapse_vars: false } } })]
  },
  plugins: [
    // Each output page needs a HTMLWebpackPlugin entry
    new HTMLWebpackPlugin({
      filename: "index.html",
      template: path.join(__dirname, "src", "index.html"),
      // Chunks correspond with the entries you wish to include in your html template
      chunks: ["index"]
    }),
    new HTMLWebpackPlugin({
      filename: "hub.html",
      template: path.join(__dirname, "src", "hub.html"),
      chunks: ["hub"],
      inject: "head"
    }),
Greg Fodor's avatar
Greg Fodor committed
    new HTMLWebpackPlugin({
      filename: "link.html",
      template: path.join(__dirname, "src", "link.html"),
      chunks: ["link"]
Greg Fodor's avatar
Greg Fodor committed
    }),
    new HTMLWebpackPlugin({
      filename: "avatar-selector.html",
      template: path.join(__dirname, "src", "avatar-selector.html"),
      chunks: ["avatar-selector"],
      inject: "head"
    }),
Greg Fodor's avatar
Greg Fodor committed
    new CopyWebpackPlugin([
      {
        from: "src/assets/images/favicon.ico",
        to: "favicon.ico"
      }
    ]),
    new CopyWebpackPlugin([
      {
        from: "src/assets/images/hub-preview.png",
        to: "hub-preview.png"
      }
    ]),
    // Extract required css and add a content hash.
    new ExtractTextPlugin({
Marshall Quander's avatar
Marshall Quander committed
      filename: "assets/stylesheets/[name]-[md5:contenthash:hex:20].css",
      disable: argv.mode !== "production"
    }),
    // Transform the output of the html-loader using _.template
    // before passing the result to html-webpack-plugin
    new LodashTemplatePlugin({
      // expose these variables to the lodash template
      // ex: <%= ORIGIN_TRIAL_TOKEN %>
      imports: {
        NODE_ENV: argv.mode,
        ORIGIN_TRIAL_EXPIRES: process.env.ORIGIN_TRIAL_EXPIRES,
        ORIGIN_TRIAL_TOKEN: process.env.ORIGIN_TRIAL_TOKEN
      }
    }),
    // Define process.env variables in the browser context.
    new webpack.DefinePlugin({
      "process.env": JSON.stringify({
        NODE_ENV: argv.mode,
Greg Fodor's avatar
Greg Fodor committed
        JANUS_SERVER: process.env.JANUS_SERVER,
        DEV_RETICULUM_SERVER: process.env.DEV_RETICULUM_SERVER,
        ASSET_BUNDLE_SERVER: process.env.ASSET_BUNDLE_SERVER,
        BUILD_VERSION: process.env.BUILD_VERSION