diff --git a/landing/webpack.config.cjs b/landing/webpack.config.cjs index 357316730..33ad66f8c 100644 --- a/landing/webpack.config.cjs +++ b/landing/webpack.config.cjs @@ -1,104 +1,82 @@ const AssetsPlugin = require('assets-webpack-plugin'); const path = require('path'); -const webpack = require('webpack'); const { createProdBrowserConfig, createDevBrowserConfig, createNodeServerRenderingConfig, } = require('lib/webpack/shared.cjs'); const babelConfig = require('./babel.config.cjs'); const baseBrowserConfig = { entry: { browser: ['./script.js'], }, output: { filename: 'prod.[hash:12].build.js', path: path.join(__dirname, 'dist'), }, resolve: { alias: { '../images': path.resolve('../keyserver/images'), }, }, }; const baseDevBrowserConfig = { ...baseBrowserConfig, output: { ...baseBrowserConfig.output, filename: 'dev.build.js', pathinfo: true, publicPath: 'http://localhost:8082/', }, devServer: { hot: true, port: 8082, contentBase: path.join(__dirname, 'dist'), headers: { 'Access-Control-Allow-Origin': '*' }, allowedHosts: ['all'], host: '0.0.0.0', }, }; const baseProdBrowserConfig = { ...baseBrowserConfig, plugins: [ new AssetsPlugin({ filename: 'assets.json', path: path.join(__dirname, 'dist'), }), ], }; const baseNodeServerRenderingConfig = { externals: ['react', 'react-dom', 'react-redux'], entry: { server: ['./landing-ssr.react.js'], }, output: { filename: 'landing.build.cjs', library: 'landing', libraryTarget: 'commonjs2', path: path.join(__dirname, 'dist'), }, }; -const alchemyKey = process.env.COMM_ALCHEMY_KEY; - module.exports = function (env) { - const rawBrowserConfig = + const browserConfig = env === 'prod' ? createProdBrowserConfig(baseProdBrowserConfig, babelConfig) : createDevBrowserConfig(baseDevBrowserConfig, babelConfig); - const browserConfig = { - ...rawBrowserConfig, - plugins: [ - ...rawBrowserConfig.plugins, - new webpack.DefinePlugin({ - 'process.env': { - COMM_ALCHEMY_KEY: JSON.stringify(alchemyKey), - }, - }), - ], - }; - const baseNodeConfig = createNodeServerRenderingConfig( + const nodeConfig = createNodeServerRenderingConfig( baseNodeServerRenderingConfig, babelConfig, ); - const nodeConfig = { - ...baseNodeConfig, + const nodeServerRenderingConfig = { + ...nodeConfig, mode: env === 'prod' ? 'production' : 'development', - plugins: [ - ...baseNodeConfig.plugins, - new webpack.DefinePlugin({ - 'process.env': { - COMM_ALCHEMY_KEY: JSON.stringify(alchemyKey), - }, - }), - ], }; - return [browserConfig, nodeConfig]; + return [browserConfig, nodeServerRenderingConfig]; }; diff --git a/lib/webpack/shared.cjs b/lib/webpack/shared.cjs index 29d125e12..8b6171812 100644 --- a/lib/webpack/shared.cjs +++ b/lib/webpack/shared.cjs @@ -1,242 +1,253 @@ const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const webpack = require('webpack'); const sharedPlugins = [ new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1, }), ]; const cssLoader = { loader: 'css-loader', options: { modules: { mode: 'local', localIdentName: '[path][name]__[local]--[hash:base64:5]', }, }, }; const cssExtractLoader = { loader: MiniCssExtractPlugin.loader, options: { esModule: true, }, }; const styleLoader = { loader: 'style-loader', options: { esModule: true, }, }; function getBabelRule(babelConfig) { return { test: /\.js$/, exclude: /node_modules\/(?!lib)/, loader: 'babel-loader', options: babelConfig, }; } function getBrowserBabelRule(babelConfig) { const babelRule = getBabelRule(babelConfig); return { ...babelRule, options: { ...babelRule.options, presets: [ ...babelRule.options.presets, [ '@babel/preset-env', { targets: 'defaults', useBuiltIns: 'usage', corejs: '3.6', }, ], ], }, }; } const imageRule = { test: /\.(png|svg)$/, use: ['url-loader'], }; const typographyRule = { test: /\.(woff2|woff)$/, use: ['url-loader'], }; function createBaseBrowserConfig(baseConfig) { return { ...baseConfig, name: 'browser', optimization: { minimizer: [new TerserPlugin(), new OptimizeCssAssetsPlugin()], }, plugins: [ ...(baseConfig.plugins ?? []), ...sharedPlugins, new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: [], }), ], }; } +const alchemyKey = process.env.COMM_ALCHEMY_KEY; + function createProdBrowserConfig(baseConfig, babelConfig) { const browserConfig = createBaseBrowserConfig(baseConfig); const babelRule = getBrowserBabelRule(babelConfig); return { ...browserConfig, mode: 'production', plugins: [ ...browserConfig.plugins, new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production'), BROWSER: true, + COMM_ALCHEMY_KEY: JSON.stringify(alchemyKey), }, }), new MiniCssExtractPlugin({ filename: 'prod.[contenthash:12].build.css', }), ], module: { rules: [ { ...babelRule, options: { ...babelRule.options, plugins: [ ...babelRule.options.plugins, '@babel/plugin-transform-react-constant-elements', ['transform-remove-console', { exclude: ['error', 'warn'] }], ], }, }, { test: /\.css$/, exclude: /node_modules\/.*\.css$/, use: [ cssExtractLoader, { ...cssLoader, options: { ...cssLoader.options, url: false, }, }, ], }, { test: /node_modules\/.*\.css$/, sideEffects: true, use: [ cssExtractLoader, { ...cssLoader, options: { ...cssLoader.options, url: false, modules: false, }, }, ], }, ], }, }; } function createDevBrowserConfig(baseConfig, babelConfig) { const browserConfig = createBaseBrowserConfig(baseConfig); const babelRule = getBrowserBabelRule(babelConfig); return { ...browserConfig, mode: 'development', plugins: [ ...browserConfig.plugins, new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('development'), BROWSER: true, + COMM_ALCHEMY_KEY: JSON.stringify(alchemyKey), }, }), new ReactRefreshWebpackPlugin(), ], module: { rules: [ { ...babelRule, options: { ...babelRule.options, plugins: [ require.resolve('react-refresh/babel'), ...babelRule.options.plugins, ], }, }, imageRule, typographyRule, { test: /\.css$/, exclude: /node_modules\/.*\.css$/, use: [styleLoader, cssLoader], }, { test: /node_modules\/.*\.css$/, use: [ styleLoader, { ...cssLoader, options: { ...cssLoader.options, modules: false, }, }, ], }, ], }, devtool: 'eval-cheap-module-source-map', }; } function createNodeServerRenderingConfig(baseConfig, babelConfig) { return { ...baseConfig, name: 'server', target: 'node', module: { rules: [ getBabelRule(babelConfig), { test: /\.css$/, use: { ...cssLoader, options: { ...cssLoader.options, modules: { ...cssLoader.options.modules, exportOnlyLocals: true, }, }, }, }, ], }, - plugins: sharedPlugins, + plugins: [ + ...sharedPlugins, + new webpack.DefinePlugin({ + 'process.env': { + COMM_ALCHEMY_KEY: JSON.stringify(alchemyKey), + }, + }), + ], }; } module.exports = { createProdBrowserConfig, createDevBrowserConfig, createNodeServerRenderingConfig, };