const { merge } = require("webpack-merge"); const path = require("path"); const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin; const DefinePlugin = require("webpack").DefinePlugin; const { WebpackManifestPlugin } = require("webpack-manifest-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const ExternalTemplateRemotesPlugin = require("external-remotes-plugin"); const CopyPlugin = require("copy-webpack-plugin"); const TerserPlugin = require("terser-webpack-plugin"); const minifyJson = require("@docspace/common/utils/minifyJson"); const runtime = require("../../runtime.json"); const dateHash = runtime?.date || ""; //const beforeBuild = require("@docspace/common/utils/beforeBuild"); const sharedDeps = require("@docspace/common/constants/sharedDependencies"); const baseConfig = require("./webpack.base.js"); for (let dep in sharedDeps) { sharedDeps[dep].eager = true; } const clientConfig = { target: "web", // mode: "development", entry: { client: ["./src/client/index.js"], }, devtool: "inline-cheap-module-source-map", output: { path: path.resolve(process.cwd(), "dist/client"), filename: "static/js/[name].[contenthash].bundle.js", publicPath: "/doceditor/", chunkFilename: "static/js/[id].[contenthash].js", assetModuleFilename: (pathData) => { //console.log({ pathData }); let result = pathData.filename .substr(pathData.filename.indexOf("public/")) .split("/") .slice(1); result.pop(); let folder = result.join("/"); folder += result.length === 0 ? "" : "/"; return `static/${folder}[name][ext]?hash=[contenthash]`; //`${folder}/[name].[contenthash][ext]`; }, }, performance: { maxEntrypointSize: 512000, maxAssetSize: 512000, }, module: { rules: [ { test: /\.json$/, resourceQuery: /url/, type: "javascript/auto", use: [ { loader: "file-loader", options: { emitFile: false, name: (resourcePath) => { let result = resourcePath .split(`public${path.sep}`)[1] .split(path.sep); result.pop(); let folder = result.join("/"); folder += result.length === 0 ? "" : "/"; return `${folder}[name].[ext]?hash=[contenthash]`; // `${folder}/[name].[contenthash][ext]`; }, }, }, ], }, { test: /\.s[ac]ss$/i, use: [ // Creates `style` nodes from JS strings "style-loader", // Translates CSS into CommonJS { loader: "css-loader", options: { url: { filter: (url, resourcePath) => { // resourcePath - path to css file // Don't handle `/static` urls if (url.startsWith("/static") || url.startsWith("data:")) { return false; } return true; }, }, }, }, // Compiles Sass to CSS "sass-loader", ], }, ], }, plugins: [ new CleanWebpackPlugin(), new ModuleFederationPlugin({ name: "editor", filename: "remoteEntry.js", remotes: { client: "client@/remoteEntry.js", }, exposes: { "./app": "./src/client/index.js", }, shared: { ...sharedDeps }, }), new ExternalTemplateRemotesPlugin(), new CopyPlugin({ patterns: [ { context: path.resolve(process.cwd(), "public"), from: "locales/**/*.json", transform: minifyJson, }, ], }), new WebpackManifestPlugin(), ], }; module.exports = (env, argv) => { if (argv.mode === "production") { clientConfig.mode = "production"; clientConfig.optimization = { splitChunks: { chunks: "all" }, minimize: !env.minimize, minimizer: [new TerserPlugin()], }; } else { clientConfig.mode = "development"; clientConfig.devtool = "cheap-module-source-map"; } clientConfig.plugins = [ ...clientConfig.plugins, new DefinePlugin({ IS_DEVELOPMENT: argv.mode !== "production", PORT: process.env.PORT || 5013, IS_PERSONAL: env.personal || false, BROWSER_DETECTOR_URL: JSON.stringify( `/static/scripts/browserDetector.js?hash=${ runtime.checksums["browserDetector.js"] || dateHash }` ), CONFIG_URL: JSON.stringify( `/static/scripts/config.json?hash=${ runtime.checksums["config.json"] || dateHash }` ), }), ]; return merge(baseConfig, clientConfig); };