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