const path = require("path"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const TerserPlugin = require("terser-webpack-plugin"); const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const isDev = process.env.NODE_ENV === "development"; /** * Base configuration shared by both FREE and PRO builds */ const baseConfig = { mode: isDev ? "development" : "production", entry: { "pdf-builder-react": "./src/js/react/index.tsx", "pdf-builder-react-executor": "./src/js/pdf-builder-react-executor.js", "settings-tabs": "./src/js/admin/settings-tabs.js", "settings-main": "./src/js/admin/settings-main.js", "canvas-settings": "./src/js/admin/canvas-settings.js", "pdf-builder-react-init": "./src/js/admin/pdf-builder-react-init.js", "pdf-builder-react-wrapper": "./src/js/admin/pdf-builder-react-wrapper.js", "ajax-throttle": "./src/js/admin/ajax-throttle.js", notifications: "./src/js/admin/notifications.js", "pdf-builder-wrap": "./src/js/admin/pdf-builder-wrap.js", "pdf-builder-init": "./src/js/admin/pdf-builder-init.js", // Admin React pages "dashboard-page-react": "./src/js/admin/dashboard-page-react.tsx", "upgrade-modals-react": "./src/js/admin/upgrade-modals-react.tsx", "licence-page-react": "./src/js/admin/licence-page-react.tsx", // CSS bundles "notifications-css": "./src/css/notifications.css", "dashboard-css": "./src/css/dashboard.css", "templates-page-css": "./src/css/templates-page.css", "pdf-builder-admin-css": "./src/css/pdf-builder-admin.css", }, devtool: isDev ? "eval-source-map" : false, performance: { maxEntrypointSize: 1024000, // 1MB maxAssetSize: 1024000, // 1MB hints: isDev ? false : "warning", }, module: { rules: [ { test: /\.(ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: [ [ "@babel/preset-env", { useBuiltIns: "entry", corejs: 3, modules: false, }, ], ["@babel/preset-react", { runtime: "automatic" }], "@babel/preset-typescript", ], cacheDirectory: true, }, }, }, { test: /\.css$/, use: [ isDev ? "style-loader" : MiniCssExtractPlugin.loader, { loader: "css-loader", options: { sourceMap: isDev, }, }, { loader: "postcss-loader", options: { sourceMap: isDev, }, }, ], }, { test: /\.(woff|woff2|eot|ttf|otf)$/, type: "asset/resource", generator: { filename: "../fonts/[name][ext]", }, }, ], }, resolve: { extensions: [".ts", ".tsx", ".js", ".jsx", ".json"], alias: { "@components": path.resolve(__dirname, "src/js/react/components/"), "@hooks": path.resolve(__dirname, "src/js/react/hooks/"), "@utils": path.resolve(__dirname, "src/js/react/utils/"), "@contexts": path.resolve(__dirname, "src/js/react/contexts/"), "@types": path.resolve(__dirname, "src/js/react/types/"), "@styles": path.resolve(__dirname, "src/js/react/styles/"), }, }, plugins: [ new MiniCssExtractPlugin({ filename: "../css/[name].min.css", chunkFilename: "../css/[name].chunk.css", }), ], optimization: { minimize: !isDev, minimizer: [ new TerserPlugin({ terserOptions: { compress: { drop_console: true, drop_debugger: true, passes: 2, pure_funcs: [], }, mangle: { properties: false, }, output: { comments: false, }, }, extractComments: false, }), new CssMinimizerPlugin({ minimizerOptions: { preset: [ "default", { discardComments: { removeAll: true }, }, ], }, }), ], runtimeChunk: false, splitChunks: { chunks: (chunk) => { return chunk.name !== "pdf-builder-react" && chunk.name !== "runtime"; }, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: "vendors", priority: 10, reuseExistingChunk: true, minChunks: 1, }, common: { name: "common", minChunks: 2, priority: 5, reuseExistingChunk: true, minSize: 10000, }, }, }, }, cache: { type: "filesystem", cacheDirectory: path.resolve(__dirname, ".webpack_cache"), }, stats: { colors: true, modules: false, children: false, chunks: false, chunkModules: false, errors: true, errorDetails: true, warnings: true, publicPath: true, performance: true, timings: true, }, }; /** * FREE version: output to plugin-free/assets/js * IMPORTANT: No upgrade-modals-react (promotional content removed) */ const freeConfig = { ...baseConfig, name: "free", entry: { "pdf-builder-react": "./src/js/react/index.tsx", "pdf-builder-react-executor": "./src/js/pdf-builder-react-executor.js", "settings-tabs": "./src/js/admin/settings-tabs.js", "settings-main": "./src/js/admin/settings-main.js", "canvas-settings": "./src/js/admin/canvas-settings.js", "pdf-builder-react-init": "./src/js/admin/pdf-builder-react-init.js", "pdf-builder-react-wrapper": "./src/js/admin/pdf-builder-react-wrapper.js", "ajax-throttle": "./src/js/admin/ajax-throttle.js", notifications: "./src/js/admin/notifications.js", "pdf-builder-wrap": "./src/js/admin/pdf-builder-wrap.js", "pdf-builder-init": "./src/js/admin/pdf-builder-init.js", // Admin React pages (FREE edition - no premium content) "dashboard-page-react": "./src/js/admin/dashboard-page-react-free.tsx", // NO upgrade-modals-react for FREE! "licence-page-react": "./src/js/admin/licence-page-react.tsx", // CSS bundles "notifications-css": "./src/css/notifications.css", "dashboard-css": "./src/css/dashboard.css", "templates-page-css": "./src/css/templates-page.css", "pdf-builder-admin-css": "./src/css/pdf-builder-admin.css", }, output: { path: path.resolve(__dirname, "plugin-free/assets/js"), filename: "[name].min.js", chunkFilename: "[name].min.js", globalObject: 'typeof window !== "undefined" ? window : global', clean: false, assetModuleFilename: "../assets/[name][ext]", }, }; /** * PRO version: output to plugin-pro/assets/js */ const proConfig = { ...baseConfig, name: "pro", output: { path: path.resolve(__dirname, "plugin-pro/assets/js"), filename: "[name].min.js", chunkFilename: "[name].min.js", globalObject: 'typeof window !== "undefined" ? window : global', clean: false, assetModuleFilename: "../assets/[name][ext]", }, }; /** * Export both configs as array * webpack --name free → builds FREE version * webpack --name pro → builds PRO version * webpack → builds both */ module.exports = [freeConfig, proConfig];