const path = require('path') const { readFileSync, readdirSync } = require('fs') const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const VueLoaderPlugin = require('vue-loader/lib/plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const ProcessLocalesPlugin = require('./ProcessLocalesPlugin') const WatchExternalFilesPlugin = require('webpack-watch-external-files-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') const isDevMode = process.env.NODE_ENV === 'development' const { version: swiperVersion } = JSON.parse(readFileSync(path.join(__dirname, '../node_modules/swiper/package.json'))) const processLocalesPlugin = new ProcessLocalesPlugin({ compress: !isDevMode, inputDir: path.join(__dirname, '../static/locales'), outputDir: 'static/locales', }) const config = { name: 'renderer', mode: process.env.NODE_ENV, devtool: isDevMode ? 'eval-cheap-module-source-map' : false, entry: { renderer: path.join(__dirname, '../src/renderer/main.js'), }, infrastructureLogging: { // Only warnings and errors // level: 'none' disable logging // Please read https://webpack.js.org/configuration/other-options/#infrastructurelogginglevel level: isDevMode ? 'info' : 'none' }, output: { libraryTarget: 'commonjs2', path: path.join(__dirname, '../dist'), filename: '[name].js', }, module: { rules: [ { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/, }, { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { whitespace: 'condense', } } }, { test: /\.scss$/, use: [ { loader: MiniCssExtractPlugin.loader, }, { loader: 'css-loader', options: { esModule: false } }, { loader: 'sass-loader', options: { implementation: require('sass') } }, ], }, { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, { loader: 'css-loader', options: { esModule: false } } ], }, { test: /\.(png|jpe?g|gif|tif?f|bmp|webp|svg)(\?.*)?$/, type: 'asset/resource', generator: { filename: 'imgs/[name][ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, type: 'asset/resource', generator: { filename: 'fonts/[name][ext]' } }, ], }, // webpack defaults to only optimising the production builds, so having this here is fine optimization: { minimizer: [ '...', // extend webpack's list instead of overwriting it new CssMinimizerPlugin() ] }, node: { __dirname: false, __filename: false }, plugins: [ processLocalesPlugin, new webpack.DefinePlugin({ 'process.env.IS_ELECTRON': true, 'process.env.IS_ELECTRON_MAIN': false, 'process.env.SUPPORTS_LOCAL_API': true, 'process.env.LOCALE_NAMES': JSON.stringify(processLocalesPlugin.localeNames), 'process.env.GEOLOCATION_NAMES': JSON.stringify(readdirSync(path.join(__dirname, '..', 'static', 'geolocations')).map(filename => filename.replace('.json', ''))), 'process.env.SWIPER_VERSION': `'${swiperVersion}'` }), new HtmlWebpackPlugin({ excludeChunks: ['processTaskWorker'], filename: 'index.html', template: path.resolve(__dirname, '../src/index.ejs') }), new VueLoaderPlugin(), new MiniCssExtractPlugin({ filename: isDevMode ? '[name].css' : '[name].[contenthash].css', chunkFilename: isDevMode ? '[id].css' : '[id].[contenthash].css', }), new CopyWebpackPlugin({ patterns: [ { from: path.join(__dirname, '../node_modules/swiper/modules/{a11y,navigation,pagination}-element.css').replaceAll('\\', '/'), to: `swiper-${swiperVersion}.css`, context: path.join(__dirname, '../node_modules/swiper/modules'), transformAll: (assets) => { return Buffer.concat(assets.map(asset => asset.data)) } } ] }) ], resolve: { alias: { vue$: 'vue/dist/vue.runtime.esm.js', 'DB_HANDLERS_ELECTRON_RENDERER_OR_WEB$': path.resolve(__dirname, '../src/datastores/handlers/electron.js'), 'youtubei.js$': 'youtubei.js/web', // video.js's mpd-parser uses @xmldom/xmldom so that it can support both node and web browsers // as FreeTube only runs in electron and web browsers we can use the native DOMParser class, instead of the "polyfill" // https://caniuse.com/mdn-api_domparser '@xmldom/xmldom$': path.resolve(__dirname, '_domParser.js') }, extensions: ['.js', '.vue'] }, target: 'electron-renderer', } if (isDevMode) { const activeLocales = JSON.parse(readFileSync(path.join(__dirname, '../static/locales/activeLocales.json'))) config.plugins.push( new WatchExternalFilesPlugin({ files: [ `./static/locales/{${activeLocales.join(',')}}.yaml`, ], }), ) } module.exports = config