text: const webpack = require('webpack')
  const path = require('path')
  const fileSystem = require('fs')
  const env = require('./utils/env')
  const { CleanWebpackPlugin } = require('clean-webpack-plugin')
  const CopyWebpackPlugin = require('copy-webpack-plugin')
  const HtmlWebpackPlugin = require('html-webpack-plugin')
  const ProgressBarPlugin = require('progress-bar-webpack-plugin')
  const MiniCssExtractPlugin = require('mini-css-extract-plugin')
  
  const srcPath = (subdir) => {
    return path.join(__dirname, 'src/js', subdir)
  }
  
  const alias = {
    background: srcPath('background'),
    components: srcPath('components'),
    libs: srcPath('libs'),
    stores: srcPath('stores'),
    svgIcons: srcPath('svgIcons'),
    img: path.join(__dirname, 'src/img')
  }
  
  const secretsPath = path.join(__dirname, 'secrets.' + env.NODE_ENV + '.js')
  
  const fileExtensions = [
    'jpg',
    'jpeg',
    'png',
    'gif',
    'eot',
    'otf',
    'svg',
    'ttf',
    'woff',
    'woff2'
  ]
  
  if (fileSystem.existsSync(secretsPath)) {
    alias.secrets = secretsPath
  }
  
  const imgDir = path.join(__dirname, 'src/img')
  const images = fileSystem
    .readdirSync(imgDir)
    .filter((x) => x.endsWith('.png'))
    .map((x) => path.join(imgDir, x))
  
  const HtmlFiles = ['popup'].map(
    (name) =>
      new HtmlWebpackPlugin({
        template: path.join(__dirname, 'src', `${name}.html`),
        filename: `${name}.html`,
        chunks: [name],
        minify: {
          collapseWhitespace: true
        }
      })
  )
  
  const entry = Object.assign(
    ...['popup', 'background', 'run', 'base'].map((name) => ({
      [name]: path.join(__dirname, 'src', 'js', `${name}.tsx`)
    }))
  )
  
  const options = {
    entry,
    output: {
      path: path.join(__dirname, 'build'),
      filename: '[name].js'
    },
    module: {
      rules: [
        {
          test: /\.m?js/,
          type: 'javascript/auto',
          resolve: {
            fullySpecified: false
          }
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader']
        },
        {
          test: new RegExp(`\\.(${fileExtensions.join('|')})$`),
          loader: 'file-loader',
          options: {
            name: '[name].[ext]'
          },
          include: path.resolve(__dirname, 'src'),
          exclude: /node_modules/
        },
        {
          test: /\.html$/,
          loader: 'html-loader',
          include: path.resolve(__dirname, 'src'),
          exclude: /node_modules/
        },
        {
          test: /\.(js|ts)x?$/,
          use: [
            {
              loader: 'ts-loader',
              options: {
                transpileOnly: true,
                experimentalWatchApi: true
              }
            }
          ],
          include: path.resolve(__dirname, 'src')
        }
      ]
    },
    resolve: {
      alias,
      extensions: fileExtensions
        .map((extension) => '.' + extension)
        .concat(['.css', '.jsx', '.js', '.tsx', 'ts'])
    },
    plugins: [
      // expose and write the allowed env vars on the compiled bundle
      new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
      new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[id].css'
      }),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV)
      }),
      new CopyWebpackPlugin({
        patterns: [
          ...images,
          {
            from: 'src/manifest.json',
            transform: function (content, path) {
              return Buffer.from(
                JSON.stringify({
                  description: process.env.npm_package_description,
                  version: process.env.npm_package_version,
                  ...JSON.parse(content.toString())
                })
              )
            }
          }
        ]
      }),
      ...HtmlFiles,
      new ProgressBarPlugin()
    ]
  }
  
  if (env.NODE_ENV === 'development') {
    options.devtool = 'eval-cheap-source-map'
  }
  
  module.exports = (plugins = []) => ({
    ...options,
    plugins: [...options.plugins, ...plugins]
  })
  