const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const autoprefixer = require('autoprefixer');

module.exports = {
  cache: true,
  stats: {
    children: true,
  },
  resolve: {
    fallback: {
      'process/browser': require.resolve('process/browser'),
      path: require.resolve('path-browserify'),
      buffer: require.resolve('buffer/'),
      stream: require.resolve("stream-browserify")
    },
    alias: {
      // React のインスタンスが複数存在することによる問題を防ぐため、
      // プロジェクト内で常に同じ React モジュールを使用するようにエイリアスを設定。
      react: path.resolve('./node_modules/react'),
      // 同様に、ReactDOM もプロジェクト内で一貫して同じインスタンスを使用するためにエイリアスを設定。
      'react-dom': path.resolve('./node_modules/react-dom'),
    }
  },
  entry: {
    index: './ablogcms/js/src/index.js',
    admin: './ablogcms/js/src/admin.js',
  },
  output: {
    path: path.join(__dirname, 'ablogcms/'),
    publicPath: '',
    filename: 'js/dest/[name].js',
    chunkFilename: `js/dest/[name].chunk.js?date=${new Date().getTime()}`,
    assetModuleFilename: 'js/dest/assets/[name][ext]',
    uniqueName: 'acmsWebpackJsonp',
  },
  externals: {
    jquery: 'jQuery',
  },
  optimization: {
    splitChunks: {
      name: 'vendor',
      chunks: 'initial',
      cacheGroups: {
        vendorAdmin: {
          test: /(styled-components|prop-types|react|react-dom)[\\/]/,
          name: 'vendor-admin',
          chunks: 'all',
          enforce: true,
        },
      },
    },
  },
  module: {
    rules: [
      {
        test: /\.(js|ts|tsx)$/,
        include: [/js\/src/, /node_modules\/punycode/],
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.(scss|css)$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../../',
            },
          },
          {
            loader: 'css-loader',
            options: {
              url: true,
              // 0 => no loaders (default);
              // 1 => postcss-loader;
              // 2 => postcss-loader, sass-loader
              importLoaders: 2,
              sourceMap: true,
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  autoprefixer({
                    grid: true,
                  }),
                ],
              },
              sourceMap: true,
            },
          },
        ],
      },
      {
        test: /\.(jpg|png|svg|woff|woff2|eot|ttf)(\?.*$|$)/,
        type: 'asset',
        sideEffects: true, // webpack 5.105+ でアセットが side-effect free 扱いになり tree-shake されるのを防ぐ
        parser: {
          dataUrlCondition: {
            maxSize: 4 * 1024, // <--- 4kb
          },
        },
      },
    ],
  },
  plugins: [
    new ESLintPlugin({
      context: './ablogcms/js/src',
      extensions: ['js', 'ts', 'tsx', 'jsx'],
      exclude: ['/node_modules/'],
      emitError: true,
      emitWarning: true,
      failOnError: true,
      fix: true,
    }),
    new webpack.ProvidePlugin({
      process: 'process/browser',
      Buffer: ['buffer', 'Buffer'],
    }),
    new MiniCssExtractPlugin({
      filename: 'js/dest/[name].css',
      chunkFilename: `js/dest/[name].chunk.css?date=${new Date().getTime()}`,
    }),
  ],
};
