]> Untitled Git - lemmy-ui.git/blob - webpack.config.js
Use http client (#1081)
[lemmy-ui.git] / webpack.config.js
1 const webpack = require("webpack");
2 const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3 const nodeExternals = require("webpack-node-externals");
4 const CopyPlugin = require("copy-webpack-plugin");
5 const RunNodeWebpackPlugin = require("run-node-webpack-plugin");
6 const merge = require("lodash/merge");
7 const { ServiceWorkerPlugin } = require("service-worker-webpack");
8 const banner = `
9   hash:[contentHash], chunkhash:[chunkhash], name:[name], filebase:[base], query:[query], file:[file]
10   Source code: https://github.com/LemmyNet/lemmy-ui
11   Created by dessalines
12   @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0
13   `;
14
15 const base = {
16   output: {
17     filename: "js/server.js",
18     publicPath: "/",
19     hashFunction: "xxhash64",
20   },
21   resolve: {
22     extensions: [".js", ".jsx", ".ts", ".tsx"],
23   },
24   performance: {
25     hints: false,
26   },
27   module: {
28     rules: [
29       {
30         test: /\.(scss|css)$/i,
31         use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
32       },
33       {
34         test: /\.(js|jsx|tsx|ts)$/, // All ts and tsx files will be process by
35         exclude: /node_modules/, // ignore node_modules
36         loader: "babel-loader",
37       },
38       // Due to some weird babel issue: https://github.com/webpack/webpack/issues/11467
39       {
40         test: /\.m?js/,
41         resolve: {
42           fullySpecified: false,
43         },
44       },
45     ],
46   },
47   plugins: [
48     new MiniCssExtractPlugin({
49       filename: "styles/styles.css",
50     }),
51     new CopyPlugin({
52       patterns: [{ from: "./src/assets", to: "./assets" }],
53     }),
54     new webpack.BannerPlugin({
55       banner,
56     }),
57   ],
58 };
59
60 const createServerConfig = (_env, mode) => {
61   const config = merge({}, base, {
62     mode,
63     entry: "./src/server/index.tsx",
64     output: {
65       filename: "js/server.js",
66     },
67     target: "node",
68     externals: [nodeExternals(), "inferno-helmet"],
69   });
70
71   if (mode === "development") {
72     // config.cache = {
73     //   type: "filesystem",
74     //   name: "server",
75     // };
76
77     config.plugins.push(
78       new RunNodeWebpackPlugin({
79         runOnlyInWatchMode: true,
80       })
81     );
82   }
83
84   return config;
85 };
86
87 const createClientConfig = (_env, mode) => {
88   const config = merge({}, base, {
89     mode,
90     entry: "./src/client/index.tsx",
91     output: {
92       filename: "js/client.js",
93     },
94     plugins: [
95       ...base.plugins,
96       new ServiceWorkerPlugin({
97         enableInDevelopment: mode !== "development", // this may seem counterintuitive, but it is correct
98         workbox: {
99           modifyURLPrefix: {
100             "/": "/static/",
101           },
102           cacheId: "lemmy",
103           include: [/(assets|styles)\/.+\..+|client\.js$/g],
104           inlineWorkboxRuntime: true,
105           runtimeCaching: [
106             {
107               urlPattern: ({
108                 sameOrigin,
109                 url: { pathname, host },
110                 request: { method },
111               }) =>
112                 (sameOrigin || host.includes("localhost")) &&
113                 (!(
114                   pathname.includes("pictrs") || pathname.includes("static")
115                 ) ||
116                   method === "POST"),
117               handler: "NetworkFirst",
118               options: {
119                 cacheName: "instance-cache",
120               },
121             },
122             {
123               urlPattern: ({ url: { pathname, host }, sameOrigin }) =>
124                 (sameOrigin || host.includes("localhost")) &&
125                 pathname.includes("static"),
126               handler: mode === "development" ? "NetworkFirst" : "CacheFirst",
127               options: {
128                 cacheName: "static-cache",
129                 expiration: {
130                   maxAgeSeconds: 60 * 60 * 24,
131                 },
132               },
133             },
134             {
135               urlPattern: ({ url: { pathname }, request: { method } }) =>
136                 pathname.includes("pictrs") && method === "GET",
137               handler: "StaleWhileRevalidate",
138               options: {
139                 cacheName: "image-cache",
140                 expiration: {
141                   maxAgeSeconds: 60 * 60 * 24,
142                 },
143               },
144             },
145           ],
146         },
147       }),
148     ],
149   });
150
151   if (mode === "development") {
152     // config.cache = {
153     //   type: "filesystem",
154     //   name: "client",
155     // };
156   }
157
158   return config;
159 };
160
161 module.exports = (env, properties) => [
162   createServerConfig(env, properties.mode || "development"),
163   createClientConfig(env, properties.mode || "development"),
164 ];