mirror of
				https://github.com/strapi/strapi.git
				synced 2025-11-04 03:43:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
const path = require('path');
 | 
						|
const fse = require('fs-extra');
 | 
						|
const webpack = require('webpack');
 | 
						|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 | 
						|
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
 | 
						|
const HtmlWebpackPlugin = require('html-webpack-plugin');
 | 
						|
const { ESBuildMinifyPlugin } = require('esbuild-loader');
 | 
						|
const WebpackBar = require('webpackbar');
 | 
						|
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
 | 
						|
const browserslist = require('browserslist');
 | 
						|
const browserslistToEsbuild = require('browserslist-to-esbuild');
 | 
						|
 | 
						|
const alias = require('./webpack.alias');
 | 
						|
const getClientEnvironment = require('./env');
 | 
						|
const createPluginsExcludePath = require('./utils/create-plugins-exclude-path');
 | 
						|
 | 
						|
const EE_REGEX = /from.* ['"]ee_else_ce\//;
 | 
						|
 | 
						|
module.exports = ({
 | 
						|
  cacheDir,
 | 
						|
  dest,
 | 
						|
  entry,
 | 
						|
  env,
 | 
						|
  optimize,
 | 
						|
  pluginsPath,
 | 
						|
  options = {
 | 
						|
    backend: 'http://localhost:1337',
 | 
						|
    adminPath: '/admin/',
 | 
						|
    features: [],
 | 
						|
  },
 | 
						|
  roots = {
 | 
						|
    eeRoot: './ee/admin',
 | 
						|
    ceRoot: './admin/src',
 | 
						|
  },
 | 
						|
  tsConfigFilePath,
 | 
						|
}) => {
 | 
						|
  const isProduction = env === 'production';
 | 
						|
 | 
						|
  const envVariables = getClientEnvironment({ ...options, env });
 | 
						|
 | 
						|
  const webpackPlugins = isProduction
 | 
						|
    ? [
 | 
						|
        new MiniCssExtractPlugin({
 | 
						|
          filename: '[name].[chunkhash].css',
 | 
						|
          chunkFilename: '[name].[chunkhash].chunkhash.css',
 | 
						|
          ignoreOrder: true,
 | 
						|
        }),
 | 
						|
        new WebpackBar(),
 | 
						|
      ]
 | 
						|
    : [];
 | 
						|
 | 
						|
  const excludeRegex = createPluginsExcludePath(pluginsPath);
 | 
						|
 | 
						|
  // Ensure we use the config in this directory, even if run with a different
 | 
						|
  // working directory
 | 
						|
  const browserslistConfig = browserslist.loadConfig({ path: __dirname });
 | 
						|
  const buildTarget = browserslistToEsbuild(browserslistConfig);
 | 
						|
 | 
						|
  return {
 | 
						|
    mode: isProduction ? 'production' : 'development',
 | 
						|
    bail: !!isProduction,
 | 
						|
    devtool: isProduction ? false : 'eval-source-map',
 | 
						|
    experiments: {
 | 
						|
      topLevelAwait: true,
 | 
						|
    },
 | 
						|
    entry: [entry],
 | 
						|
    output: {
 | 
						|
      path: dest,
 | 
						|
      publicPath: options.adminPath,
 | 
						|
      // Utilize long-term caching by adding content hashes (not compilation hashes)
 | 
						|
      // to compiled assets for production
 | 
						|
      filename: isProduction ? '[name].[contenthash:8].js' : '[name].bundle.js',
 | 
						|
      chunkFilename: isProduction ? '[name].[contenthash:8].chunk.js' : '[name].chunk.js',
 | 
						|
    },
 | 
						|
    optimization: {
 | 
						|
      minimize: optimize,
 | 
						|
      minimizer: [
 | 
						|
        new ESBuildMinifyPlugin({
 | 
						|
          target: buildTarget,
 | 
						|
          css: true, // Apply minification to CSS assets
 | 
						|
        }),
 | 
						|
      ],
 | 
						|
      moduleIds: 'deterministic',
 | 
						|
      runtimeChunk: true,
 | 
						|
    },
 | 
						|
    module: {
 | 
						|
      rules: [
 | 
						|
        {
 | 
						|
          test: /\.tsx?$/,
 | 
						|
          loader: require.resolve('esbuild-loader'),
 | 
						|
          include: [cacheDir, ...pluginsPath],
 | 
						|
          exclude: excludeRegex,
 | 
						|
          options: {
 | 
						|
            loader: 'tsx',
 | 
						|
            target: buildTarget,
 | 
						|
          },
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.m?jsx?$/,
 | 
						|
          include: cacheDir,
 | 
						|
          oneOf: [
 | 
						|
            // Use babel-loader for files that distinct the ee and ce code
 | 
						|
            // These files have an import Something from 'ee_else_ce/
 | 
						|
            {
 | 
						|
              test(filePath) {
 | 
						|
                if (!filePath) {
 | 
						|
                  return false;
 | 
						|
                }
 | 
						|
 | 
						|
                try {
 | 
						|
                  const fileContent = fse.readFileSync(filePath).toString();
 | 
						|
 | 
						|
                  if (fileContent.match(/from.* ['"]ee_else_ce\//)) {
 | 
						|
                    return true;
 | 
						|
                  }
 | 
						|
 | 
						|
                  return EE_REGEX.test(fileContent);
 | 
						|
                } catch (e) {
 | 
						|
                  return false;
 | 
						|
                }
 | 
						|
              },
 | 
						|
              use: {
 | 
						|
                loader: require.resolve('babel-loader'),
 | 
						|
                options: {
 | 
						|
                  cacheDirectory: true,
 | 
						|
                  cacheCompression: isProduction,
 | 
						|
                  compact: isProduction,
 | 
						|
                  presets: [
 | 
						|
                    require.resolve('@babel/preset-env'),
 | 
						|
                    require.resolve('@babel/preset-react'),
 | 
						|
                  ],
 | 
						|
                  plugins: [
 | 
						|
                    [
 | 
						|
                      require.resolve('@strapi/babel-plugin-switch-ee-ce'),
 | 
						|
                      {
 | 
						|
                        // Imported this tells the custom plugin where to look for the ee folder
 | 
						|
                        roots,
 | 
						|
                      },
 | 
						|
                    ],
 | 
						|
 | 
						|
                    [
 | 
						|
                      require.resolve('@babel/plugin-transform-runtime'),
 | 
						|
                      {
 | 
						|
                        helpers: true,
 | 
						|
                        regenerator: true,
 | 
						|
                      },
 | 
						|
                    ],
 | 
						|
                    [require.resolve('babel-plugin-styled-components'), { pure: true }],
 | 
						|
                  ],
 | 
						|
                },
 | 
						|
              },
 | 
						|
            },
 | 
						|
            // Use esbuild-loader for the other files
 | 
						|
            {
 | 
						|
              use: {
 | 
						|
                loader: require.resolve('esbuild-loader'),
 | 
						|
                options: {
 | 
						|
                  loader: 'jsx',
 | 
						|
                  target: buildTarget,
 | 
						|
                },
 | 
						|
              },
 | 
						|
            },
 | 
						|
          ],
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.m?jsx?$/,
 | 
						|
          include: pluginsPath,
 | 
						|
          use: {
 | 
						|
            loader: require.resolve('esbuild-loader'),
 | 
						|
            options: {
 | 
						|
              loader: 'jsx',
 | 
						|
              target: buildTarget,
 | 
						|
            },
 | 
						|
          },
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * This is used to avoid webpack import errors where
 | 
						|
         * the origin is strict EcmaScript Module.
 | 
						|
         *
 | 
						|
         * e. g. a module with javascript mimetype, a '.mjs' file,
 | 
						|
         * or a '.js' file where the package.json contains '"type": "module"'
 | 
						|
         */
 | 
						|
        {
 | 
						|
          test: /\.m?jsx?$/,
 | 
						|
          resolve: {
 | 
						|
            fullySpecified: false,
 | 
						|
          },
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.css$/i,
 | 
						|
          use: ['style-loader', 'css-loader'],
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.(svg|eot|otf|ttf|woff|woff2)$/,
 | 
						|
          type: 'asset/resource',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/, /\.ico$/],
 | 
						|
          type: 'asset',
 | 
						|
          parser: {
 | 
						|
            dataUrlCondition: {
 | 
						|
              maxSize: 1000,
 | 
						|
            },
 | 
						|
          },
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.html$/,
 | 
						|
          include: [path.join(__dirname, 'src')],
 | 
						|
          use: require.resolve('html-loader'),
 | 
						|
        },
 | 
						|
        {
 | 
						|
          test: /\.(mp4|webm)$/,
 | 
						|
          type: 'asset',
 | 
						|
          parser: {
 | 
						|
            dataUrlCondition: {
 | 
						|
              maxSize: 10000,
 | 
						|
            },
 | 
						|
          },
 | 
						|
        },
 | 
						|
      ],
 | 
						|
    },
 | 
						|
    resolve: {
 | 
						|
      alias,
 | 
						|
      symlinks: false,
 | 
						|
      extensions: ['.js', '.jsx', '.react.js', '.ts', '.tsx'],
 | 
						|
      mainFields: ['browser', 'module', 'jsnext:main', 'main'],
 | 
						|
      modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
 | 
						|
    },
 | 
						|
    plugins: [
 | 
						|
      new HtmlWebpackPlugin({
 | 
						|
        inject: true,
 | 
						|
        template: path.resolve(__dirname, 'index.html'),
 | 
						|
      }),
 | 
						|
      new webpack.DefinePlugin(envVariables),
 | 
						|
 | 
						|
      new ForkTsCheckerPlugin({
 | 
						|
        typescript: {
 | 
						|
          configFile: tsConfigFilePath,
 | 
						|
        },
 | 
						|
      }),
 | 
						|
 | 
						|
      !isProduction && process.env.REACT_REFRESH !== 'false' && new ReactRefreshWebpackPlugin(),
 | 
						|
 | 
						|
      ...webpackPlugins,
 | 
						|
    ].filter(Boolean),
 | 
						|
  };
 | 
						|
};
 |