From a96c52b21e7e590bbdd70b80896780a446fa2e8b Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 13 Dec 2021 02:07:04 +0100 Subject: build: separate module for frontend This allows us to simplify the webpack configuration and the gradle build scripts. --- subprojects/frontend/webpack.config.js | 164 +++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 subprojects/frontend/webpack.config.js (limited to 'subprojects/frontend/webpack.config.js') diff --git a/subprojects/frontend/webpack.config.js b/subprojects/frontend/webpack.config.js new file mode 100644 index 00000000..bacb7e4a --- /dev/null +++ b/subprojects/frontend/webpack.config.js @@ -0,0 +1,164 @@ +const fs = require('fs'); +const path = require('path'); + +const { DefinePlugin } = require('webpack'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity'); + +const packageInfo = require('./package.json'); + +const currentNodeEnv = process.env.NODE_ENV || 'development'; +const devMode = currentNodeEnv !== 'production'; +const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv); + +function portNumberOrElse (envName, fallback) { + const value = process.env[envName]; + return value ? parseInt(value) : fallback; +} + +const listenHost = process.env['LISTEN_HOST'] || 'localhost'; +const listenPort = portNumberOrElse('LISTEN_PORT', 1313); +const apiHost = process.env['API_HOST'] || listenHost; +const apiPort = portNumberOrElse('API_PORT', 1312); +const publicHost = process.env['PUBLIC_HOST'] || listenHost; +const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); + +module.exports = { + mode: devMode ? 'development' : 'production', + entry: './src/index', + output: { + path: outputPath, + publicPath: '/', + filename: devMode ? '[name].js' : '[name].[contenthash].js', + assetModuleFilename: devMode ? '[name][ext]' : '[name].[contenthash][ext]', + clean: true, + crossOriginLoading: 'anonymous', + }, + module: { + rules: [ + { + test: /.[jt]sx?$/i, + include: [path.resolve(__dirname, 'src')], + use: [ + { + loader: 'babel-loader', + options: { + presets: [ + [ + '@babel/preset-env', + { + targets: 'defaults', + }, + ], + '@babel/preset-react', + [ + '@babel/preset-typescript', + { + isTSX: true, + allExtensions: true, + allowDeclareFields: true, + onlyRemoveTypeImports: true, + optimizeConstEnums: true, + }, + ] + ], + plugins: [ + '@babel/plugin-transform-runtime', + ], + }, + }, + ], + }, + { + test: /\.scss$/i, + use: [ + devMode ? 'style-loader' : MiniCssExtractPlugin.loader, + 'css-loader', + { + loader: 'sass-loader', + options: { + implementation: require.resolve('sass'), + }, + }, + ], + }, + { + test: /\.(gif|png|jpe?g|svg?)$/i, + use: [ + { + loader: 'image-webpack-loader', + options: { + disable: true, + } + }, + ], + type: 'asset', + }, + { + test: /\.woff2?$/i, + type: 'asset/resource', + }, + ], + }, + resolve: { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + }, + devtool: devMode ? 'inline-source-map' : 'source-map', + optimization: { + providedExports: !devMode, + sideEffects: devMode ? 'flag' : true, + splitChunks: { + chunks: 'all', + }, + }, + devServer: { + client: { + logging: 'info', + overlay: true, + progress: true, + webSocketURL: { + hostname: publicHost, + port: publicPort, + protocol: publicPort === 443 ? 'wss' : 'ws', + }, + }, + compress: true, + host: listenHost, + port: listenPort, + proxy: { + '/xtext-service': { + target: `${apiPort === 443 ? 'https' : 'http'}://${apiHost}:${apiPort}`, + ws: true, + }, + }, + }, + plugins: [ + new DefinePlugin({ + 'DEBUG': JSON.stringify(devMode), + 'PACKAGE_NAME': JSON.stringify(packageInfo.name), + 'PACKAGE_VERSION': JSON.stringify(packageInfo.version), + }), + new MiniCssExtractPlugin({ + filename: '[name].[contenthash].css', + chunkFilename: '[name].[contenthash].css', + }), + new SubresourceIntegrityPlugin(), + new HtmlWebpackPlugin({ + template: 'src/index.html', + }), + new HtmlWebpackInjectPreload({ + files: [ + { + match: /(roboto-latin-(400|500)-normal|jetbrains-mono-latin-variable).*\.woff2/, + attributes: { + as: 'font', + type: 'font/woff2', + crossorigin: 'anonymous', + }, + }, + ], + }), + ], +}; -- cgit v1.2.3-70-g09d2