<commit_before>/*
 @author Zakai Hamilton
 @component AppTable
 */

screens.app.table = function AppTable(me) {
    me.init = function () {
        me.ui.content.attach(me);
        me.updateContentList();
    };
    me.launch = function (args) {
        if (!args) {
            args = [""];
        }
        var window = me.ui.element.create(__json__, "workspace", "self");
        if (typeof args[0] === "string") {
            me.importItem(window, args[0]);
        }
        return window;
    };
    me.initOptions = {
        set: function (object) {
            var window = me.widget.window.get(object);
            if (!window.optionsLoaded) {
                window.optionsLoaded = true;
                me.ui.options.load(me, window, {
                    editMode: false,
                    autoComplete: true,
                    doTranslation: true,
                    doExplanation: true,
                    prioritizeExplanation: true,
                    addStyles: true,
                    abridged: false,
                    keepSource: false,
                    category: true,
                    headings: true,
                    subHeadings: true,
                    language: "Auto",
                    fontSize: "18px",
                    phaseNumbers: true,
                    animation: true,
                    autoRotate: false
                });
            }
            me.ui.options.toggleSet(me, null, {
                "editMode": me.reload.set,
                "autoComplete": me.reload.set,
                "doTranslation": me.reload.set,
                "doExplanation": me.reload.set,
                "prioritizeExplanation": me.reload.set,
                "addStyles": me.reload.set,
                "phaseNumbers": me.reload.set,
                "keepSource": me.reload.set,
                "abridged": me.reload.set,
                "pages": me.reload.set,
                "columns": me.reload.set,
                "category": me.reload.set,
                "headings": me.reload.set,
                "subHeadings": me.reload.set,
                "animation": me.reload.set,
                "autoRotate": me.update
            });
            me.ui.options.choiceSet(me, null, {
                "language": me.reload.set,
                "fontSize": (object, value) => {
                    var window = me.widget.window.get(object);
                    me.core.property.set(window.var.table, "ui.style.fontSize", value);
                    me.core.property.notify(window, "reload");
                    me.core.property.notify(window, "update");
                }
            });
            me.ui.class.useStylesheet("kab");
            window.rowCount = 20;
            window.columnCount = 10;
            window.language = "english";
            window.options.clickCallback = "screens.widget.transform.openPopup";
            me.core.property.set(window, "app", me);
        }
    };
    me.clear = function (object) {
        var window = me.widget.window.get(object);
        me.core.property.set(window, "title", "Table");
        window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
        me.reload.set(window);
    };
    me.importData = function (object, text, title) {
        var window = me.widget.window.get(object);
        me.core.property.set(window, "title", title);
        var cells = JSON.parse(text);
        window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
        for (var cell of cells) {
            window.cells[cell.row][cell.column] = { value: cell.text };
        }
        me.reload.set(window);
    };
    me.exportData = function (object) {
        var window = me.widget.window.get(object);
        var title = me.core.property.get(window, "title");
        var data = [];
        window.cells.map((row, rowIndex) => {
            row.map((column, columnIndex) => {
                if (column.value) {
                    data.push({
                        row: rowIndex,
                        column: columnIndex,
                        text: column.value
                    });
                }
            });
        });
        if (!data.length) {
            return [];
        }
        return [JSON.stringify(data), title];
    };
    me.attributes = function (dict) {
        var attributes = "";
        for (const [key, value] of Object.entries(dict)) {
            attributes += " " + key + "=\"" + value + "\" ";
        }
        return attributes;
    };
    me.rename = function (object) {
        var window = me.widget.window.get(object);
        var title = object.value;
        if (!title) {
            title = "Table";
        }
        me.core.property.set(window, "title", title);
    };
    me.store = function (object) {
        var window = me.widget.window.get(object);
        var rowIndex = parseInt(me.core.property.get(object, "ui.attribute.rowIndex"));
        var columnIndex = parseInt(me.core.property.get(object, "ui.attribute.columnIndex"));
        var cell = window.cells[rowIndex][columnIndex];
        if (!cell) {
            cell = window.cells[rowIndex][columnIndex] = {};
        }
        cell.value = object.value;
    };
    me.rows = async function (object) {
        var html = "";
        var window = me.widget.window.get(object);
        var editMode = window.options.editMode;
        var cellOffset = 1;
        var countOffset = editMode ? 1 : 0;
        for (var rowIndex = 0; rowIndex < window.rowCount + countOffset; rowIndex++) {
            for (var columnIndex = 0; columnIndex < window.columnCount + countOffset; columnIndex++) {
                var cell = {};
                if (!editMode || (rowIndex && columnIndex)) {
                    cell = window.cells[rowIndex - countOffset][columnIndex - countOffset];
                }
                if (!cell) {
                    cell = {};
                }
                if (!cell.value && !editMode) {
                    continue;
                }
                var styles = ["grid-column:" + (columnIndex + cellOffset), "grid-row:" + (rowIndex + cellOffset)];
                var classes = ["app-table-row"];
                var attributes = {};
                var header = null;
                if (editMode) {
                    if (!rowIndex && !columnIndex) {
                        header = "";
                    }
                    else if (!rowIndex) {
                        header = columnIndex;
                    }
                    else if (!columnIndex) {
                        header = rowIndex;
                    }
                    styles.push("height:2em");
                }
                else {
                    styles.push("height:3em");
                }
                if (header) {
                    classes.push("header");
                }
                else if (editMode) {
                    if (!rowIndex && !columnIndex) {
                        attributes.oninput = "screens.app.table.rename(this)";
                    }
                    else {
                        attributes.oninput = "screens.app.table.store(this)";
                    }
                    classes.push("edit-mode");
                    styles.push("font-size:1em");
                }
                if (rowIndex > 0) {
                    attributes.rowIndex = rowIndex - countOffset;
                }
                if (columnIndex > 0) {
                    attributes.columnIndex = columnIndex - countOffset;
                }
                if (!header && cell.value) {
                    attributes.value = cell.value;
                }
                else if (!rowIndex && !columnIndex) {
                    attributes.value = me.core.property.get(window, "title");
                }
                attributes.class = classes.join(" ");
                attributes.style = styles.join(";");
                var tag = editMode && !header ? "input" : "div";
                var value = "";
                if (!editMode) {
                    value = await me.core.property.get(window, "widget.transform.term", cell.value);
                }
                else if (header) {
                    value = header;
                }
                else if (window.options.autoComplete) {
                    attributes.list = "terms";
                }
                html += "<" + tag + me.attributes(attributes) + ">" + value + "</" + tag + ">";
            }
        }
        if (window.options.autoComplete && editMode && window.terms) {
            html += "<datalist id=\"terms\">";
            html += window.terms.map(term => "<option value=\"" + term + "\"></option>").join("\n");
        }
        return html;
    };
    me.reload = {
        set: async function (object) {
            var window = me.widget.window.get(object);
            var language = window.language.toLowerCase();
            if (language === "auto") {
                language = "english";
            }
            if (language) {
                window.terms = await me.kab.data.terms(language);
            }
            me.core.property.set(window.var.table, "ui.style.fontSize", window.options.fontSize);
            me.core.property.set(window.var.table, "ui.class.edit-mode", window.options.editMode);
            if (!window.cells) {
                window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
            }
            var html = await me.rows(window);
            me.core.property.set([window.var.table, window.var.table], {
                "ui.basic.html": html
            });
            me.core.property.notify(window, "update");
        }
    };
    me.copyUrl = {
        get: function (object) {
            var window = me.widget.window.get(object);
            var title = me.core.property.get(window, "title");
            return title !== "Table";
        },
        set: function (object) {
            var window = me.widget.window.get(object);
            var title = me.core.property.get(window, "title");
            me.core.util.copyUrl("table", [title]);
        }
    };
};
<commit_msg>small refactor<commit_after>/*
 @author Zakai Hamilton
 @component AppTable
 */

screens.app.table = function AppTable(me) {
    me.init = function () {
        me.ui.content.attach(me);
        me.updateContentList();
    };
    me.launch = function (args) {
        if (!args) {
            args = [""];
        }
        var window = me.ui.element.create(__json__, "workspace", "self");
        if (typeof args[0] === "string") {
            me.importItem(window, args[0]);
        }
        return window;
    };
    me.initOptions = {
        set: function (object) {
            var window = me.widget.window.get(object);
            if (!window.optionsLoaded) {
                window.optionsLoaded = true;
                me.ui.options.load(me, window, {
                    editMode: false,
                    autoComplete: true,
                    doTranslation: true,
                    doExplanation: true,
                    prioritizeExplanation: true,
                    addStyles: true,
                    abridged: false,
                    keepSource: false,
                    category: true,
                    headings: true,
                    subHeadings: true,
                    language: "Auto",
                    fontSize: "18px",
                    phaseNumbers: true,
                    animation: true,
                    autoRotate: false
                });
            }
            me.ui.options.toggleSet(me, null, {
                "editMode": me.reload.set,
                "autoComplete": me.reload.set,
                "doTranslation": me.reload.set,
                "doExplanation": me.reload.set,
                "prioritizeExplanation": me.reload.set,
                "addStyles": me.reload.set,
                "phaseNumbers": me.reload.set,
                "keepSource": me.reload.set,
                "abridged": me.reload.set,
                "pages": me.reload.set,
                "columns": me.reload.set,
                "category": me.reload.set,
                "headings": me.reload.set,
                "subHeadings": me.reload.set,
                "animation": me.reload.set,
                "autoRotate": me.update
            });
            me.ui.options.choiceSet(me, null, {
                "language": me.reload.set,
                "fontSize": (object, value) => {
                    var window = me.widget.window.get(object);
                    me.core.property.set(window.var.table, "ui.style.fontSize", value);
                    me.core.property.notify(window, "reload");
                    me.core.property.notify(window, "update");
                }
            });
            me.ui.class.useStylesheet("kab");
            window.rowCount = 20;
            window.columnCount = 10;
            window.language = "english";
            window.options.clickCallback = "screens.widget.transform.openPopup";
            me.core.property.set(window, "app", me);
        }
    };
    me.clear = function (object) {
        var window = me.widget.window.get(object);
        me.core.property.set(window, "title", "Table");
        window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
        me.reload.set(window);
    };
    me.importData = function (object, text, title) {
        var window = me.widget.window.get(object);
        me.core.property.set(window, "title", title);
        var cells = JSON.parse(text);
        window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
        for (var cell of cells) {
            window.cells[cell.row][cell.column] = { value: cell.text };
        }
        me.reload.set(window);
    };
    me.exportData = function (object) {
        var window = me.widget.window.get(object);
        var title = me.core.property.get(window, "title");
        var data = [];
        window.cells.map((row, rowIndex) => {
            row.map((column, columnIndex) => {
                if (column.value) {
                    data.push({
                        row: rowIndex,
                        column: columnIndex,
                        text: column.value
                    });
                }
            });
        });
        if (!data.length) {
            return [];
        }
        return [JSON.stringify(data), title];
    };
    me.attributes = function (dict) {
        var attributes = "";
        for (const [key, value] of Object.entries(dict)) {
            attributes += " " + key + "=\"" + value + "\" ";
        }
        return attributes;
    };
    me.rename = function (object) {
        var window = me.widget.window.get(object);
        var title = object.value;
        if (!title) {
            title = "Table";
        }
        me.core.property.set(window, "title", title);
    };
    me.store = function (object) {
        var window = me.widget.window.get(object);
        var rowIndex = parseInt(me.core.property.get(object, "ui.attribute.rowIndex"));
        var columnIndex = parseInt(me.core.property.get(object, "ui.attribute.columnIndex"));
        var cell = window.cells[rowIndex][columnIndex];
        if (!cell) {
            cell = window.cells[rowIndex][columnIndex] = {};
        }
        cell.value = object.value;
    };
    me.rows = async function (object) {
        var html = "";
        var window = me.widget.window.get(object);
        var editMode = window.options.editMode;
        var cellOffset = 1;
        var countOffset = editMode ? 1 : 0;
        for (var rowIndex = 0; rowIndex < window.rowCount + countOffset; rowIndex++) {
            for (var columnIndex = 0; columnIndex < window.columnCount + countOffset; columnIndex++) {
                var cell = {};
                if (!editMode || (rowIndex && columnIndex)) {
                    cell = window.cells[rowIndex - countOffset][columnIndex - countOffset];
                }
                if (!cell) {
                    cell = {};
                }
                if (!cell.value && !editMode) {
                    continue;
                }
                var styles = ["grid-column:" + (columnIndex + cellOffset), "grid-row:" + (rowIndex + cellOffset)];
                var classes = ["app-table-row"];
                var attributes = {};
                var header = null;
                if (editMode) {
                    if (!rowIndex && !columnIndex) {
                        header = "";
                    }
                    else if (!rowIndex) {
                        header = columnIndex;
                    }
                    else if (!columnIndex) {
                        header = rowIndex;
                    }
                    styles.push("height:2em");
                }
                else {
                    styles.push("height:3em");
                }
                if (header) {
                    classes.push("header");
                }
                else if (editMode) {
                    if (!rowIndex && !columnIndex) {
                        attributes.oninput = "screens.app.table.rename(this)";
                    }
                    else {
                        attributes.oninput = "screens.app.table.store(this)";
                    }
                    classes.push("edit-mode");
                    styles.push("font-size:1em");
                }
                if (rowIndex > 0) {
                    attributes.rowIndex = rowIndex - countOffset;
                }
                if (columnIndex > 0) {
                    attributes.columnIndex = columnIndex - countOffset;
                }
                if (!header && cell.value) {
                    attributes.value = cell.value;
                }
                else if (!rowIndex && !columnIndex) {
                    attributes.value = me.core.property.get(window, "title");
                }
                attributes.class = classes.join(" ");
                attributes.style = styles.join(";");
                var tag = editMode && !header ? "input" : "div";
                var value = "";
                if (!editMode) {
                    value = await me.core.property.get(window, "widget.transform.term", cell.value);
                }
                else if (header) {
                    value = header;
                }
                else if (window.options.autoComplete) {
                    attributes.list = "terms";
                }
                html += "<" + tag + me.attributes(attributes) + ">" + value + "</" + tag + ">";
            }
        }
        if (window.options.autoComplete && editMode && window.terms) {
            html += "<datalist id=\"terms\">";
            html += window.terms.map(term => "<option value=\"" + term + "\"></option>").join("\n");
        }
        return html;
    };
    me.reload = {
        set: async function (object) {
            var window = me.widget.window.get(object);
            var language = window.language.toLowerCase();
            if (language === "auto") {
                language = "english";
            }
            if (language) {
                window.terms = await me.kab.data.terms(language);
            }
            me.core.property.set(window.var.table, {
                "ui.style.fontSize": window.options.fontSize,
                "ui.class.edit-mode": window.options.editMode
            });
            if (!window.cells) {
                window.cells = Array.from(Array(window.rowCount), () => new Array(window.columnCount));
            }
            var html = await me.rows(window);
            me.core.property.set([window.var.table, window.var.table], {
                "ui.basic.html": html
            });
            me.core.property.notify(window, "update");
        }
    };
    me.copyUrl = {
        get: function (object) {
            var window = me.widget.window.get(object);
            var title = me.core.property.get(window, "title");
            return title !== "Table";
        },
        set: function (object) {
            var window = me.widget.window.get(object);
            var title = me.core.property.get(window, "title");
            me.core.util.copyUrl("table", [title]);
        }
    };
};
<|endoftext|>


<commit_before>"use strict";

//Load dependencies
var request = require("request");
var applicationStorage = process.require("core/applicationStorage.js");

//For russian Ream wowprogress is bad ...
var russianRealms = {
    "Gordunni": "Гордунни",
    "Howling Fjord": "Ревущий фьорд",
    "Blackscar": "Черный Шрам",
    "Ashenvale": "Ясеневый лес",
    "Soulflayer": "Свежеватель Душ",
    "Razuvious": "Разувий",
    "Azuregos": "Азурегос",
    "Booty Bay": "Пиратская Бухта",
    "Eversong": "Вечная Песня",
    "Deathguard": "Страж смерти",
    "Lich King": "Король-лич",
    "Fordragon": "Дракономор",
    "Borean Tundra": "Борейская тундра",
    "Goldrinn": "Голдринн",
    "Grom": "Гром",
    "Galakrond": "Галакронд"
};

/**
 * Return the guild ranking from warcraftLogs
 * @param region
 * @param realm
 * @param name
 * @param callback
 */
module.exports.getRankings = function (region, realm, name, callback) {

    var logger = applicationStorage.logger;
    var config = applicationStorage.config;

    var warcraftlogs = {};

    if (region.toLowerCase() == "eu" && russianRealms[realm]) {
        realm = russianRealms[realm];
    }

    realm = realm.split(" ").join("-");
    realm = realm.split("'").join("");

    //noinspection JSUnresolvedVariable
    var url = encodeURI("https://www.warcraftlogs.com/v1/rankings/character/" + name + "/" + realm + "/" + region + "?metric=dps&api_key=" + config.warcraftLogs.api_key);

    request(url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            warcraftlogs.dps = JSON.parse(body);

            //noinspection JSUnresolvedVariable
            url = encodeURI("https://www.warcraftlogs.com/v1/rankings/character/" + name + "/" + realm + "/" + region + "?metric=hps&api_key=" + config.warcraftLogs.api_key);

            request(url, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    warcraftlogs.hps = JSON.parse(body);
                    callback(error, warcraftlogs);
                }
                else {
                    if (error) {
                        logger.error(error.message + " on fetching warcraftlogs api " + url);
                    }
                    else {
                        logger.warn("Error HTTP " + response.statusCode + " on fetching warcraftlogs api " + url);
                    }
                    callback(new Error("WARCRAFTLOGS_API_ERROR"));
                }
            });
        }
        else {
            if (error) {
                logger.error(error.message + " on fetching warcraftlogs api " + url);
            }
            else {
                logger.warn("Error HTTP " + response.statusCode + " on fetching warcraftlogs api " + url);
            }
            callback(new Error("WARCRAFTLOGS_API_ERROR"));
        }
    });
};
<commit_msg>Fix bug on warcraftlogs api error<commit_after>"use strict";

//Load dependencies
var request = require("request");
var applicationStorage = process.require("core/applicationStorage.js");

//For russian Ream wowprogress is bad ...
var russianRealms = {
    "Gordunni": "Гордунни",
    "Howling Fjord": "Ревущий фьорд",
    "Blackscar": "Черный Шрам",
    "Ashenvale": "Ясеневый лес",
    "Soulflayer": "Свежеватель Душ",
    "Razuvious": "Разувий",
    "Azuregos": "Азурегос",
    "Booty Bay": "Пиратская Бухта",
    "Eversong": "Вечная Песня",
    "Deathguard": "Страж смерти",
    "Lich King": "Король-лич",
    "Fordragon": "Дракономор",
    "Borean Tundra": "Борейская тундра",
    "Goldrinn": "Голдринн",
    "Grom": "Гром",
    "Galakrond": "Галакронд"
};

/**
 * Return the guild ranking from warcraftLogs
 * @param region
 * @param realm
 * @param name
 * @param callback
 */
module.exports.getRankings = function (region, realm, name, callback) {

    var logger = applicationStorage.logger;
    var config = applicationStorage.config;

    var warcraftlogs = {};

    if (region.toLowerCase() == "eu" && russianRealms[realm]) {
        realm = russianRealms[realm];
    }

    realm = realm.split(" ").join("-");
    realm = realm.split("'").join("");

    //noinspection JSUnresolvedVariable
    var url = encodeURI("https://www.warcraftlogs.com/v1/rankings/character/" + name + "/" + realm + "/" + region + "?metric=dps&api_key=" + config.warcraftLogs.api_key);

    request(url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
	    try{
	    warcraftlogs.dps = JSON.parse(body);
            }
	    catch(e){
            return callback(new Error("WARCRAFTLOGS_API_ERROR"));
	    }
            //noinspection JSUnresolvedVariable
            url = encodeURI("https://www.warcraftlogs.com/v1/rankings/character/" + name + "/" + realm + "/" + region + "?metric=hps&api_key=" + config.warcraftLogs.api_key);

            request(url, function (error, response, body) {
                if (!error && response.statusCode == 200) {
		try{
                    warcraftlogs.hps = JSON.parse(body);
		}
            catch(e){
            return callback(new Error("WARCRAFTLOGS_API_ERROR"));
            }

                    callback(error, warcraftlogs);
                }
                else {
                    if (error) {
                        logger.error(error.message + " on fetching warcraftlogs api " + url);
                    }
                    else {
                        logger.warn("Error HTTP " + response.statusCode + " on fetching warcraftlogs api " + url);
                    }
                    callback(new Error("WARCRAFTLOGS_API_ERROR"));
                }
            });
        }
        else {
            if (error) {
                logger.error(error.message + " on fetching warcraftlogs api " + url);
            }
            else {
                logger.warn("Error HTTP " + response.statusCode + " on fetching warcraftlogs api " + url);
            }
            callback(new Error("WARCRAFTLOGS_API_ERROR"));
        }
    });
};
<|endoftext|>


<commit_before>var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack/webpack.dev.config')

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  inline: true,
  noInfo: false,
  stats: { colors: true },
  historyApiFallback: false,
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  },
}).listen(3000, '0.0.0.0', function (err, result) {
  if (err) {
    console.log(err)
  }

  console.log('Listening at 0.0.0.0:3000')
})
<commit_msg>More stable webpack builds, less vagrant hangings.<commit_after>var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack/webpack.dev.config')

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  inline: true,
  noInfo: false,
  stats: { colors: true },
  historyApiFallback: false,
  watchOptions: {
    aggregateTimeout: 500,
    poll: 2000
  },
}).listen(3000, '0.0.0.0', function (err, result) {
  if (err) {
    console.log(err)
  }

  console.log('Listening at 0.0.0.0:3000')
})
<|endoftext|>


<commit_before>const webpack = require('webpack');
const fs = require('fs');
const path = require('path');
const md5 = require('md5');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

// invalidate webpack cache when webpack config is changed or cache-loader is updated,
const CACHE_INVALIDATE = JSON.stringify({
  THREAD_LOADER:       require('cache-loader/package.json').version,
  WEBPACK_CONFIG:      md5(fs.readFileSync(__filename)),
});

const NODE_MODULE_PATH = path.join(__dirname, 'node_modules');
const SETTINGS_PATH = process.env.SETTINGS_PATH || './settings.js';

function configure(IS_TEST) {

  const config = {
    context: __dirname, // to automatically find tsconfig.json,
    stats: 'errors-only',
    devtool: 'source-map',
    plugins: [],
    output: IS_TEST ? undefined : {
      path: path.join(__dirname, 'build', 'webpack', process.env.SPINNAKER_ENV || ''),
      filename: '[name].js',
    },
    resolveLoader: IS_TEST ? {} : {
      modules: [
        NODE_MODULE_PATH
      ],
      moduleExtensions: ['-loader']
    },
    resolve: {
      extensions: ['.json', '.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.html'],
      modules: [
        NODE_MODULE_PATH,
        path.join(__dirname, 'app', 'scripts', 'modules'),
      ],
      alias: {
        'root': __dirname,
        'core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        '@spinnaker/core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        'docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        '@spinnaker/docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        'amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        'google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        '@spinnaker/google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        'kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        '@spinnaker/kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        'openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        '@spinnaker/openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        'coreImports': path.resolve(__dirname, 'app', 'scripts', 'modules', 'core', 'src', 'presentation', 'less', 'imports', 'commonImports.less'),
      }
    },
    module: {
      rules: [
        {
          test: /settings\.js/,
          use: [
            { loader: 'envify-loader' },
          ],
        },
        {
          test: /\.js$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: 3 } },
            { loader: 'babel-loader' },
            { loader: 'eslint-loader' } ,
          ],
          exclude: /(node_modules(?!\/clipboard)|settings\.js)/
        },
        {
          test: /\.tsx?$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: 3 } },
            { loader: 'babel-loader' },
            { loader: 'ts-loader', options: { happyPackMode: true } },
            { loader: 'tslint-loader' },
          ],
          exclude: /node_modules/
        },
        {
          test: /\.less$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
            { loader: 'less-loader' },
          ],
        },
        {
          test: /\.css$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
          ]
        },
        {
          test: /\.html$/,
          use: [
            { loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname)) + '/' },
            { loader: 'html-loader' },
          ]
        },
        {
          test: /\.json$/,
          use: [
            { loader: 'json-loader' },
          ],
        },
        {
          test: /\.(woff|woff2|otf|ttf|eot|png|gif|ico|svg)$/,
          use: [
            { loader: 'file-loader', options: { name: '[name].[hash:5].[ext]'} },
          ],
        },
        {
          test: require.resolve('jquery'),
          use: [
            { loader: 'expose-loader?$' },
            { loader: 'expose-loader?jQuery' },
          ],
        },
      ],
    },
    watch: IS_TEST,
    devServer: IS_TEST ? {
      stats: 'errors-only',
    } : {
      port: process.env.DECK_PORT || 9000,
      host: process.env.DECK_HOST || 'localhost',
      https: process.env.DECK_HTTPS === 'true',
      stats: 'errors-only',
    },
    externals: {
      'cheerio': 'window',
      'react/addons': 'react',
      'react/lib/ExecutionEnvironment': 'react',
      'react/lib/ReactContext': 'react',
    },
  };

  if (process.env.DECK_CERT) {
    config.devServer.cert = fs.readFileSync(process.env.DECK_CERT);
    config.devServer.key = fs.readFileSync(process.env.DECK_KEY);
    if (process.env.DECK_CA_CERT) {
      config.devServer.cacert = fs.readFileSync(process.env.DECK_CA_CERT);
    }
  }

  config.plugins = [
    new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true, tslint: true }),
  ];

  if (!IS_TEST) {
    config.entry = {
      settings: SETTINGS_PATH,
      settingsLocal: './settings-local.js',
      halconfig: './halconfig/settings.js',
      app: './app/scripts/app.ts',
      vendor: [
        'jquery', 'angular', 'angular-ui-bootstrap', 'source-sans-pro',
        'angular-cache', 'angular-messages', 'angular-sanitize', 'bootstrap',
        'clipboard', 'd3', 'jquery-ui', 'moment-timezone', 'rxjs', 'react', 'angular2react',
        'react2angular', 'react-bootstrap', 'react-dom', 'react-ga', 'ui-select',
        '@uirouter/angularjs', '@uirouter/visualizer',
      ]
    };

    config.plugins.push(...[
      new webpack.EnvironmentPlugin({
        API_HOST: 'https://api-prestaging.spinnaker.mgmt.netflix.net',
        ENTITY_TAGS_ENABLED: 'true',
        FIAT_ENABLED: 'false',
        INFRA_STAGES: 'false',
        TIMEZONE: 'America/Los_Angeles',
        NODE_ENV: 'development',
      }),
      new webpack.optimize.CommonsChunkPlugin({name: 'vendor', filename: 'vendor.bundle.js'}),
      new webpack.optimize.CommonsChunkPlugin('init'),
      new HtmlWebpackPlugin({
        title: 'Spinnaker',
        template: './app/index.deck',
        favicon: process.env.NODE_ENV === 'production' ? 'app/prod-favicon.ico' : 'app/dev-favicon.ico',
        inject: true,

        // default order is based on webpack's compile process
        // with the migration to webpack two, we need this or
        // settings.js is put at the end of the <script> blocks
        // which breaks the booting of the app.
        chunksSortMode: (a, b) => {
          const chunks = ['init', 'vendor', 'halconfig', 'settings', 'settingsLocal', 'app'];
          return chunks.indexOf(a.names[0]) - chunks.indexOf(b.names[0]);
        }
      })
    ]);

    if (process.env.NODE_ENV === 'production') {
      config.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
      config.plugins.push(new webpack.optimize.UglifyJsPlugin({ include: /vendor/, sourceMap: true }));
    }
  }

  // this is temporary and will be deprecated in WP3.  moving forward,
  // loaders will individually need to accept this as an option.
  config.plugins.push(new webpack.LoaderOptionsPlugin({debug: !IS_TEST}));

  return config;
}

module.exports = configure;
<commit_msg>fix(webpack): remove API_HOST (#4469)<commit_after>const webpack = require('webpack');
const fs = require('fs');
const path = require('path');
const md5 = require('md5');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

// invalidate webpack cache when webpack config is changed or cache-loader is updated,
const CACHE_INVALIDATE = JSON.stringify({
  THREAD_LOADER:       require('cache-loader/package.json').version,
  WEBPACK_CONFIG:      md5(fs.readFileSync(__filename)),
});

const NODE_MODULE_PATH = path.join(__dirname, 'node_modules');
const SETTINGS_PATH = process.env.SETTINGS_PATH || './settings.js';

function configure(IS_TEST) {

  const config = {
    context: __dirname, // to automatically find tsconfig.json,
    stats: 'errors-only',
    devtool: 'source-map',
    plugins: [],
    output: IS_TEST ? undefined : {
      path: path.join(__dirname, 'build', 'webpack', process.env.SPINNAKER_ENV || ''),
      filename: '[name].js',
    },
    resolveLoader: IS_TEST ? {} : {
      modules: [
        NODE_MODULE_PATH
      ],
      moduleExtensions: ['-loader']
    },
    resolve: {
      extensions: ['.json', '.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.html'],
      modules: [
        NODE_MODULE_PATH,
        path.join(__dirname, 'app', 'scripts', 'modules'),
      ],
      alias: {
        'root': __dirname,
        'core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        '@spinnaker/core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        'docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        '@spinnaker/docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        'amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        'google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        '@spinnaker/google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        'kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        '@spinnaker/kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        'openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        '@spinnaker/openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        'coreImports': path.resolve(__dirname, 'app', 'scripts', 'modules', 'core', 'src', 'presentation', 'less', 'imports', 'commonImports.less'),
      }
    },
    module: {
      rules: [
        {
          test: /settings\.js/,
          use: [
            { loader: 'envify-loader' },
          ],
        },
        {
          test: /\.js$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: 3 } },
            { loader: 'babel-loader' },
            { loader: 'eslint-loader' } ,
          ],
          exclude: /(node_modules(?!\/clipboard)|settings\.js)/
        },
        {
          test: /\.tsx?$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: 3 } },
            { loader: 'babel-loader' },
            { loader: 'ts-loader', options: { happyPackMode: true } },
            { loader: 'tslint-loader' },
          ],
          exclude: /node_modules/
        },
        {
          test: /\.less$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
            { loader: 'less-loader' },
          ],
        },
        {
          test: /\.css$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
          ]
        },
        {
          test: /\.html$/,
          use: [
            { loader: 'ngtemplate-loader?relativeTo=' + (path.resolve(__dirname)) + '/' },
            { loader: 'html-loader' },
          ]
        },
        {
          test: /\.json$/,
          use: [
            { loader: 'json-loader' },
          ],
        },
        {
          test: /\.(woff|woff2|otf|ttf|eot|png|gif|ico|svg)$/,
          use: [
            { loader: 'file-loader', options: { name: '[name].[hash:5].[ext]'} },
          ],
        },
        {
          test: require.resolve('jquery'),
          use: [
            { loader: 'expose-loader?$' },
            { loader: 'expose-loader?jQuery' },
          ],
        },
      ],
    },
    watch: IS_TEST,
    devServer: IS_TEST ? {
      stats: 'errors-only',
    } : {
      port: process.env.DECK_PORT || 9000,
      host: process.env.DECK_HOST || 'localhost',
      https: process.env.DECK_HTTPS === 'true',
      stats: 'errors-only',
    },
    externals: {
      'cheerio': 'window',
      'react/addons': 'react',
      'react/lib/ExecutionEnvironment': 'react',
      'react/lib/ReactContext': 'react',
    },
  };

  if (process.env.DECK_CERT) {
    config.devServer.cert = fs.readFileSync(process.env.DECK_CERT);
    config.devServer.key = fs.readFileSync(process.env.DECK_KEY);
    if (process.env.DECK_CA_CERT) {
      config.devServer.cacert = fs.readFileSync(process.env.DECK_CA_CERT);
    }
  }

  config.plugins = [
    new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true, tslint: true }),
  ];

  if (!IS_TEST) {
    config.entry = {
      settings: SETTINGS_PATH,
      settingsLocal: './settings-local.js',
      halconfig: './halconfig/settings.js',
      app: './app/scripts/app.ts',
      vendor: [
        'jquery', 'angular', 'angular-ui-bootstrap', 'source-sans-pro',
        'angular-cache', 'angular-messages', 'angular-sanitize', 'bootstrap',
        'clipboard', 'd3', 'jquery-ui', 'moment-timezone', 'rxjs', 'react', 'angular2react',
        'react2angular', 'react-bootstrap', 'react-dom', 'react-ga', 'ui-select',
        '@uirouter/angularjs', '@uirouter/visualizer',
      ]
    };

    config.plugins.push(...[
      new webpack.EnvironmentPlugin({
        ENTITY_TAGS_ENABLED: 'true',
        FIAT_ENABLED: 'false',
        INFRA_STAGES: 'false',
        TIMEZONE: 'America/Los_Angeles',
        NODE_ENV: 'development',
      }),
      new webpack.optimize.CommonsChunkPlugin({name: 'vendor', filename: 'vendor.bundle.js'}),
      new webpack.optimize.CommonsChunkPlugin('init'),
      new HtmlWebpackPlugin({
        title: 'Spinnaker',
        template: './app/index.deck',
        favicon: process.env.NODE_ENV === 'production' ? 'app/prod-favicon.ico' : 'app/dev-favicon.ico',
        inject: true,

        // default order is based on webpack's compile process
        // with the migration to webpack two, we need this or
        // settings.js is put at the end of the <script> blocks
        // which breaks the booting of the app.
        chunksSortMode: (a, b) => {
          const chunks = ['init', 'vendor', 'halconfig', 'settings', 'settingsLocal', 'app'];
          return chunks.indexOf(a.names[0]) - chunks.indexOf(b.names[0]);
        }
      })
    ]);

    if (process.env.NODE_ENV === 'production') {
      config.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
      config.plugins.push(new webpack.optimize.UglifyJsPlugin({ include: /vendor/, sourceMap: true }));
    }
  }

  // this is temporary and will be deprecated in WP3.  moving forward,
  // loaders will individually need to accept this as an option.
  config.plugins.push(new webpack.LoaderOptionsPlugin({debug: !IS_TEST}));

  return config;
}

module.exports = configure;
<|endoftext|>


<commit_before>/* jshint node:true, es3:false */

'use strict';

var webpack = require('webpack');
var path = require('path')

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:5001',
		'webpack/hot/dev-server',
    './client.js'
  ],
	plugins: [
    new webpack.HotModuleReplacementPlugin()
	],
  output: {
		path: __dirname + '/resources/',
    filename: 'bundle.js',
    publicPath: 'http://localhost:5001/resources/'
  },
	module: {
		loaders: [
      { test: /\.jsx$/, loaders: ['react-hot', 'jsx'] }
		]
	},
	devtool: '#eval'
};
<commit_msg>point to only-dev-server<commit_after>/* jshint node:true, es3:false */

'use strict';

var webpack = require('webpack');
var path = require('path')

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:5001',
		'webpack/hot/only-dev-server',
    './client.js'
  ],
	plugins: [
    new webpack.HotModuleReplacementPlugin()
	],
  output: {
		path: __dirname + '/resources/',
    filename: 'bundle.js',
    publicPath: 'http://localhost:5001/resources/'
  },
	module: {
		loaders: [
      { test: /\.jsx$/, loaders: ['react-hot', 'jsx'] }
		]
	},
	devtool: '#eval'
};
<|endoftext|>


<commit_before>var webpack = require('webpack');
var yargs = require('yargs').argv;
var testing = yargs.env === 'test';

//------------------------------------------------------------------------------
// https://github.com/webpack/webpack/issues/839#issuecomment-177219660
function getExternals() {
    var fs = require('fs');
    var nodeModules = {};

    fs.readdirSync('node_modules').forEach(function (module) {
      if (module !== '.bin') {
        nodeModules[module] = true;
      }
    });

    var nodeModulesTransform = function(context, request, callback) {
      // search for a '/' indicating a nested module
      var slashIndex = request.indexOf("/");
      var rootModuleName;
      if (slashIndex == -1) {
        rootModuleName = request;
      } else {
        rootModuleName = request.substr(0, slashIndex);
      }

      // Match for root modules that are in our node_modules
      if (nodeModules.hasOwnProperty(rootModuleName)) {
        callback(null, "commonjs " + request);
      } else {
        callback();
      }
    };
    return nodeModulesTransform;
}
//------------------------------------------------------------------------------

var config = {
    entry: './src/redux-decorators.ts',
    resolve: {
        extensions: ['', '.ts', '.js']
    },
    module: {
        loaders: [
            { test: /\.ts$/, loader: 'ts-loader' }
        ]
    },
    "compilerOptions": {
        "module": "commonjs",
        "sourceMap": true
      },
    output: {
        filename: './dist/redux-decorators.js',
        library: 'ReduxDecorators',
        libraryTarget: 'umd'
    },
    externals: getExternals(),
    plugins: [
        new webpack.ProvidePlugin({
            // 'redux': 'Redux'
        })
    ],
    // Turn on sourcemaps
    devtool: 'source-map'
};

var testingDecorator = function(config) {
    var path = require('path');
    config.entry = path.resolve('./test/all-tests.ts');
    config.target = 'node';
    config.output = {};
    config.output.filename = './dist/redux-decorators.spec.js';
    return config;
};

if (testing) {
    config = testingDecorator(config);
}

module.exports = config;
<commit_msg>Cleaned up webpack config<commit_after>var webpack = require('webpack');
var yargs = require('yargs').argv;
var testing = yargs.env === 'test';

//------------------------------------------------------------------------------
// https://github.com/webpack/webpack/issues/839#issuecomment-177219660
function getExternals() {
    var fs = require('fs');
    var nodeModules = {};

    fs.readdirSync('node_modules').forEach(function (module) {
      if (module !== '.bin') {
        nodeModules[module] = true;
      }
    });

    var nodeModulesTransform = function(context, request, callback) {
      // search for a '/' indicating a nested module
      var slashIndex = request.indexOf("/");
      var rootModuleName;
      if (slashIndex == -1) {
        rootModuleName = request;
      } else {
        rootModuleName = request.substr(0, slashIndex);
      }

      // Match for root modules that are in our node_modules
      if (nodeModules.hasOwnProperty(rootModuleName)) {
        callback(null, "commonjs " + request);
      } else {
        callback();
      }
    };
    return nodeModulesTransform;
}
//------------------------------------------------------------------------------

var config = {
    entry: './src/redux-decorators.ts',
    resolve: {
        extensions: ['', '.ts', '.js']
    },
    module: {
        loaders: [
            { test: /\.ts$/, loader: 'ts-loader' }
        ]
    },
    compilerOptions: {
        module: 'commonjs',
        sourceMap: true
    },
    output: {
        filename: './dist/redux-decorators.js',
        library: 'ReduxDecorators',
        libraryTarget: 'umd'
    },
    devtool: 'source-map',
    externals: getExternals()
};

var testingDecorator = function(config) {
    var path = require('path');
    config.entry = path.resolve('./test/all-tests.ts');
    config.target = 'node';
    config.output = {};
    config.output.filename = './dist/redux-decorators.spec.js';
    return config;
};

if (testing) {
    config = testingDecorator(config);
}

module.exports = config;
<|endoftext|>


<commit_before>{
  module.exports = {
    entry: "./src/index.js",
    output: {
      path: __dirname,
      filename: "./dist/index.js",
      libraryTarget: "commonjs",
      library: "react-attr"
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/
            }
        ]
    }
  }
};
<commit_msg>Set libraryTarget to be commonjs2. Should fix the export.<commit_after>{
  module.exports = {
    entry: "./src/index.js",
    output: {
      path: __dirname,
      filename: "./dist/index.js",
      libraryTarget: "commonjs2",
      library: "react-attr"
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/
            }
        ]
    }
  }
};
<|endoftext|>


<commit_before>var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var WebpackNotifierPlugin = require('webpack-notifier');
var CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
var LiveReloadPlugin = require('webpack-livereload-plugin');
var nodeExternals = require('webpack-node-externals');

var plugins = [];

//do we minify it all
if(process.env.NODE_ENV === 'production'){
	console.log("creating production build");
	new CheckerPlugin(),
	plugins.push(new webpack.optimize.UglifyJsPlugin({
		mangle: {
			keep_fnames: true
		},
		compress: {
			keep_fnames: true,
			warnings: false,
		}
	}));
	plugins.push(new webpack.DefinePlugin({
		'process.env.NODE_ENV': JSON.stringify('production')
	}));
}

/**
 * @author Dylan Vorster
 */
module.exports = [
	//for building the umd distribution
	{
		entry: './src/main.ts',
		output: {
			filename: 'main.js',
			path: __dirname + '/dist',
			libraryTarget: 'umd',
			library: 'storm-react-forms'
		},
		externals: [nodeExternals()],
		plugins:plugins,
		module: {
			rules: [
				{
					test: /\.scss$/,
					use: ExtractTextPlugin.extract({
						fallback: 'style-loader',
						use: ['css-loader', 'sass-loader']
					})
				},
				{
					test: /\.tsx?$/,
					loader: 'awesome-typescript-loader'
				},
			]
		},
		resolve: {
			extensions: [".tsx", ".ts", ".js"]
		},
		devtool: process.env.NODE_ENV === 'production'?false:'cheap-module-source-map'
	},

	//for building the demos and tests
	{
		entry: {
			'demo1/min/bundle.min': './demos/demo1/index.ts',
		},
		output: {
			filename: '[name].js',
			path: __dirname + '/demos',
			libraryTarget: 'umd',
			library: 'storm-react-forms'
		},
		plugins:plugins.concat([
			new WebpackNotifierPlugin({alwaysNotify: true}),
			new ExtractTextPlugin({filename:'[name].css'}),
			new LiveReloadPlugin({port: 35729})
		]),
		module: {
			rules: [
				{
					test: /\.scss$/,
					use: ExtractTextPlugin.extract({
						fallback: 'style-loader',
						use: ['css-loader', 'sass-loader']
					})
				},
				{
					enforce: 'pre',
					test: /\.js$/,
					loader: "source-map-loader"
				},
				{
					test: /\.tsx?$/,
					loader: 'awesome-typescript-loader'
				},
			]
		},
		resolve: {
			extensions: [".tsx", ".ts", ".js"]
		},
		devtool: process.env.NODE_ENV === 'production'?false:'cheap-module-source-map'
	}
];
<commit_msg>node externals suck<commit_after>var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var WebpackNotifierPlugin = require('webpack-notifier');
var CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
var LiveReloadPlugin = require('webpack-livereload-plugin');

var plugins = [];

//do we minify it all
if(process.env.NODE_ENV === 'production'){
	console.log("creating production build");
	new CheckerPlugin(),
	plugins.push(new webpack.optimize.UglifyJsPlugin({
		mangle: {
			keep_fnames: true
		},
		compress: {
			keep_fnames: true,
			warnings: false,
		}
	}));
	plugins.push(new webpack.DefinePlugin({
		'process.env.NODE_ENV': JSON.stringify('production')
	}));
}

/**
 * @author Dylan Vorster
 */
module.exports = [
	//for building the umd distribution
	{
		entry: './src/main.ts',
		output: {
			filename: 'main.js',
			path: __dirname + '/dist',
			libraryTarget: 'umd',
			library: 'storm-react-forms'
		},
		externals: {
			react: {
				root: 'React',
				commonjs2: 'react',
				commonjs: 'react',
				amd: 'react'
			},
			'react-dom': {
				root: 'ReactDOM',
				commonjs2: 'react-dom',
				commonjs: 'react-dom',
				amd: 'react-dom'
			},
			"lodash": {
				commonjs: 'lodash',
				commonjs2: 'lodash',
				amd: '_',
				root: '_'
			}
		},
		plugins:plugins,
		module: {
			rules: [
				{
					test: /\.scss$/,
					use: ExtractTextPlugin.extract({
						fallback: 'style-loader',
						use: ['css-loader', 'sass-loader']
					})
				},
				{
					test: /\.tsx?$/,
					loader: 'awesome-typescript-loader'
				},
			]
		},
		resolve: {
			extensions: [".tsx", ".ts", ".js"]
		},
		devtool: process.env.NODE_ENV === 'production'?false:'cheap-module-source-map'
	},

	//for building the demos and tests
	{
		entry: {
			'demo1/min/bundle.min': './demos/demo1/index.ts',
		},
		output: {
			filename: '[name].js',
			path: __dirname + '/demos',
			libraryTarget: 'umd',
			library: 'storm-react-forms'
		},
		plugins:plugins.concat([
			new WebpackNotifierPlugin({alwaysNotify: true}),
			new ExtractTextPlugin({filename:'[name].css'}),
			new LiveReloadPlugin({port: 35729})
		]),
		module: {
			rules: [
				{
					test: /\.scss$/,
					use: ExtractTextPlugin.extract({
						fallback: 'style-loader',
						use: ['css-loader', 'sass-loader']
					})
				},
				{
					enforce: 'pre',
					test: /\.js$/,
					loader: "source-map-loader"
				},
				{
					test: /\.tsx?$/,
					loader: 'awesome-typescript-loader'
				},
			]
		},
		resolve: {
			extensions: [".tsx", ".ts", ".js"]
		},
		devtool: process.env.NODE_ENV === 'production'?false:'cheap-module-source-map'
	}
];
<|endoftext|>


<commit_before>'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const COMPONENT_NAME = process.env.COMPONENT_NAME;

if (!COMPONENT_NAME) {
  throw Error('COMPONENT_NAME is required');
}

const loaders = [
  {
    test: /\.css$/,
    loader: 'style!css?sourceMap&modules&localIdentName=[path][name]---[local]',
    include: [path.resolve('src/example')]
  },
  {test: /\.json$/, loader: 'json'},
  {
    test: /\.js$/,
    loader: 'babel',
    include: [path.resolve('src')]
  }
];

const definePlugin = new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
  }
});

const resolve = {extensions: ['', '.js']};
const stats = {colors: true};

const development = {
  devtool: '#source-map',

  entry: [
    './src/example/Example.js',
    'webpack-dev-server/client?http://localhost:8080'
  ],
  output: {filename: 'bundle.js', path: path.resolve('example')},
  plugins: [
    new HtmlWebpackPlugin(),
    definePlugin
  ],
  module: {
    loaders,
    preLoaders: [
      {test: /\.js$/, loader: 'eslint', include: [path.resolve('src')]}
    ]
  },
  resolve,
  stats,
  devServer: {
    historyApiFallback: true,
    stats: {
      // Do not show list of hundreds of files included in a bundle
      chunkModules: false,
      colors: true
    }
  }
};

const ghPages = {
  devtool: '#source-map',
  entry: './src/example/Example.js',
  output: {filename: 'bundle.js', path: path.resolve('example')},
  plugins: [new HtmlWebpackPlugin(), definePlugin],
  module: {loaders},
  resolve,
  stats
};

const dist = {
  devtool: '#source-map',
  entry: './src/index.js',
  output: {
    filename: `${require('./package.json').name}.js`,
    path: path.resolve('build'),
    library: COMPONENT_NAME,
    libraryTarget: 'umd'
  },
  plugins: [definePlugin],
  module: {loaders},
  resolve,
  stats,
  externals: {
    react: {root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react'}
  }
};

const min = {
  devtool: '#source-map',
  entry: './src/index.js',
  output: {
    filename: `${require('./package.json').name}.min.js`,
    path: path.resolve('build'),
    library: COMPONENT_NAME,
    libraryTarget: 'umd'
  },
  plugins: [
    definePlugin,
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  ],
  module: {loaders},
  resolve,
  stats,
  externals: {
    react: {root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react'}
  }
};

const test = {
  output: {libraryTarget: 'commonjs2'},
  module: {loaders}
};

const configs = {development, ghPages, dist, min, test};
const build = process.env.BUILD || process.env.NODE_ENV || 'development';

module.exports = configs[build];
<commit_msg>Use relative paths for webpack config<commit_after>'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const COMPONENT_NAME = process.env.COMPONENT_NAME;
const pathTo = path.join.bind(null, process.cwd());

if (!COMPONENT_NAME) {
  throw Error('COMPONENT_NAME is required');
}

const loaders = [
  {
    test: /\.css$/,
    loader: 'style!css?sourceMap&modules&localIdentName=[path][name]---[local]',
    include: [pathTo('src', 'example')]
  },
  {test: /\.json$/, loader: 'json'},
  {
    test: /\.js$/,
    loader: 'babel',
    include: [pathTo('src')]
  }
];

const definePlugin = new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
  }
});

const resolve = {extensions: ['', '.js']};
const stats = {colors: true};

const development = {
  devtool: '#source-map',

  entry: [
    pathTo('src', 'example', 'Example.js'),
    'webpack-dev-server/client?http://localhost:8080'
  ],
  output: {filename: 'bundle.js', path: pathTo('example')},
  plugins: [
    new HtmlWebpackPlugin(),
    definePlugin
  ],
  module: {
    loaders,
    preLoaders: [
      {test: /\.js$/, loader: 'eslint', include: [pathTo('src')]}
    ]
  },
  resolve,
  stats,
  devServer: {
    historyApiFallback: true,
    stats: {
      // Do not show list of hundreds of files included in a bundle
      chunkModules: false,
      colors: true
    }
  }
};

const ghPages = {
  devtool: '#source-map',
  entry: pathTo('src', 'example', 'Example.js'),
  output: {filename: 'bundle.js', path: pathTo('example')},
  plugins: [new HtmlWebpackPlugin(), definePlugin],
  module: {loaders},
  resolve,
  stats
};

const dist = {
  devtool: '#source-map',
  entry: pathTo('src', 'index.js'),
  output: {
    filename: `${require(pathTo('package.json')).name}.js`,
    path: pathTo('build'),
    library: COMPONENT_NAME,
    libraryTarget: 'umd'
  },
  plugins: [definePlugin],
  module: {loaders},
  resolve,
  stats,
  externals: {
    react: {root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react'}
  }
};

const min = {
  devtool: '#source-map',
  entry: pathTo('src', 'index.js'),
  output: {
    filename: `${require(pathTo('package.json')).name}.min.js`,
    path: pathTo('build'),
    library: COMPONENT_NAME,
    libraryTarget: 'umd'
  },
  plugins: [
    definePlugin,
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  ],
  module: {loaders},
  resolve,
  stats,
  externals: {
    react: {root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react'}
  }
};

const test = {
  output: {libraryTarget: 'commonjs2'},
  module: {loaders}
};

const configs = {development, ghPages, dist, min, test};
const build = process.env.BUILD || process.env.NODE_ENV || 'development';

module.exports = configs[build];
<|endoftext|>


<commit_before>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require("webpack");

let og_image_url = process.env.RIOT_OG_IMAGE_URL;
if (!og_image_url) og_image_url = 'https://riot.im/app/themes/riot/img/logos/riot-im-logo-black-text.png';

module.exports = (env, argv) => {
    if (process.env.CI_PACKAGE) {
        // Don't run minification for CI builds (this is only set for runs on develop)
        argv.mode = "development";
    }

    const development = {};
    if (argv.mode !== "production") {
        // This makes the sourcemaps human readable for developers. We use eval-source-map
        // because the plain source-map devtool ruins the alignment.
        development['devtool'] = 'eval-source-map';
    }

    // Resolve the directories for the react-sdk and js-sdk for later use. We resolve these early so we
    // don't have to call them over and over. We also resolve to the package.json instead of the src
    // directory so we don't have to rely on a index.js or similar file existing.
    const reactSdkSrcDir = path.resolve(require.resolve("matrix-react-sdk/package.json"), '..', 'src');
    const jsSdkSrcDir = path.resolve(require.resolve("matrix-js-sdk/package.json"), '..', 'src');

    return {
        ...development,

        entry: {
            "bundle": "./src/vector/index.js",
            "indexeddb-worker": "./src/vector/indexeddb-worker.js",
            "mobileguide": "./src/vector/mobile_guide/index.js",

            // CSS themes
            "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
            "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
            "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss",
            "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss",
        },

        optimization: {
            // Put all of our CSS into one useful place - this is needed for MiniCssExtractPlugin.
            // Previously we used a different extraction plugin that did this magic for us, but
            // now we need to consider that the CSS needs to be bundled up together.
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name: 'styles',
                        test: /\.css$/,
                        enforce: true,
                        // Do not add `chunks: 'all'` here because you'll break the app entry point.
                    },
                },
            },

            // This fixes duplicate files showing up in chrome with sourcemaps enabled.
            // See https://github.com/webpack/webpack/issues/7128 for more info.
            namedModules: false,

            // Minification is normally enabled by default for webpack in production mode, but
            // we use a CSS optimizer too and need to manage it ourselves.
            minimize: argv.mode === 'production',
            minimizer: argv.mode === 'production' ? [new TerserPlugin({}), new OptimizeCSSAssetsPlugin({})] : [],
        },

        resolve: {
            // We define an alternative import path so we can safely use src/ across the react-sdk
            // and js-sdk. We already import from src/ where possible to ensure our source maps are
            // extremely accurate (and because we're capable of compiling the layers manually rather
            // than relying on partially-mangled output from babel), though we do need to fix the
            // package level import (stuff like `import {Thing} from "matrix-js-sdk"` for example).
            // We can't use the aliasing down below to point at src/ because that'll fail to resolve
            // the package.json for the dependency. Instead, we rely on the package.json of each
            // layer to have our custom alternate fields to load things in the right order. These are
            // the defaults of webpack prepended with `matrix_src_`.
            mainFields: ['matrix_src_browser', 'matrix_src_main', 'browser', 'main'],
            aliasFields: ['matrix_src_browser', 'browser'],

            // We need to specify that TS can be resolved without an extension
            extensions: ['.js', '.json', '.ts'],
            alias: {
                // alias any requires to the react module to the one in our path,
                // otherwise we tend to get the react source included twice when
                // using `npm link` / `yarn link`.
                "react": path.resolve(__dirname, 'node_modules/react'),
                "react-dom": path.resolve(__dirname, 'node_modules/react-dom'),

                // same goes for js-sdk - we don't need two copies.
                "matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'),

                // Define a variable so the i18n stuff can load
                "$webapp": path.resolve(__dirname, 'webapp'),
            },
        },

        module: {
            noParse: [
                // for cross platform compatibility use [\\\/] as the path separator
                // this ensures that the regex trips on both Windows and *nix

                // don't parse the languages within highlight.js. They cause stack
                // overflows (https://github.com/webpack/webpack/issues/1721), and
                // there is no need for webpack to parse them - they can just be
                // included as-is.
                /highlight\.js[\\\/]lib[\\\/]languages/,

                // olm takes ages for webpack to process, and it's already heavily
                // optimised, so there is little to gain by us uglifying it.
                /olm[\\\/](javascript[\\\/])?olm\.js$/,
            ],
            rules: [
                {
                    test: /\.(ts|js)x?$/,
                    include: (f) => {
                        // our own source needs babel-ing
                        if (f.startsWith(path.resolve(__dirname, 'src'))) return true;

                        // we use the original source files of react-sdk and js-sdk, so we need to
                        // run them through babel. Because the path tested is the resolved, absolute
                        // path, these could be anywhere thanks to yarn link. We must also not
                        // include node modules inside these modules, so we add 'src'.
                        if (f.startsWith(reactSdkSrcDir)) return true;
                        if (f.startsWith(jsSdkSrcDir)) return true;

                        // but we can't run all of our dependencies through babel (many of them still
                        // use module.exports which breaks if babel injects an 'include' for its
                        // polyfills: probably fixable but babeling all our dependencies is probably
                        // not necessary anyway). So, for anything else, don't babel.
                        return false;
                    },
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use significantly fewer plugins on the plain
                                    // CSS parser. If we start to parse plain CSS, we end with all
                                    // kinds of nasty problems (like stylesheets not loading).
                                    //
                                    // You might have noticed that we're also sending regular CSS
                                    // through PostCSS. This looks weird, and in fact is probably
                                    // not what you'd expect, however in order for our CSS build
                                    // to work nicely we have to do this. Because down the line
                                    // our SCSS stylesheets reference plain CSS we have to load
                                    // the plain CSS through PostCSS so it can find it safely. This
                                    // also acts like a babel-for-css by transpiling our (S)CSS
                                    // down/up to the right browser support (prefixes, etc).
                                    // Further, if we don't do this then PostCSS assumes that our
                                    // plain CSS is SCSS and it really doesn't like that, even
                                    // though plain CSS should be compatible. The chunking options
                                    // at the top of this webpack config help group the SCSS and
                                    // plain CSS together for the bundler.

                                    require("postcss-simple-vars")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use slightly different plugins for SCSS.

                                    require('postcss-import')(),
                                    require("postcss-simple-vars")(),
                                    require("postcss-extend")(),
                                    require("postcss-nested")(),
                                    require("postcss-mixins")(),
                                    require("postcss-easings")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.wasm$/,
                    loader: "file-loader",
                    type: "javascript/auto", // https://github.com/webpack/webpack/issues/6725
                    options: {
                        name: '[name].[hash:7].[ext]',
                        outputPath: '.',
                    },
                },
                {
                    // cache-bust languages.json file placed in
                    // riot-web/webapp/i18n during build by copy-res.js
                    test: /\.*languages.json$/,
                    type: "javascript/auto",
                    loader: 'file-loader',
                    options: {
                        name: 'i18n/[name].[hash:7].[ext]',
                    },
                },
                {
                    test: /\.(gif|png|svg|ttf|woff|woff2|xml|ico)$/,
                    // Use a content-based hash in the name so that we can set a long cache
                    // lifetime for assets while still delivering changes quickly.
                    oneOf: [
                        {
                            // Assets referenced in CSS files
                            issuer: /\.(scss|css)$/,
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    // CSS image usages end up in the `bundles/[hash]` output
                                    // directory, so we adjust the final path to navigate up
                                    // twice.
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(path.join("../..", outputPath));
                                },
                            },
                        },
                        {
                            // Assets referenced in HTML and JS files
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(outputPath);
                                },
                            },
                        },
                    ],
                },
            ]
        },

        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV),
                },
            }),

            // This exports our CSS using the splitChunks and loaders above.
            new MiniCssExtractPlugin({
                filename: 'bundles/[hash]/[name].css',
                ignoreOrder: false, // Enable to remove warnings about conflicting order
            }),

            // This is the app's main entry point.
            new HtmlWebpackPlugin({
                template: './src/vector/index.html',

                // we inject the links ourselves via the template, because
                // HtmlWebpackPlugin will screw up our formatting like the names
                // of the themes and which chunks we actually care about.
                inject: false,
                excludeChunks: ['mobileguide'],
                minify: argv.mode === 'production',
                vars: {
                    og_image_url: og_image_url,
                },
            }),

            // This is the mobile guide's entry point (separate for faster mobile loading)
            new HtmlWebpackPlugin({
                template: './src/vector/mobile_guide/index.html',
                filename: 'mobile_guide/index.html',
                minify: argv.mode === 'production',
                chunks: ['mobileguide'],
            }),
        ],

        output: {
            path: path.join(__dirname, "webapp"),

            // The generated JS (and CSS, from the extraction plugin) are put in a
            // unique subdirectory for the build. There will only be one such
            // 'bundle' directory in the generated tarball; however, hosting
            // servers can collect 'bundles' from multiple versions into one
            // directory and symlink it into place - this allows users who loaded
            // an older version of the application to continue to access webpack
            // chunks even after the app is redeployed.
            filename: "bundles/[hash]/[name].js",
            chunkFilename: "bundles/[hash]/[name].js",
        },

        // configuration for the webpack-dev-server
        devServer: {
            // serve unwebpacked assets from webapp.
            contentBase: './webapp',

            stats: {
                // don't fill the console up with a mahoosive list of modules
                chunks: false,
            },

            // hot module replacement doesn't work (I think we'd need react-hot-reload?)
            // so webpack-dev-server reloads the page on every update which is quite
            // tedious in Riot since that can take a while.
            hot: false,
            inline: false,
        },
    };
};

/**
 * Merge assets found via CSS and imports into a single tree, while also preserving
 * directories under `res`.
 *
 * @param {string} url The adjusted name of the file, such as `warning.1234567.svg`.
 * @param {string} resourcePath The absolute path to the source file with unmodified name.
 * @return {string} The returned paths will look like `img/warning.1234567.svg`.
 */
function getImgOutputPath(url, resourcePath) {
    const prefix = /^.*[/\\]res[/\\]/;
    const outputDir = path.dirname(resourcePath).replace(prefix, "");
    return path.join(outputDir, path.basename(url));
}

/**
 * Convert path to public path format, which always uses forward slashes, since it will
 * be placed directly into things like CSS files.
 *
 * @param {string} path Some path to a file.
 */
function toPublicPath(path) {
    return path.replace(/\\/g, '/');
}
<commit_msg>Change to minimal Webpack output<commit_after>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require("webpack");

let og_image_url = process.env.RIOT_OG_IMAGE_URL;
if (!og_image_url) og_image_url = 'https://riot.im/app/themes/riot/img/logos/riot-im-logo-black-text.png';

module.exports = (env, argv) => {
    if (process.env.CI_PACKAGE) {
        // Don't run minification for CI builds (this is only set for runs on develop)
        argv.mode = "development";
    }

    const development = {};
    if (argv.mode !== "production") {
        // This makes the sourcemaps human readable for developers. We use eval-source-map
        // because the plain source-map devtool ruins the alignment.
        development['devtool'] = 'eval-source-map';
    }

    // Resolve the directories for the react-sdk and js-sdk for later use. We resolve these early so we
    // don't have to call them over and over. We also resolve to the package.json instead of the src
    // directory so we don't have to rely on a index.js or similar file existing.
    const reactSdkSrcDir = path.resolve(require.resolve("matrix-react-sdk/package.json"), '..', 'src');
    const jsSdkSrcDir = path.resolve(require.resolve("matrix-js-sdk/package.json"), '..', 'src');

    return {
        ...development,

        entry: {
            "bundle": "./src/vector/index.js",
            "indexeddb-worker": "./src/vector/indexeddb-worker.js",
            "mobileguide": "./src/vector/mobile_guide/index.js",

            // CSS themes
            "theme-light": "./node_modules/matrix-react-sdk/res/themes/light/css/light.scss",
            "theme-dark": "./node_modules/matrix-react-sdk/res/themes/dark/css/dark.scss",
            "theme-light-custom": "./node_modules/matrix-react-sdk/res/themes/light-custom/css/light-custom.scss",
            "theme-dark-custom": "./node_modules/matrix-react-sdk/res/themes/dark-custom/css/dark-custom.scss",
        },

        optimization: {
            // Put all of our CSS into one useful place - this is needed for MiniCssExtractPlugin.
            // Previously we used a different extraction plugin that did this magic for us, but
            // now we need to consider that the CSS needs to be bundled up together.
            splitChunks: {
                cacheGroups: {
                    styles: {
                        name: 'styles',
                        test: /\.css$/,
                        enforce: true,
                        // Do not add `chunks: 'all'` here because you'll break the app entry point.
                    },
                },
            },

            // This fixes duplicate files showing up in chrome with sourcemaps enabled.
            // See https://github.com/webpack/webpack/issues/7128 for more info.
            namedModules: false,

            // Minification is normally enabled by default for webpack in production mode, but
            // we use a CSS optimizer too and need to manage it ourselves.
            minimize: argv.mode === 'production',
            minimizer: argv.mode === 'production' ? [new TerserPlugin({}), new OptimizeCSSAssetsPlugin({})] : [],
        },

        resolve: {
            // We define an alternative import path so we can safely use src/ across the react-sdk
            // and js-sdk. We already import from src/ where possible to ensure our source maps are
            // extremely accurate (and because we're capable of compiling the layers manually rather
            // than relying on partially-mangled output from babel), though we do need to fix the
            // package level import (stuff like `import {Thing} from "matrix-js-sdk"` for example).
            // We can't use the aliasing down below to point at src/ because that'll fail to resolve
            // the package.json for the dependency. Instead, we rely on the package.json of each
            // layer to have our custom alternate fields to load things in the right order. These are
            // the defaults of webpack prepended with `matrix_src_`.
            mainFields: ['matrix_src_browser', 'matrix_src_main', 'browser', 'main'],
            aliasFields: ['matrix_src_browser', 'browser'],

            // We need to specify that TS can be resolved without an extension
            extensions: ['.js', '.json', '.ts'],
            alias: {
                // alias any requires to the react module to the one in our path,
                // otherwise we tend to get the react source included twice when
                // using `npm link` / `yarn link`.
                "react": path.resolve(__dirname, 'node_modules/react'),
                "react-dom": path.resolve(__dirname, 'node_modules/react-dom'),

                // same goes for js-sdk - we don't need two copies.
                "matrix-js-sdk": path.resolve(__dirname, 'node_modules/matrix-js-sdk'),

                // Define a variable so the i18n stuff can load
                "$webapp": path.resolve(__dirname, 'webapp'),
            },
        },

        module: {
            noParse: [
                // for cross platform compatibility use [\\\/] as the path separator
                // this ensures that the regex trips on both Windows and *nix

                // don't parse the languages within highlight.js. They cause stack
                // overflows (https://github.com/webpack/webpack/issues/1721), and
                // there is no need for webpack to parse them - they can just be
                // included as-is.
                /highlight\.js[\\\/]lib[\\\/]languages/,

                // olm takes ages for webpack to process, and it's already heavily
                // optimised, so there is little to gain by us uglifying it.
                /olm[\\\/](javascript[\\\/])?olm\.js$/,
            ],
            rules: [
                {
                    test: /\.(ts|js)x?$/,
                    include: (f) => {
                        // our own source needs babel-ing
                        if (f.startsWith(path.resolve(__dirname, 'src'))) return true;

                        // we use the original source files of react-sdk and js-sdk, so we need to
                        // run them through babel. Because the path tested is the resolved, absolute
                        // path, these could be anywhere thanks to yarn link. We must also not
                        // include node modules inside these modules, so we add 'src'.
                        if (f.startsWith(reactSdkSrcDir)) return true;
                        if (f.startsWith(jsSdkSrcDir)) return true;

                        // but we can't run all of our dependencies through babel (many of them still
                        // use module.exports which breaks if babel injects an 'include' for its
                        // polyfills: probably fixable but babeling all our dependencies is probably
                        // not necessary anyway). So, for anything else, don't babel.
                        return false;
                    },
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use significantly fewer plugins on the plain
                                    // CSS parser. If we start to parse plain CSS, we end with all
                                    // kinds of nasty problems (like stylesheets not loading).
                                    //
                                    // You might have noticed that we're also sending regular CSS
                                    // through PostCSS. This looks weird, and in fact is probably
                                    // not what you'd expect, however in order for our CSS build
                                    // to work nicely we have to do this. Because down the line
                                    // our SCSS stylesheets reference plain CSS we have to load
                                    // the plain CSS through PostCSS so it can find it safely. This
                                    // also acts like a babel-for-css by transpiling our (S)CSS
                                    // down/up to the right browser support (prefixes, etc).
                                    // Further, if we don't do this then PostCSS assumes that our
                                    // plain CSS is SCSS and it really doesn't like that, even
                                    // though plain CSS should be compatible. The chunking options
                                    // at the top of this webpack config help group the SCSS and
                                    // plain CSS together for the bundler.

                                    require("postcss-simple-vars")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.scss$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 1,
                                sourceMap: true,
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            ident: 'postcss',
                            options: {
                                sourceMap: true,
                                plugins: () => [
                                    // Note that we use slightly different plugins for SCSS.

                                    require('postcss-import')(),
                                    require("postcss-simple-vars")(),
                                    require("postcss-extend")(),
                                    require("postcss-nested")(),
                                    require("postcss-mixins")(),
                                    require("postcss-easings")(),
                                    require("postcss-strip-inline-comments")(),

                                    // It's important that this plugin is last otherwise we end
                                    // up with broken CSS.
                                    require('postcss-preset-env')({stage: 3, browsers: 'last 2 versions'}),
                                ],
                                parser: "postcss-scss",
                                "local-plugins": true,
                            },
                        },
                    ]
                },
                {
                    test: /\.wasm$/,
                    loader: "file-loader",
                    type: "javascript/auto", // https://github.com/webpack/webpack/issues/6725
                    options: {
                        name: '[name].[hash:7].[ext]',
                        outputPath: '.',
                    },
                },
                {
                    // cache-bust languages.json file placed in
                    // riot-web/webapp/i18n during build by copy-res.js
                    test: /\.*languages.json$/,
                    type: "javascript/auto",
                    loader: 'file-loader',
                    options: {
                        name: 'i18n/[name].[hash:7].[ext]',
                    },
                },
                {
                    test: /\.(gif|png|svg|ttf|woff|woff2|xml|ico)$/,
                    // Use a content-based hash in the name so that we can set a long cache
                    // lifetime for assets while still delivering changes quickly.
                    oneOf: [
                        {
                            // Assets referenced in CSS files
                            issuer: /\.(scss|css)$/,
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    // CSS image usages end up in the `bundles/[hash]` output
                                    // directory, so we adjust the final path to navigate up
                                    // twice.
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(path.join("../..", outputPath));
                                },
                            },
                        },
                        {
                            // Assets referenced in HTML and JS files
                            loader: 'file-loader',
                            options: {
                                esModule: false,
                                name: '[name].[hash:7].[ext]',
                                outputPath: getImgOutputPath,
                                publicPath: function(url, resourcePath) {
                                    const outputPath = getImgOutputPath(url, resourcePath);
                                    return toPublicPath(outputPath);
                                },
                            },
                        },
                    ],
                },
            ]
        },

        plugins: [
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify(process.env.NODE_ENV),
                },
            }),

            // This exports our CSS using the splitChunks and loaders above.
            new MiniCssExtractPlugin({
                filename: 'bundles/[hash]/[name].css',
                ignoreOrder: false, // Enable to remove warnings about conflicting order
            }),

            // This is the app's main entry point.
            new HtmlWebpackPlugin({
                template: './src/vector/index.html',

                // we inject the links ourselves via the template, because
                // HtmlWebpackPlugin will screw up our formatting like the names
                // of the themes and which chunks we actually care about.
                inject: false,
                excludeChunks: ['mobileguide'],
                minify: argv.mode === 'production',
                vars: {
                    og_image_url: og_image_url,
                },
            }),

            // This is the mobile guide's entry point (separate for faster mobile loading)
            new HtmlWebpackPlugin({
                template: './src/vector/mobile_guide/index.html',
                filename: 'mobile_guide/index.html',
                minify: argv.mode === 'production',
                chunks: ['mobileguide'],
            }),
        ],

        output: {
            path: path.join(__dirname, "webapp"),

            // The generated JS (and CSS, from the extraction plugin) are put in a
            // unique subdirectory for the build. There will only be one such
            // 'bundle' directory in the generated tarball; however, hosting
            // servers can collect 'bundles' from multiple versions into one
            // directory and symlink it into place - this allows users who loaded
            // an older version of the application to continue to access webpack
            // chunks even after the app is redeployed.
            filename: "bundles/[hash]/[name].js",
            chunkFilename: "bundles/[hash]/[name].js",
        },

        // configuration for the webpack-dev-server
        devServer: {
            // serve unwebpacked assets from webapp.
            contentBase: './webapp',

            // Only output errors, warnings, or new compilations.
            // This hides the massive list of modules.
            stats: 'minimal',

            // hot module replacement doesn't work (I think we'd need react-hot-reload?)
            // so webpack-dev-server reloads the page on every update which is quite
            // tedious in Riot since that can take a while.
            hot: false,
            inline: false,
        },
    };
};

/**
 * Merge assets found via CSS and imports into a single tree, while also preserving
 * directories under `res`.
 *
 * @param {string} url The adjusted name of the file, such as `warning.1234567.svg`.
 * @param {string} resourcePath The absolute path to the source file with unmodified name.
 * @return {string} The returned paths will look like `img/warning.1234567.svg`.
 */
function getImgOutputPath(url, resourcePath) {
    const prefix = /^.*[/\\]res[/\\]/;
    const outputDir = path.dirname(resourcePath).replace(prefix, "");
    return path.join(outputDir, path.basename(url));
}

/**
 * Convert path to public path format, which always uses forward slashes, since it will
 * be placed directly into things like CSS files.
 *
 * @param {string} path Some path to a file.
 */
function toPublicPath(path) {
    return path.replace(/\\/g, '/');
}
<|endoftext|>