-
Notifications
You must be signed in to change notification settings - Fork 0
/
webpack.config.ts
136 lines (121 loc) · 3.72 KB
/
webpack.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import path from "node:path";
import { readFileSync } from "node:fs";
import webpack from "webpack";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import { WebpackManifestPlugin } from "webpack-manifest-plugin";
import webpackDevMiddleware from "webpack-dev-middleware";
import webpackHotMiddleware from "@gatsbyjs/webpack-hot-middleware";
import type { Request, Response, NextFunction } from "express";
const swcConfig = JSON.parse(
readFileSync(path.resolve(process.cwd(), "swc.config.json"), "utf-8")
);
const isDevMode = process.env.NODE_ENV === "development";
const webpackSwcConfig = {
...swcConfig,
jsc: {
...swcConfig.jsc,
transform: {
react: {
runtime: "automatic",
// Enable fast refresh in dev
refresh: isDevMode,
},
},
},
module: {
// Set module type to get code splitting.
// Code splitting does not work for type: "commonjs".
type: "nodenext",
},
};
const contenthash = isDevMode ? "" : ".[contenthash:8]";
const webpackConfig: webpack.Configuration = {
mode: isDevMode ? "development" : "production",
entry: {
main: ["./react/index.tsx"],
},
output: {
clean: true,
path: path.resolve(__dirname, "./build/public"),
filename: `[name]${contenthash}.js`,
chunkFilename: `[name].chunk${contenthash}.js`,
publicPath: "/",
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"],
},
module: {
rules: [
{
test: /\.(js|ts|tsx)$/,
exclude: /node_modules/,
include: [path.join(__dirname, "react")], // only bundle files in this directory
use: {
loader: "swc-loader",
options: webpackSwcConfig,
},
},
],
},
plugins: [
new WebpackManifestPlugin({
fileName: "webpack-stats.json",
writeToFileEmit: true,
isInitial: true,
}),
],
optimization: {
moduleIds: "deterministic", // Now, despite any new local dependencies, our vendor hash should stay consistent between builds
runtimeChunk: true, // see https://webpack.js.org/guides/build-performance/#minimal-entry-chunk
},
};
if (isDevMode) {
webpackConfig.entry = {
main: ["@gatsbyjs/webpack-hot-middleware/client", "./react/index.tsx"],
};
webpackConfig.output = {
...webpackConfig.output,
hotUpdateChunkFilename: "[id].hot-update.js",
hotUpdateMainFilename: "[runtime].hot-update.json",
};
webpackConfig.plugins = [
...(webpackConfig.plugins || []),
new webpack.HotModuleReplacementPlugin(),
new ReactRefreshWebpackPlugin({
overlay: {
sockIntegration: "whm",
},
}),
];
webpackConfig.cache = {
// https://webpack.js.org/configuration/other-options/#cache
type: "filesystem",
cacheDirectory: path.resolve(__dirname, ".tmp"),
name: "dev-react-cache",
};
}
const compiler = webpack(webpackConfig);
if (isDevMode) {
const dirName = path.resolve(__dirname, "./react/");
compiler.hooks.afterEmit.tap("cleanup-the-require-cache", () => {
// After webpack rebuild, clear the files from the require cache,
// so that next server side render will be in sync
Object.keys(require.cache)
.filter((key) => key.includes(dirName))
.forEach((key) => delete require.cache[key]);
});
}
export const devMiddleware = isDevMode
? webpackDevMiddleware(compiler, {
serverSideRender: true,
publicPath: webpackConfig.output?.publicPath || "/",
})
: (req: Request, res: Response, next: NextFunction) => next();
export const hotMiddleware = isDevMode
? webpackHotMiddleware(compiler, {
log: false,
path: "/__webpack_hmr",
heartbeat: 10 * 1000,
})
: (req: Request, res: Response, next: NextFunction) => next();
export default webpackConfig;