Skip to content

Commit 6f3ef46

Browse files
authored
Merge pull request #865 from evershopcommerce/webpack
Feat: Use Single Webpack Instance in Dev Mode #806
2 parents 628a3d6 + 50145f0 commit 6f3ef46

20 files changed

Lines changed: 176 additions & 132 deletions

File tree

package-lock.json

Lines changed: 1 addition & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"theme:create": "evershop theme:create",
1919
"compile": "rimraf ./packages/evershop/dist && cd ./packages/evershop && swc ./src/ -d dist/ --config-file .swcrc --copy-files --strip-leading-paths",
2020
"compile:db": "rimraf ./packages/postgres-query-builder/dist && cd ./packages/postgres-query-builder && swc ./src/ -d dist/ --config-file .swcrc --copy-files --strip-leading-paths",
21-
"compile:tsc": "rimraf ./packages/evershop/dist && cd ./packages/evershop && tsc && copyfiles -u 1 \"src/**/*.{graphql,scss,json}\" dist",
21+
"compile:tsc": "rimraf ./packages/evershop/dist && cd ./packages/evershop && tsc && copyfiles -u 1 \"src/**/*.{graphql,scss,css,json}\" dist",
2222
"start:debug": "node ./packages/evershop/dist/bin/start/index.js --debug",
2323
"test": "ALLOW_CONFIG_MUTATIONS=true NODE_OPTIONS=--experimental-vm-modules node_modules/jest/bin/jest.js",
2424
"lint": "eslint --fix --ext .js,.jsx,.ts,.tsx ./packages",

packages/evershop/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@
197197
"pg": "^8.16.3",
198198
"postcss": "^8.4.18",
199199
"postcss-loader": "^8.2.0",
200-
"postcss-prefix-selector": "^2.1.1",
201200
"prop-types": "^15.8.1",
202201
"react": "^17.0.1",
203202
"react-dom": "^17.0.1",

packages/evershop/src/bin/lib/addDefaultMiddlewareFuncs.ts

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import sessionStorage from 'connect-pg-simple';
33
import cookieParser from 'cookie-parser';
44
import session from 'express-session';
55
import pathToRegexp from 'path-to-regexp';
6-
import webpack from 'webpack';
7-
import middleware from 'webpack-dev-middleware';
8-
import webpackHotMiddleware from 'webpack-hot-middleware';
96
import { translate } from '../../lib/locale/translate/translate.js';
107
import { debug, warning } from '../../lib/log/logger.js';
118
import publicStatic from '../../lib/middlewares/publicStatic.js';
@@ -15,13 +12,11 @@ import { getRoutes } from '../../lib/router/Router.js';
1512
import { getConfig } from '../../lib/util/getConfig.js';
1613
import isDevelopmentMode from '../../lib/util/isDevelopmentMode.js';
1714
import isProductionMode from '../../lib/util/isProductionMode.js';
18-
import { createConfigClient } from '../../lib/webpack/dev/createConfigClient.js';
19-
import { isBuildRequired } from '../../lib/webpack/isBuildRequired.js';
2015
import { getAdminSessionCookieName } from '../../modules/auth/services/getAdminSessionCookieName.js';
2116
import { getCookieSecret } from '../../modules/auth/services/getCookieSecret.js';
2217
import { getFrontStoreSessionCookieName } from '../../modules/auth/services/getFrontStoreSessionCookieName.js';
2318
import { setPageMetaInfo } from '../../modules/cms/services/pageMetaInfo.js';
24-
import { findRoute } from './findRoute.js';
19+
import { getDevMiddleware, getHotMiddleware } from './devEnvHelper.js';
2520

2621
export function addDefaultMiddlewareFuncs(app) {
2722
app.use((request, response, next) => {
@@ -172,63 +167,60 @@ export function addDefaultMiddlewareFuncs(app) {
172167
}
173168
});
174169

175-
app.use(async (request, response, next) => {
176-
if (!isDevelopmentMode()) {
177-
return next();
178-
}
170+
if (isDevelopmentMode()) {
171+
// Admin webpack dev middleware - only for /backend/* paths
172+
app.use((request, response, next) => {
173+
if (request.path.startsWith('/backend/')) {
174+
const adminDevMiddleware = getDevMiddleware(true);
175+
adminDevMiddleware.waitUntilValid(() => {
176+
const { stats } = adminDevMiddleware.context;
177+
if (stats) {
178+
response.locals.jsonWebpackStats = stats.toJson();
179+
}
180+
});
181+
adminDevMiddleware(request, response, next);
182+
} else {
183+
next();
184+
}
185+
});
179186

180-
const route = findRoute(request);
181-
if (!route || !isBuildRequired(route)) {
182-
next();
183-
} else {
184-
if (!app.locals.webpackCompiler) {
185-
app.locals.webpackCompiler = webpack(createConfigClient() as any);
187+
app.use((request, response, next) => {
188+
if (request.path.startsWith('/__webpack_hmr_admin')) {
189+
const adminHotMiddleware = getHotMiddleware(true);
190+
adminHotMiddleware(request, response, next);
191+
} else {
192+
next();
186193
}
187-
const { webpackCompiler } = app.locals;
188-
let middlewareFunc;
189-
if (!app.locals.webpackMiddleware) {
190-
middlewareFunc = app.locals.webpackMiddleware = middleware(
191-
webpackCompiler,
192-
{
193-
serverSideRender: true,
194-
publicPath: '/',
195-
stats: 'none'
194+
});
195+
196+
// Frontstore webpack dev middleware - for all other paths
197+
app.use((request, response, next) => {
198+
if (
199+
!request.path.startsWith('/backend/') &&
200+
!request.path.startsWith('/__webpack_hmr_admin')
201+
) {
202+
const frontstoreDevMiddleware = getDevMiddleware(false);
203+
frontstoreDevMiddleware.waitUntilValid(() => {
204+
const { stats } = frontstoreDevMiddleware.context;
205+
if (stats) {
206+
response.locals.jsonWebpackStats = stats.toJson();
196207
}
197-
);
198-
middlewareFunc.context.logger.info = () => {};
208+
});
209+
frontstoreDevMiddleware(request, response, next);
199210
} else {
200-
middlewareFunc = app.locals.webpackMiddleware;
211+
next();
201212
}
202-
middlewareFunc.waitUntilValid(() => {
203-
const { stats } = middlewareFunc.context;
204-
const jsonWebpackStats = stats.toJson();
205-
response.locals.jsonWebpackStats = jsonWebpackStats;
206-
});
207-
208-
middlewareFunc(request, response, next);
209-
}
210-
});
211-
app.use((request, response, next) => {
212-
if (!isDevelopmentMode()) {
213-
return next();
214-
}
215-
const route = findRoute(request);
216-
request.currentRoute = route;
217-
if (!isBuildRequired(route)) {
218-
return next();
219-
}
220-
if (!app.locals.hotMiddleware) {
221-
const { webpackCompiler } = app.locals;
222-
const hotMiddleware = webpackHotMiddleware(webpackCompiler, {
223-
path: `/eHot`
224-
});
225-
app.locals.hotMiddleware = hotMiddleware;
226-
}
227-
return app.locals.hotMiddleware(request, response, () => {
228-
next();
229213
});
230-
});
231214

215+
app.use((request, response, next) => {
216+
if (request.path.startsWith('/__webpack_hmr_frontstore')) {
217+
const frontstoreHotMiddleware = getHotMiddleware(false);
218+
frontstoreHotMiddleware(request, response, next);
219+
} else {
220+
next();
221+
}
222+
});
223+
}
232224
/** 404 Not Found handle */
233225
app.use((request, response, next) => {
234226
if (!request.currentRoute) {

packages/evershop/src/bin/lib/bootstrap/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const loadBootstrapScript = async function loadBootstrapScript(
2727
if (!existsSync(filePath)) {
2828
return;
2929
}
30+
3031
// Convert path to a URL
3132
const bootstrapPath = pathToFileURL(filePath).toString();
3233
const bootstrap = (await import(bootstrapPath)) as BootstrapModule;

packages/evershop/src/bin/lib/buildEntry.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import JSON5 from 'json5';
77
import { getComponentsByRoute } from '../../lib/componee/getComponentsByRoute.js';
88
import { CONSTANTS } from '../../lib/helpers.js';
99
import { error } from '../../lib/log/logger.js';
10-
import { getRouteBuildPath } from '../../lib/webpack/getRouteBuildPath.js';
1110
import { generateComponentKey } from '../../lib/util/keyGenerator.js';
11+
import { getRouteBuildPath } from '../../lib/webpack/getRouteBuildPath.js';
1212
import { parseGraphql } from '../../lib/webpack/util/parseGraphql.js';
1313
import { getEnabledWidgets } from '../../lib/widget/widgetManager.js';
1414
/**
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import webpack from 'webpack';
2+
import middleware from 'webpack-dev-middleware';
3+
import webpackHotMiddleware from 'webpack-hot-middleware';
4+
import { createConfigClient } from '../../lib/webpack/dev/createConfigClient.js';
5+
6+
type DevConfig = {
7+
admin: {
8+
compiler?: webpack.Compiler;
9+
devMiddleware?: ReturnType<typeof middleware>;
10+
hotMiddleware?: ReturnType<typeof webpackHotMiddleware>;
11+
};
12+
frontStore: {
13+
compiler?: webpack.Compiler | null;
14+
devMiddleware?: ReturnType<typeof middleware> | null;
15+
hotMiddleware?: ReturnType<typeof webpackHotMiddleware> | null;
16+
};
17+
};
18+
19+
const webpackConfig = {
20+
admin: {},
21+
frontStore: {}
22+
} as DevConfig;
23+
24+
function getWebpackCompiler(isAdmin: boolean) {
25+
const area = isAdmin ? 'admin' : 'frontStore';
26+
if (!webpackConfig[area].compiler) {
27+
webpackConfig[area].compiler = webpack(createConfigClient(isAdmin) as any);
28+
}
29+
return webpackConfig[area].compiler;
30+
}
31+
32+
function getDevMiddleware(isAdmin: boolean) {
33+
const area = isAdmin ? 'admin' : 'frontStore';
34+
if (!webpackConfig[area].devMiddleware) {
35+
const compiler = getWebpackCompiler(isAdmin);
36+
const devMiddleware = middleware(compiler, {
37+
serverSideRender: true,
38+
publicPath: isAdmin ? '/backend/' : '/',
39+
stats: 'none'
40+
});
41+
devMiddleware.context.logger.info = () => {};
42+
webpackConfig[area].devMiddleware = devMiddleware;
43+
}
44+
return webpackConfig[area].devMiddleware;
45+
}
46+
47+
function getHotMiddleware(isAdmin: boolean) {
48+
const area = isAdmin ? 'admin' : 'frontStore';
49+
if (!webpackConfig[area].hotMiddleware) {
50+
const compiler = getWebpackCompiler(isAdmin);
51+
const hotMiddleware = webpackHotMiddleware(compiler, {
52+
path: isAdmin ? `/__webpack_hmr_admin` : `/__webpack_hmr_frontstore`
53+
});
54+
webpackConfig[area].hotMiddleware = hotMiddleware;
55+
}
56+
return webpackConfig[area].hotMiddleware;
57+
}
58+
59+
export { getWebpackCompiler, getDevMiddleware, getHotMiddleware };

packages/evershop/src/bin/lib/findRoute.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

packages/evershop/src/components/common/react/client/Index.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import { App } from '@components/common/react/client/Client';
33
import { HotReload } from '@components/common/react/client/HotReload';
44
import React from 'react';
55
import ReactDOM from 'react-dom';
6-
import hot from 'webpack-hot-middleware/client?path=/eHot&reload=true&overlay=true';
76
/** render */
87
ReactDOM.render(
98
<App>
109
<Area />
11-
<HotReload hot={hot} />
1210
</App>,
1311
document.getElementById('app')
1412
);

packages/evershop/src/lib/componee/getComponentsByRoute.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,11 @@ interface AllRouteComponentsMap {
3838
* Scan components for all routes
3939
* @returns A map of route IDs to their components
4040
*/
41-
export function getAllRouteComponents(): AllRouteComponentsMap {
41+
export function getAllRouteComponents(isAdmin = false): AllRouteComponentsMap {
4242
const allComponents: AllRouteComponentsMap = {};
43-
const routes = getRoutes();
43+
const routes = getRoutes().filter(
44+
(route) => route.isApi === false && route.isAdmin === isAdmin
45+
);
4446
routes.forEach((route) => {
4547
allComponents[route.id] = getComponentsByRoute(route);
4648
});

0 commit comments

Comments
 (0)