{"size": 3321, "ext": "js", "max_stars_repo_path": "util/webpack.js", "max_stars_repo_name": "toyobayashi/ty", "max_stars_repo_stars_event_min_datetime": "2019-08-23T02:20:37.000Z", "max_stars_repo_stars_event_max_datetime": "2019-12-17T09:21:38.000Z", "max_issues_repo_path": "util/webpack.js", "max_issues_repo_name": "toyobayashi/ty", "max_issues_repo_issues_event_min_datetime": "2019-12-03T15:50:49.000Z", "max_issues_repo_issues_event_max_datetime": "2020-08-31T07:16:59.000Z", "max_forks_repo_path": "util/webpack.js", "max_forks_repo_name": "toyobayashi/ty", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 5, "max_issues_count": 4, "max_forks_count": null, "avg_line_length": 27.675, "max_line_length": 108, "alphanum_fraction": 0.6693766938}
let webpack
try {
  webpack = require('webpack')
} catch (_) {
  throw new Error('webpack is not found, try to run `npm install -D webpack` first')
}
const webpackVersion = Number(webpack.version.charAt(0))

const camelcase = require('camelcase')
const uppercamelcase = require('uppercamelcase')

function compile (config, statsOptions) {
  return new Promise((resolve, reject) => {
    webpack(config, (err, stats) => {
      if (err) {
        console.log(err)
        return reject(err)
      }
      console.log(stats.toString(statsOptions) + '\n')
      resolve()
    })
  })
}

function watch (config, handler) {
  const compiler = webpack(config)
  compiler.watch({
    aggregateTimeout: 200,
    poll: undefined
  }, handler)
  return compiler
}

function startDevServer (configuration, port, host, callback) {
  let WebpackDevServer
  try {
    WebpackDevServer = require('webpack-dev-server')
  } catch (_) {
    throw new Error('webpack-dev-server is not found, try to run `npm install -D webpack-dev-server` first')
  }

  const devServerOptions = configuration.devServer || {}
  WebpackDevServer.addDevServerEntrypoints(configuration, devServerOptions)
  const server = new WebpackDevServer(webpack(configuration), devServerOptions)

  return server.listen(port, host, callback)
}

function copyExtraResources (config, webpackConfig, needWatch, watchCallback) {
  const fs = require('fs-extra')
  const chokidar = require('chokidar')
  const { relative, join } = require('path')
  const minimatch = require('minimatch')

  const filter = [
    '**/.gitkeep',
    '**/.DS_Store'
  ]

  const extraResourcesPath = webpackConfig.pathUtil.getPath(config.extraResourcesPath)
  const localResourcesPath = webpackConfig.pathUtil.getPath(config.localResourcesPath)
  if (fs.existsSync(extraResourcesPath)) {
    fs.copySync(
      extraResourcesPath,
      localResourcesPath,
      { filter: (src) => !filter.map(g => minimatch(src, g)).includes(true) }
    )
    if (needWatch) {
      const watcher = chokidar.watch(extraResourcesPath)
      watcher.on('all', (event, p) => {
        if (filter.map(g => minimatch(p, g)).includes(true)) {
          return
        }
        const rp = relative(extraResourcesPath, p)
        const tp = join(localResourcesPath, rp)
        if (event === 'unlink' || event === 'unlinkDir') {
          fs.removeSync(tp)
        } else {
          fs.copySync(p, tp, { filter: (src) => !src.endsWith('.gitkeep') })
        }
        if (typeof watchCallback === 'function') {
          watchCallback(event, p)
        }
      })
    }
  }
}

function getLoaderPath (config, name) {
  const camel = camelcase(name)
  if (typeof config.loaderPath[camel] === 'string') {
    return config.loaderPath[camel]
  }
  return require.resolve(name)
}

function getPluginImplementation (config, name) {
  const uppercame = uppercamelcase(name)
  if (typeof config.pluginImplementation[uppercame] === 'function') {
    return config.pluginImplementation[uppercame]
  }
  return require(name)
}

function isWebpack5plus (config) {
  return typeof config.webpack === 'number' ? (config.webpack > 4) : (webpackVersion > 4)
}

module.exports = {
  webpack,
  webpackVersion,
  compile,
  watch,
  startDevServer,
  copyExtraResources,
  getLoaderPath,
  getPluginImplementation,
  isWebpack5plus
}
