X-Git-Url: http://these/git/?a=blobdiff_plain;f=webpack.config.js;h=b12af48334aa7647f79a101451e23af391861e9a;hb=61e0241d8930badc4a77cd973c3cbb64bd13c49e;hp=e36f8190d303b57cba1b36f681fc8b9e8f509a9b;hpb=1ab6f9059999e5d9e9fb45f804736ef31619e3f7;p=lemmy-ui.git diff --git a/webpack.config.js b/webpack.config.js index e36f819..b12af48 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,19 +1,30 @@ -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const nodeExternals = require('webpack-node-externals'); -const CopyPlugin = require('copy-webpack-plugin'); -const path = require('path'); +const webpack = require("webpack"); +const { resolve } = require("path"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const nodeExternals = require("webpack-node-externals"); +const CopyPlugin = require("copy-webpack-plugin"); +const { ServiceWorkerPlugin } = require("service-worker-webpack"); + +const banner = ` + hash:[contentHash], chunkhash:[chunkhash], name:[name], filebase:[base], query:[query], file:[file] + Source code: https://github.com/LemmyNet/lemmy-ui + Created by dessalines + @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0 + `; + +module.exports = (env, argv) => { + const mode = argv.mode; -module.exports = function (env, _) { const base = { - // mode is set by package.json flags - entry: './src/server/index.tsx', // Point to main file output: { - path: path.resolve(process.cwd(), 'dist'), - filename: 'js/server.js', - publicPath: '/', + hashFunction: "xxhash64", }, resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], + extensions: [".js", ".jsx", ".ts", ".tsx"], + alias: { + "@": resolve(__dirname, "src/"), + "@utils": resolve(__dirname, "src/shared/utils/"), + }, }, performance: { hints: false, @@ -22,39 +33,127 @@ module.exports = function (env, _) { rules: [ { test: /\.(scss|css)$/i, - use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'], + use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], }, { test: /\.(js|jsx|tsx|ts)$/, // All ts and tsx files will be process by - loaders: 'babel-loader', // first babel-loader, then ts-loader exclude: /node_modules/, // ignore node_modules + loader: "babel-loader", + }, + // Due to some weird babel issue: https://github.com/webpack/webpack/issues/11467 + { + test: /\.m?js/, + resolve: { + fullySpecified: false, + }, }, ], }, - devServer: { - host: '0.0.0.0', - contentBase: 'src/', - historyApiFallback: true, - }, plugins: [ + new webpack.DefinePlugin({ + "process.env.COMMIT_HASH": `"${env.COMMIT_HASH}"`, + "process.env.NODE_ENV": `"${mode}"`, + }), new MiniCssExtractPlugin({ - filename: 'styles/styles.css', + filename: "styles/styles.css", }), new CopyPlugin({ - patterns: [{ from: './src/assets', to: './assets' }], + patterns: [{ from: "./src/assets", to: "./assets" }], + }), + new webpack.BannerPlugin({ + banner, }), ], }; - // server-specific configuration - if (env.platform === 'server') { - base.target = 'node'; - base.externals = [nodeExternals()]; - } - // client-specific configurations - if (env.platform === 'client') { - base.entry = './src/client/index.tsx'; - base.output.filename = 'js/client.js'; + const serverConfig = { + ...base, + entry: "./src/server/index.tsx", + output: { + ...base.output, + filename: "js/server.js", + publicPath: "/", + }, + target: "node", + externals: [nodeExternals(), "inferno-helmet"], + }; + + const clientConfig = { + ...base, + entry: "./src/client/index.tsx", + output: { + ...base.output, + filename: "js/client.js", + publicPath: `/static/${env.COMMIT_HASH}/`, + }, + plugins: [ + ...base.plugins, + new ServiceWorkerPlugin({ + enableInDevelopment: mode !== "development", // this may seem counterintuitive, but it is correct + workbox: { + cacheId: "lemmy", + include: [/(assets|styles|js)\/.+\..+$/g], + inlineWorkboxRuntime: true, + runtimeCaching: [ + { + urlPattern: ({ + sameOrigin, + url: { pathname, host }, + request: { method }, + }) => + (sameOrigin || host.includes("localhost")) && + (!( + pathname.includes("pictrs") || pathname.includes("static") + ) || + method === "POST"), + handler: "NetworkFirst", + options: { + cacheName: "instance-cache", + }, + }, + { + urlPattern: ({ url: { pathname, host }, sameOrigin }) => + (sameOrigin || host.includes("localhost")) && + pathname.includes("static"), + handler: mode === "development" ? "NetworkFirst" : "CacheFirst", + options: { + cacheName: "static-cache", + expiration: { + maxAgeSeconds: 60 * 60 * 24, + }, + }, + }, + { + urlPattern: ({ url: { pathname }, request: { method } }) => + pathname.includes("pictrs") && method === "GET", + handler: "StaleWhileRevalidate", + options: { + cacheName: "image-cache", + expiration: { + maxAgeSeconds: 60 * 60 * 24, + }, + }, + }, + ], + }, + }), + ], + }; + + if (mode === "development") { + // serverConfig.cache = { + // type: "filesystem", + // name: "server", + // }; + + const RunNodeWebpackPlugin = require("run-node-webpack-plugin"); + serverConfig.plugins.push( + new RunNodeWebpackPlugin({ runOnlyInWatchMode: true }) + ); + } else if (mode === "none") { + const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); + serverConfig.plugins.push(new BundleAnalyzerPlugin()); } - return base; + + return [serverConfig, clientConfig]; };