<|start_filename|>client/webpack/FsWatchPlugin.js<|end_filename|>
const fs = require('fs');
const path = require('path');

module.exports = class {
    constructor(settings = {extraRootFolders: [], extraFolders: [], extraFiles: []}) {
        this._extraFiles = settings.extraFiles;
        this._extraFolders = settings.extraFolders;
        this._extraRootFolders = settings.extraRootFolders;
    }

    // noinspection JSUnusedGlobalSymbols
    apply(compiler) {
        compiler.hooks.afterCompile.tap('LimoncelloFsWatch', (compilation) => {
            const webpackFiles = Array.isArray(compilation.fileDependencies) ? compilation.fileDependencies : [];
            const webpackFolders = Array.isArray(compilation.contextDependencies) ? compilation.contextDependencies : [];

            let extraFolders = [];
            this._extraRootFolders.forEach(extraRootFolder => {
                extraFolders = extraFolders.concat(this.addAllNestedFolders(extraRootFolder));
            });

            compilation.fileDependencies = this.constructor.makeUniqueAndNonNull(
                webpackFiles.concat(this._extraFiles)
            );
            compilation.contextDependencies = this.constructor.makeUniqueAndNonNull(
                webpackFolders.concat(extraFolders).concat(this._extraRootFolders).concat(this._extraFolders)
            );
        });
    }

    addAllNestedFolders(root, folders = []) {
        fs.readdirSync(root).forEach(fileOrFolder => {
            const fullPath = path.resolve(root, fileOrFolder);
            if (fs.lstatSync(fullPath).isDirectory() === true) {
                folders.push(fullPath);
                this.addAllNestedFolders(fullPath, folders);
            }
        });

        return folders;
    }

    static makeUniqueAndNonNull(array) {
        return array.filter((value, index, self) => value != null && self.indexOf(value) === index);
    }
};


<|start_filename|>client/webpack/development.config.js<|end_filename|>
'use strict';

let baseConfig = require('./base.config.js');

baseConfig.mode = 'development';
baseConfig.devtool = "inline-source-map";

module.exports = baseConfig;


<|start_filename|>client/webpack/base.config.js<|end_filename|>
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FsWatchPlugin = require('./FsWatchPlugin');

const assetsSubFolder = 'assets';
const publicDir = path.resolve(__dirname, '..', '..', 'public');
const outputDir = path.resolve(publicDir, assetsSubFolder);
const srcRootFolder = path.resolve(__dirname, '..', 'src');

module.exports = {
    entry: {
        index: path.resolve(srcRootFolder, 'index.ts')
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'ts-loader',
                        options: {
                            configFile: path.resolve(srcRootFolder, 'tsconfig.json')
                        }
                    }
                ],
            }, {
                test: /\.(scss)$/,
                use: [{
                    loader: 'style-loader', // inject CSS to page
                }, {
                    loader: 'css-loader', // translates CSS into CommonJS modules
                }, {
                    loader: 'postcss-loader', // Run post css actions
                    options: 'precss,autoprefixer'
                }, {
                    loader: 'sass-loader' // compiles Sass to CSS
                }]
            }, {
                test: /\.(jpe|jpg|woff|woff2|eot|ttf|svg)/,
                loader: 'file-loader'
            }
        ]
    },
    plugins: [
        // hack with `root` dir. Otherwise the files are not removed because they are 'outside of the project root'.
        new CleanWebpackPlugin('*.*', {root: outputDir}),

        new FsWatchPlugin({
            extraRootFolders: [
                path.resolve(__dirname, '..', 'src'),
                path.resolve(__dirname, '..', '..', 'server', 'resources', 'views'),
            ]
        }),
    ],
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    },
    output: {
        // https://webpack.js.org/configuration/output/#output-librarytarget
        libraryTarget: 'var',
        publicPath: `/${assetsSubFolder}/`,
        path: outputDir,
        filename: '[name].js',
    },
    devServer: {
        contentBase: publicDir,
        compress: true,
        port: 8080,
        stats: 'minimal',
        proxy: [{
            context: ['**', '!/assets/**', '!/img/**'],
            target: 'http://localhost:8090',
        }],
    },
};


<|start_filename|>client/webpack/production.config.js<|end_filename|>
'use strict';

let baseConfig = require('./base.config.js');

baseConfig.mode = 'production';
baseConfig.devtool = 'source-map';

module.exports = baseConfig;
