@proteinjs/server 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +20 -0
- package/.prettierignore +3 -0
- package/.prettierrc +8 -0
- package/CHANGELOG.md +11 -44
- package/LICENSE +21 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/jest.config.d.ts +1 -1
- package/dist/jest.config.js +6 -15
- package/dist/jest.config.js.map +1 -1
- package/dist/src/NodeSessionDataStorage.d.ts.map +1 -1
- package/dist/src/NodeSessionDataStorage.js +13 -7
- package/dist/src/NodeSessionDataStorage.js.map +1 -1
- package/dist/src/loadRoutes.d.ts.map +1 -1
- package/dist/src/loadRoutes.js +14 -7
- package/dist/src/loadRoutes.js.map +1 -1
- package/dist/src/routes/healthCheck.d.ts.map +1 -1
- package/dist/src/routes/healthCheck.js +1 -1
- package/dist/src/routes/healthCheck.js.map +1 -1
- package/dist/src/routes/reactApp.d.ts.map +1 -1
- package/dist/src/routes/reactApp.js +7 -4
- package/dist/src/routes/reactApp.js.map +1 -1
- package/dist/src/startServer.d.ts.map +1 -1
- package/dist/src/startServer.js +25 -12
- package/dist/src/startServer.js.map +1 -1
- package/dist/webpack.config.js +15 -15
- package/dist/webpack.config.js.map +1 -1
- package/generated/index.ts +5 -8
- package/index.ts +1 -1
- package/jest.config.js +8 -17
- package/package.json +11 -5
- package/src/NodeSessionDataStorage.ts +35 -29
- package/src/loadRoutes.ts +124 -103
- package/src/nodeModulesPath.ts +1 -1
- package/src/routes/healthCheck.ts +7 -7
- package/src/routes/reactApp.ts +43 -36
- package/src/startServer.ts +164 -132
- package/tsconfig.json +17 -17
- package/webpack.config.js +20 -20
package/src/routes/reactApp.ts
CHANGED
|
@@ -4,18 +4,20 @@ import { ServerConfig, getServerRenderedScripts } from '@proteinjs/server-api';
|
|
|
4
4
|
import { Fs } from '@proteinjs/util-node';
|
|
5
5
|
|
|
6
6
|
export const createReactApp = (serverConfig: ServerConfig) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
return {
|
|
8
|
+
path: '*',
|
|
9
|
+
method: 'get' as 'get',
|
|
10
|
+
onRequest: async (request: any, response: any): Promise<void> => {
|
|
11
|
+
if (request.path.startsWith('/static')) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
if (!(serverConfig.staticContent?.bundlePaths || serverConfig.staticContent?.bundlesDir)) {
|
|
16
|
+
throw new Error(`ServerConfig.bundlePath or ServerConfig.bundlesDir must be provided to serve a react app`);
|
|
17
|
+
}
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
const helmet = ReactHelmet.renderStatic();
|
|
20
|
+
response.send(`<!DOCTYPE html>
|
|
19
21
|
<html ${helmet.htmlAttributes}>
|
|
20
22
|
<head>
|
|
21
23
|
<meta charset='utf-8' />
|
|
@@ -31,37 +33,42 @@ export const createReactApp = (serverConfig: ServerConfig) => {
|
|
|
31
33
|
${await serverRenderedScriptTags()}
|
|
32
34
|
${await bundleScriptTags(serverConfig)}
|
|
33
35
|
</body>
|
|
34
|
-
</html>`
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
36
|
+
</html>`);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
39
40
|
|
|
40
41
|
async function bundleScriptTags(serverConfig: ServerConfig) {
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
if (!(serverConfig.staticContent?.bundlePaths || serverConfig.staticContent?.bundlesDir)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
const scriptTags: string[] = [];
|
|
47
|
+
if (serverConfig.staticContent?.bundlePaths) {
|
|
48
|
+
for (const bundlePath of serverConfig.staticContent.bundlePaths) {
|
|
49
|
+
scriptTags.push(`<script src='${path.join('/static/', bundlePath)}'></script>`);
|
|
50
|
+
}
|
|
51
|
+
} else if (serverConfig.staticContent?.bundlesDir && serverConfig.staticContent?.staticContentDir) {
|
|
52
|
+
const resolvedBundlesDir = path.join(
|
|
53
|
+
serverConfig.staticContent.staticContentDir,
|
|
54
|
+
serverConfig.staticContent.bundlesDir
|
|
55
|
+
);
|
|
56
|
+
const filePaths = await Fs.getFilePathsMatchingGlob(resolvedBundlesDir, '**/*.js');
|
|
57
|
+
for (const filePath of filePaths) {
|
|
58
|
+
const relativePath = path.relative(serverConfig.staticContent.staticContentDir, filePath);
|
|
59
|
+
scriptTags.push(`<script src='${path.join('/static/', relativePath)}'></script>`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
return scriptTags.join('\n');
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
async function serverRenderedScriptTags() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
const scripts = getServerRenderedScripts();
|
|
68
|
+
const scriptTags: string[] = [];
|
|
69
|
+
for (const script of scripts) {
|
|
70
|
+
scriptTags.push(`<script>${await script.script()}</script>`);
|
|
71
|
+
}
|
|
65
72
|
|
|
66
|
-
|
|
67
|
-
}
|
|
73
|
+
return scriptTags.join('\n');
|
|
74
|
+
}
|
package/src/startServer.ts
CHANGED
|
@@ -18,173 +18,205 @@ const staticContentPath = '/static/';
|
|
|
18
18
|
const logger = new Logger('Server');
|
|
19
19
|
|
|
20
20
|
export async function startServer(config: ServerConfig) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
const routes = getRoutes();
|
|
22
|
+
await runStartupEvents(config);
|
|
23
|
+
const server = express();
|
|
24
|
+
configureRequests(server);
|
|
25
|
+
initializeHotReloading(server, config);
|
|
26
|
+
beforeRequest(server, config);
|
|
27
|
+
loadRoutes(
|
|
28
|
+
routes.filter((route) => route.useHttp),
|
|
29
|
+
server,
|
|
30
|
+
config
|
|
31
|
+
);
|
|
32
|
+
configureHttps(server); // registering here forces static content to be redirected to https
|
|
33
|
+
configureStaticContentRouter(server, config); // registering here prevents sessions from being created on static content requests
|
|
34
|
+
configureSession(server, config);
|
|
35
|
+
loadRoutes(
|
|
36
|
+
routes.filter((route) => !route.useHttp),
|
|
37
|
+
server,
|
|
38
|
+
config
|
|
39
|
+
);
|
|
40
|
+
loadDefaultStarRoute(routes, server, config);
|
|
41
|
+
afterRequest(server, config);
|
|
42
|
+
start(server, config);
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
async function runStartupEvents(config: ServerConfig) {
|
|
38
|
-
|
|
46
|
+
await new Db().init();
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
if (config.onStartup) {
|
|
49
|
+
await config.onStartup();
|
|
50
|
+
}
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
function configureRequests(server: express.Express) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
server.use(compression());
|
|
55
|
+
server.use(cookieParser());
|
|
56
|
+
server.use(bodyParser.json({ limit: '100mb' }));
|
|
57
|
+
server.use(
|
|
58
|
+
bodyParser.urlencoded({
|
|
59
|
+
extended: true,
|
|
60
|
+
limit: '100mb',
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
server.disable('x-powered-by');
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
function initializeHotReloading(server: express.Express, config: ServerConfig) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
if (
|
|
68
|
+
!process.env.DEVELOPMENT ||
|
|
69
|
+
process.env.DISABLE_HOT_CLIENT_BUILDS ||
|
|
70
|
+
!config.hotClientBuilds ||
|
|
71
|
+
!config.staticContent?.staticContentDir ||
|
|
72
|
+
!config.staticContent?.appEntryPath
|
|
73
|
+
) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const wpConfig = Object.assign({}, getWebpackConfig(config));
|
|
78
|
+
wpConfig['entry'] = { app: ['webpack-hot-middleware/client', config.staticContent.appEntryPath] };
|
|
79
|
+
wpConfig['output']['path'] = config.staticContent.staticContentDir;
|
|
80
|
+
wpConfig['output']['publicPath'] = staticContentPath;
|
|
81
|
+
const webpackCompiler = webpack(wpConfig);
|
|
82
|
+
server.use(
|
|
83
|
+
webpackDevMiddleware(webpackCompiler, {
|
|
84
|
+
publicPath: staticContentPath,
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
server.use(webpackHotMiddleware(webpackCompiler));
|
|
68
88
|
}
|
|
69
89
|
|
|
70
90
|
function getWebpackConfig(config: ServerConfig) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
91
|
+
setNodeModulesPath(config.hotClientBuilds?.nodeModulesPath as string);
|
|
92
|
+
const webpackConfig = require('../webpack.config');
|
|
93
|
+
return webpackConfig;
|
|
74
94
|
}
|
|
75
95
|
|
|
76
96
|
function configureHttps(server: express.Express) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
server.use((request: express.Request, response: express.Response, next: express.NextFunction) => {
|
|
98
|
+
if (request.protocol == 'https' || response.headersSent || process.env.DEVELOPMENT) {
|
|
99
|
+
next();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
logger.debug(`Redirecting to https: ${request.headers.host + request.url}`);
|
|
104
|
+
response.redirect('https://' + request.headers.host + request.url);
|
|
105
|
+
});
|
|
86
106
|
}
|
|
87
107
|
|
|
88
108
|
function configureStaticContentRouter(server: express.Express, config: ServerConfig) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
if (!config.staticContent?.staticContentDir) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
server.use(staticContentPath, express.static(config.staticContent.staticContentDir));
|
|
114
|
+
logger.info(
|
|
115
|
+
`Serving static content on path: ${staticContentPath}, serving from directory: ${config.staticContent.staticContentDir}`
|
|
116
|
+
);
|
|
94
117
|
}
|
|
95
118
|
|
|
96
119
|
function configureSession(server: express.Express, config: ServerConfig) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
sessionOptions.cookie.secure = true;
|
|
120
|
+
const sixtyDays = 1000 * 60 * 60 * 24 * 60;
|
|
121
|
+
let sessionOptions: expressSession.SessionOptions = {
|
|
122
|
+
secret: config.session.secret,
|
|
123
|
+
store: config.session.store,
|
|
124
|
+
resave: false,
|
|
125
|
+
saveUninitialized: false,
|
|
126
|
+
cookie: {
|
|
127
|
+
maxAge: sixtyDays,
|
|
128
|
+
},
|
|
129
|
+
rolling: true,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (!process.env.DEVELOPMENT) {
|
|
133
|
+
server.set('trust proxy', 1);
|
|
134
|
+
if (!sessionOptions.cookie) {
|
|
135
|
+
sessionOptions.cookie = {};
|
|
114
136
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
sessionOptions.cookie.secure = true;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (config.session) {
|
|
141
|
+
sessionOptions = Object.assign(sessionOptions, config.session);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
server.use(expressSession(sessionOptions));
|
|
145
|
+
server.use(passport.initialize());
|
|
146
|
+
server.use(passport.session());
|
|
147
|
+
if (config.authenticate) {
|
|
148
|
+
initializeAuthentication(config.authenticate);
|
|
149
|
+
}
|
|
124
150
|
}
|
|
125
151
|
|
|
126
152
|
function initializeAuthentication(authenticate: (username: string, password: string) => Promise<true | string>) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
153
|
+
passport.use(
|
|
154
|
+
new passportLocal.Strategy(async function (username, password, done) {
|
|
155
|
+
logger.info(`Authenticating`);
|
|
156
|
+
const result = await authenticate(username, password);
|
|
157
|
+
if (result === true) {
|
|
158
|
+
return done(null, { username });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return done(new Error(result));
|
|
162
|
+
})
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
passport.serializeUser(function (user, done) {
|
|
166
|
+
done(null, user);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
passport.deserializeUser(function (id, done) {
|
|
170
|
+
done(null, id);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
135
173
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
174
|
+
function beforeRequest(server: express.Express, config: ServerConfig) {
|
|
175
|
+
let requestCounter: number = 0;
|
|
176
|
+
if (config.request?.disableRequestLogging == false || typeof config.request?.disableRequestLogging === 'undefined') {
|
|
177
|
+
server.use((request: express.Request, response: express.Response, next: express.NextFunction) => {
|
|
178
|
+
if (request.path.startsWith('/static') || request.path.startsWith('/favicon.ico')) {
|
|
179
|
+
next();
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
139
182
|
|
|
140
|
-
|
|
141
|
-
|
|
183
|
+
const requestNumber = ++requestCounter;
|
|
184
|
+
logger.info(`[#${requestNumber}] Started ${request.originalUrl}`);
|
|
185
|
+
response.locals = { requestNumber };
|
|
186
|
+
next();
|
|
142
187
|
});
|
|
143
|
-
}
|
|
188
|
+
}
|
|
144
189
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
server.use((request: express.Request, response: express.Response, next: express.NextFunction) => {
|
|
149
|
-
if (request.path.startsWith('/static') || request.path.startsWith('/favicon.ico')) {
|
|
150
|
-
next();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const requestNumber = ++requestCounter;
|
|
155
|
-
logger.info(`[#${requestNumber}] Started ${request.originalUrl}`);
|
|
156
|
-
response.locals = { requestNumber };
|
|
157
|
-
next();
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (config.request?.beforeRequest)
|
|
162
|
-
server.use(config.request.beforeRequest);
|
|
190
|
+
if (config.request?.beforeRequest) {
|
|
191
|
+
server.use(config.request.beforeRequest);
|
|
192
|
+
}
|
|
163
193
|
}
|
|
164
194
|
|
|
165
195
|
function afterRequest(server: express.Express, config: ServerConfig) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
196
|
+
if (config.request?.afterRequest) {
|
|
197
|
+
server.use(config.request.afterRequest);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (config.request?.disableRequestLogging == false || typeof config.request?.disableRequestLogging === 'undefined') {
|
|
201
|
+
server.use((request: express.Request, response: express.Response, next: express.NextFunction) => {
|
|
202
|
+
if (request.path.startsWith('/static') || request.path.startsWith('/favicon.ico')) {
|
|
203
|
+
next();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
logger.info(`[#${response.locals.requestNumber}] Finished ${request.originalUrl}`);
|
|
208
|
+
next();
|
|
209
|
+
});
|
|
210
|
+
}
|
|
180
211
|
}
|
|
181
212
|
|
|
182
213
|
function start(server: express.Express, config: ServerConfig) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
214
|
+
const port = config.port ? config.port : 3000;
|
|
215
|
+
server.listen(port, () => {
|
|
216
|
+
if (process.env.DEVELOPMENT) {
|
|
217
|
+
logger.info(`Starting in development mode`);
|
|
218
|
+
}
|
|
187
219
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
220
|
+
logger.info(`Server listening on port: ${port}`);
|
|
221
|
+
});
|
|
222
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "./",
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"module": "commonjs",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"outDir": "./dist/",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noImplicitAny": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"forceConsistentCasingInFileNames": true,
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"allowJs": true
|
|
17
|
+
}
|
|
18
|
+
}
|
package/webpack.config.js
CHANGED
|
@@ -13,8 +13,8 @@ const { nodeModulesPath } = require('./src/nodeModulesPath');
|
|
|
13
13
|
const webpack5esmInteropRule = {
|
|
14
14
|
test: /\.m?js/,
|
|
15
15
|
resolve: {
|
|
16
|
-
fullySpecified: false
|
|
17
|
-
}
|
|
16
|
+
fullySpecified: false,
|
|
17
|
+
},
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
module.exports = {
|
|
@@ -28,26 +28,26 @@ module.exports = {
|
|
|
28
28
|
filename: '[name].js',
|
|
29
29
|
// path and publicPath provided in startServer.initializeHotReloading
|
|
30
30
|
// path: path.join(__dirname, 'dist'),
|
|
31
|
-
library: '[name]'
|
|
31
|
+
library: '[name]',
|
|
32
32
|
},
|
|
33
33
|
resolve: {
|
|
34
34
|
extensions: ['.tsx', '.ts', '.js', '.json'],
|
|
35
35
|
alias: {
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
react: path.join(nodeModulesPath, 'react'),
|
|
37
|
+
process: 'process/browser',
|
|
38
38
|
'@mui/joy': path.join(nodeModulesPath, '@mui/joy'),
|
|
39
39
|
'@mui/material': path.join(nodeModulesPath, '@mui/material'),
|
|
40
40
|
'@mui/icons-material': path.join(nodeModulesPath, '@mui/icons-material'),
|
|
41
41
|
'webpack-hot-middleware': path.join(nodeModulesPath, 'webpack-hot-middleware'),
|
|
42
42
|
},
|
|
43
43
|
// provide shims for node libraries for webpack >= 5
|
|
44
|
-
fallback: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
fallback: {
|
|
45
|
+
crypto: require.resolve('crypto-browserify'),
|
|
46
|
+
util: require.resolve('util/'),
|
|
47
|
+
events: require.resolve('events/'),
|
|
48
|
+
url: require.resolve('url/'),
|
|
49
|
+
buffer: require.resolve('buffer/'),
|
|
50
|
+
stream: require.resolve('stream-browserify'),
|
|
51
51
|
'process/browser': require.resolve('process/browser'),
|
|
52
52
|
},
|
|
53
53
|
},
|
|
@@ -95,20 +95,20 @@ module.exports = {
|
|
|
95
95
|
splitChunks: {
|
|
96
96
|
cacheGroups: {
|
|
97
97
|
vendor: {
|
|
98
|
-
test: /[\\/]node_modules[\\/]/,
|
|
98
|
+
test: /[\\/]node_modules[\\/]/, // Matches node_modules folder
|
|
99
99
|
name: 'vendor',
|
|
100
100
|
chunks: 'all',
|
|
101
|
-
priority: -10
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
101
|
+
priority: -10,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
105
|
},
|
|
106
106
|
plugins: [
|
|
107
107
|
new webpack.ProvidePlugin({
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
process: 'process/browser',
|
|
109
|
+
Buffer: ['buffer', 'Buffer'],
|
|
110
110
|
}),
|
|
111
111
|
new webpack.HotModuleReplacementPlugin(),
|
|
112
112
|
new ReactRefreshWebpackPlugin(),
|
|
113
113
|
],
|
|
114
|
-
};
|
|
114
|
+
};
|