"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = createClientConfig;

var _assetsWebpackPlugin = _interopRequireDefault(require("assets-webpack-plugin"));

var _offlinePlugin = _interopRequireDefault(require("offline-plugin"));

var _uglifyjsWebpackPlugin = _interopRequireDefault(require("uglifyjs-webpack-plugin"));

var _lodash = _interopRequireDefault(require("lodash"));

var _errorOverlayMiddleware = _interopRequireDefault(require("react-dev-utils/errorOverlayMiddleware"));

var _path = _interopRequireDefault(require("path"));

var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");

var _webpack = require("webpack");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function createClientConfig(config, {
  platform,
  webpackConfig
}) {
  const action = config.action,
        env = config.env,
        host = config.host,
        offline = config.offline,
        options = config.options,
        paths = config.paths,
        platformName = config.platformName,
        ports = config.ports;
  webpackConfig = _objectSpread({}, webpackConfig, {
    entry: {
      client: [_path.default.resolve(paths.platform, 'client.js')]
    },
    externals: _objectSpread({}, webpackConfig.externals, {
      child_process: '{}',
      deasync: '{}',
      fs: '{}',
      winston: '{}'
    }),
    resolve: _objectSpread({}, webpackConfig.resolve, {
      alias: _objectSpread({}, _lodash.default.get(webpackConfig, 'resolve.alias'), {
        '@reactant/web-isomorphic/ClientRoot': _path.default.resolve(paths.platform, 'ClientRoot.js')
      }),
      extensions: _lodash.default.uniq([`.${platform.properties.name}.client.js`, `.${platform.properties.name}.client.json`, `.${platform.properties.name}.client.jsx`, `.${platform.properties.name}.client.mjs`, `.${platformName}.client.js`, `.${platformName}.client.json`, `.${platformName}.client.jsx`, `.${platformName}.client.mjs`, ..._lodash.default.get(webpackConfig, 'resolve.extensions', [])])
    }),
    plugins: [...webpackConfig.plugins, new _assetsWebpackPlugin.default({
      path: paths.dist,
      filename: 'assets.json'
    }), new _webpack.IgnorePlugin(/^child_process$/), new _webpack.IgnorePlugin(/^deasync$/), new _webpack.IgnorePlugin(/^fs$/), new _webpack.IgnorePlugin(/^winston$/)]
  });

  if (env === 'development') {
    webpackConfig = _objectSpread({}, webpackConfig, {
      output: {
        path: _path.default.resolve(paths.dist, 'public'),
        publicPath: action === 'start' ? `http://${host}:${ports.dev}/` : '/',
        pathinfo: true,
        filename: 'scripts/bundle.js',
        chunkFilename: 'scripts/[name].chunk.js',
        devtoolModuleFilenameTemplate: info => {
          return _path.default.resolve(info.resourcePath).replace(/\\/g, '/');
        }
      }
    });
  } else {
    webpackConfig = _objectSpread({}, webpackConfig, {
      optimization: {
        concatenateModules: true,
        flagIncludedChunks: true,
        mangleWasmImports: true,
        mergeDuplicateChunks: true,
        minimize: true,
        occurrenceOrder: true,
        providedExports: true,
        removeAvailableModules: true,
        removeEmptyChunks: true,
        sideEffects: true,
        minimizer: [new _uglifyjsWebpackPlugin.default({
          uglifyOptions: {
            compress: {
              warnings: false,
              comparisons: false,
              drop_console: true
            },
            output: {
              comments: false
            }
          },
          sourceMap: true
        })],
        splitChunks: {
          chunks: 'all'
        }
      },
      output: {
        path: _path.default.resolve(paths.dist, 'public'),
        publicPath: '/',
        filename: 'scripts/bundle.[hash:8].js',
        chunkFilename: 'scripts/[name].[hash:8].chunk.js'
      }
    });
  }

  if (action === 'start') {
    webpackConfig = _objectSpread({}, webpackConfig, {
      entry: {
        client: [...webpackConfig.entry.client, require.resolve('../hotDevClient')]
      },
      devServer: {
        before(app) {
          app.use((0, _errorOverlayMiddleware.default)());
        },

        compress: true,
        disableHostCheck: true,
        headers: {
          'Access-Control-Allow-Origin': '*'
        },
        historyApiFallback: {
          disableDotRule: true
        },
        host,
        hot: true,
        noInfo: !options.debug,
        overlay: false,
        port: ports.dev,
        quiet: false,
        watchOptions: {
          ignored: /node_modules/
        }
      }
    });
  }

  if (config.options.analyze) {
    webpackConfig = _objectSpread({}, webpackConfig, {
      plugins: [...webpackConfig.plugins, new _webpackBundleAnalyzer.BundleAnalyzerPlugin({
        analyzerPort: ports.analyzer,
        analyzerMode: 'static'
      })]
    });
  }

  if (offline) {
    webpackConfig = _objectSpread({}, webpackConfig, {
      plugins: [...webpackConfig.plugins, new _offlinePlugin.default({
        publicPath: _path.default.resolve(paths.dist, 'public')
      })]
    });
  } else {
    webpackConfig = _objectSpread({}, webpackConfig, {
      plugins: [...webpackConfig.plugins, new _webpack.IgnorePlugin(/^offline-plugin\/runtime/)]
    });
  }

  return webpackConfig;
}