"use strict";

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

function _react() {
  const data = _interopRequireDefault(require("react"));

  _react = function _react() {
    return data;
  };

  return data;
}

function _path() {
  const data = require("path");

  _path = function _path() {
    return data;
  };

  return data;
}

function _autoprefixer() {
  const data = _interopRequireDefault(require("autoprefixer"));

  _autoprefixer = function _autoprefixer() {
    return data;
  };

  return data;
}

var _normalizeTheme = _interopRequireDefault(require("./normalizeTheme"));

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

function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(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; }

const DEFAULT_BROWSERS = ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9' // React doesn't support IE8 anyway
];

function _default(webpackConfig, opts) {
  const isDev = process.env.NODE_ENV === 'development';

  const cssOpts = _objectSpread({
    importLoaders: 1,
    sourceMap: !opts.disableCSSSourceMap
  }, opts.cssLoaderOptions || {}); // should pass down opts.cwd


  const theme = (0, _normalizeTheme.default)(opts.theme, opts);
  const postcssOptions = {
    // Necessary for external CSS imports to work
    // https://github.com/facebookincubator/create-react-app/issues/2677
    ident: 'postcss',
    plugins: () => [require('postcss-flexbugs-fixes'), // eslint-disable-line
    (0, _autoprefixer().default)(_objectSpread({
      overrideBrowserslist: opts.browserslist || DEFAULT_BROWSERS,
      flexbox: 'no-2009'
    }, opts.autoprefixer || {})), ...(opts.extraPostCSSPlugins ? opts.extraPostCSSPlugins : []), ...(isDev || process.env.CSS_COMPRESS === 'none' || process.env.COMPRESS === 'none' || process.env.NO_COMPRESS ? [] : [require('cssnano')({
      preset: ['default', opts.cssnano || {
        mergeRules: false,
        // ref: https://github.com/umijs/umi/issues/955
        normalizeUrl: false
      }]
    })])]
  };
  const cssModulesConfig = {
    modules: true,
    localIdentName: cssOpts.localIdentName || (isDev ? '[name]__[local]___[hash:base64:5]' : '[local]___[hash:base64:5]')
  };

  const lessOptions = _objectSpread({
    modifyVars: theme,
    javascriptEnabled: true
  }, opts.lessLoaderOptions || {});

  let hasSassLoader = true;

  try {
    require.resolve('sass-loader');
  } catch (e) {
    hasSassLoader = false;
  }

  function applyCSSRules(rule, {
    cssModules,
    less,
    sass,
    stylus
  }) {
    if (!opts.ssr) {
      if (opts.styleLoader) {
        rule.use('style-loader').loader(require.resolve('style-loader')).options({
          base: opts.styleLoader.base || 0,
          convertToAbsoluteUrls: true
        });
      } else {
        rule.use('extract-css-loader').loader(require('mini-css-extract-plugin').loader).options({
          publicPath: isDev ? '/' : opts.cssPublicPath,
          hmr: isDev
        });
      }
    } // https://github.com/webpack-contrib/mini-css-extract-plugin/issues/90


    const cssLoader = opts.cssLoaderVersion === 2 ? opts.ssr ? 'css-loader/locals' : 'css-loader' : opts.ssr ? 'css-loader-1/locals' : 'css-loader-1';

    if (isDev && cssModules && opts.generateCssModulesTypings) {
      rule.use('css-modules-typescript-loader').loader(require.resolve('css-modules-typescript-loader'));
    }

    rule.use('css-loader').loader(require.resolve(cssLoader)).options(_objectSpread({}, cssOpts, {}, cssModules ? cssModulesConfig : {}));
    rule.use('postcss-loader').loader(require.resolve('postcss-loader')).options(postcssOptions);

    if (less) {
      rule.use('less-loader').loader(require.resolve('less-loader')).options(lessOptions);
    }

    if (sass && hasSassLoader) {
      rule.use('sass-loader').loader(require.resolve('sass-loader')).options(opts.sass);
    } // 开始添加 stylus 支持


    if (stylus) {
      const _ref = opts.stylus || {},
            _ref$loader = _ref.loader,
            stylusLoader = _ref$loader === void 0 ? 'stylus-loader' : _ref$loader,
            _ref$options = _ref.options,
            stylusOptions = _ref$options === void 0 ? {
        preferPathResolver: 'webpack'
      } : _ref$options,
            poststylus = _ref.poststylus; // 避免项目启动时出现异常 Error: Cannot find module 'stylus-loader'


      let stylusLoaderPath;

      try {
        stylusLoaderPath = require.resolve(stylusLoader); // eslint-disable-next-line no-empty
      } catch (e) {} // 如果安装了 stylus-loader 模块


      if (stylusLoaderPath) {
        rule.use('stylus-loader').loader(stylusLoaderPath).options(stylusOptions); // 如果使用了 poststylus, 需要移除 postcss-loader

        if (poststylus) {
          rule.delete('postcss-loader');
        }
      }
    }
  }

  if (opts.cssModulesExcludes) {
    opts.cssModulesExcludes.forEach((exclude, index) => {
      const rule = `cssModulesExcludes_${index}`;
      const config = webpackConfig.module.rule(rule).test(filePath => {
        if (exclude instanceof RegExp) {
          return exclude.test(filePath);
        } else {
          return filePath.indexOf(exclude) > -1;
        }
      });
      const ext = (0, _path().extname)(exclude).toLowerCase();
      applyCSSRules(config, {
        less: ext === '.less',
        sass: ext === '.sass' || ext === '.scss',
        stylus: ext === '.styl' || ext === '.stylus'
      });
    });
  }

  if (opts.cssModulesWithAffix) {
    applyCSSRules(webpackConfig.module.rule('.module.css').test(/\.module\.css$/), {
      cssModules: true
    });
    applyCSSRules(webpackConfig.module.rule('.module.less').test(/\.module\.less$/), {
      cssModules: true,
      less: true
    });
    applyCSSRules(webpackConfig.module.rule('.module.sass').test(/\.module\.(sass|scss)$/), {
      cssModules: true,
      sass: true
    });
    applyCSSRules(webpackConfig.module.rule('.module.stylus').test(/\.module\.styl(us)?$/), {
      cssModules: true,
      stylus: true
    });
  }

  function cssExclude(filePath) {
    if (/node_modules/.test(filePath)) {
      return true;
    }

    if (opts.cssModulesWithAffix) {
      if (/\.module\.(css|less|sass|scss|styl(us)?)$/.test(filePath)) return true;
    }

    if (opts.cssModulesExcludes) {
      var _iterator = _createForOfIteratorHelper(opts.cssModulesExcludes),
          _step;

      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          const exclude = _step.value;
          if (filePath.indexOf(exclude) > -1) return true;
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
    }

    return false;
  }

  applyCSSRules(webpackConfig.module.rule('css').test(/\.css$/).exclude.add(cssExclude).end(), {
    cssModules: !opts.disableCSSModules
  });
  applyCSSRules(webpackConfig.module.rule('css-in-node_modules').test(/\.css$/).include.add(/node_modules/).end(), {});
  applyCSSRules(webpackConfig.module.rule('less').test(/\.less$/).exclude.add(cssExclude).end(), {
    cssModules: !opts.disableCSSModules,
    less: true
  });
  applyCSSRules(webpackConfig.module.rule('less-in-node_modules').test(/\.less$/).include.add(/node_modules/).end(), {
    less: true
  });
  applyCSSRules(webpackConfig.module.rule('sass').test(/\.(sass|scss)$/).exclude.add(cssExclude).end(), {
    cssModules: !opts.disableCSSModules,
    sass: true
  });
  applyCSSRules(webpackConfig.module.rule('sass-in-node_modules').test(/\.(sass|scss)$/).include.add(/node_modules/).end(), {
    sass: true
  });
  applyCSSRules(webpackConfig.module.rule('stylus').test(/\.styl(us)?$/).exclude.add(cssExclude).end(), {
    cssModules: !opts.disableCSSModules,
    stylus: true
  });
  applyCSSRules(webpackConfig.module.rule('stylus-in-node_modules').test(/\.styl(us)?$/).include.add(/node_modules/).end(), {
    stylus: true
  });
  const hash = !isDev && opts.hash ? '.[contenthash:8]' : '';

  if (!opts.ssr && !opts.styleLoader) {
    webpackConfig.plugin('extract-css').use(require('mini-css-extract-plugin'), [{
      filename: `[name]${hash}.css`,
      chunkFilename: `[name]${hash}.chunk.css`
    }]);
  }
}