Skip to content

Commit 41cb62f

Browse files
authored
Merge pull request #854 from evershopcommerce/webpack
[FEATURE REQUEST] Use Single Webpack Instance in Dev Mode #806
2 parents fe676fe + bbb7204 commit 41cb62f

26 files changed

Lines changed: 403 additions & 281 deletions

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ If you add some more information such as your thoughts and vision about the feat
9494

9595
Please refer to our [Contribution Guidelines](./CONTRIBUTING.md) and [Code of Conduct](./CODE_OF_CONDUCT.md).
9696

97+
## 🚀 The Future of EverShop
98+
99+
EverShop is seeing rapid organic growth and strong adoption from the developer community. We are now scaling our operations and building **EverShop Cloud**.
100+
101+
If you are a strategic investor interested in the future of Node.js commerce and our mission to set a new standard for modern eCommerce, we’d love to share our vision and roadmap with you.
102+
103+
📩 **Get in touch:** support@evershop.io
104+
97105
## License
98106

99107
[GPL-3.0 License](https://github.com/evershopcommerce/evershop/blob/main/LICENSE)

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/evershop/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
"pg": "^8.16.3",
197197
"postcss": "^8.4.18",
198198
"postcss-loader": "^8.2.0",
199+
"postcss-prefix-selector": "^2.1.1",
199200
"prop-types": "^15.8.1",
200201
"react": "^17.0.1",
201202
"react-dom": "^17.0.1",

packages/evershop/src/bin/lib/addDefaultMiddlewareFuncs.js renamed to packages/evershop/src/bin/lib/addDefaultMiddlewareFuncs.ts

Lines changed: 25 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ export function addDefaultMiddlewareFuncs(app) {
7070
},
7171
resave: getConfig('system.session.resave', false),
7272
saveUninitialized: getConfig('system.session.saveUninitialized', true)
73-
};
73+
} as session.SessionOptions;
7474

7575
if (isProductionMode()) {
7676
app.set('trust proxy', 1);
77-
sess.cookie.secure = false;
77+
sess.cookie!.secure = false;
7878
}
7979

8080
const adminSessionMiddleware = session({
@@ -156,7 +156,7 @@ export function addDefaultMiddlewareFuncs(app) {
156156
if (match) {
157157
request.locals = request.locals || {};
158158
request.locals.customParams = {};
159-
const keys = [];
159+
const keys: any[] = [];
160160
pathToRegexp(r.path, keys);
161161
keys.forEach((key, index) => {
162162
request.locals.customParams[key.name] = match[index + 1];
@@ -182,10 +182,7 @@ export function addDefaultMiddlewareFuncs(app) {
182182
return next();
183183
}
184184

185-
const routes = getRoutes();
186185
const route = findRoute(request);
187-
request.locals = request.locals || {};
188-
request.locals.webpackMatchedRoute = route;
189186
if (!route || !isBuildRequired(route)) {
190187
next();
191188
} else {
@@ -222,100 +219,55 @@ export function addDefaultMiddlewareFuncs(app) {
222219
path.join(theme.path, 'dist', '**', '[A-Z]*.js')
223220
);
224221
}
225-
if (!route.webpackCompiler) {
226-
route.webpackCompiler = webpack(
222+
if (!app.locals.webpackCompiler) {
223+
app.locals.webpackCompiler = webpack(
227224
createConfigClient(
228-
route,
229-
route.isAdmin ? adminTailwindConfig : frontStoreTailwindConfig
230-
)
225+
adminTailwindConfig,
226+
frontStoreTailwindConfig
227+
) as any
231228
);
232229
}
233-
const { webpackCompiler } = route;
230+
const { webpackCompiler } = app.locals;
234231
let middlewareFunc;
235-
if (!route.webpackMiddleware) {
236-
middlewareFunc = route.webpackMiddleware = middleware(webpackCompiler, {
237-
serverSideRender: true,
238-
publicPath: '/',
239-
stats: 'none'
240-
});
241-
middlewareFunc.context.logger.info = () => {};
242-
} else {
243-
middlewareFunc = route.webpackMiddleware;
244-
}
245-
middlewareFunc.waitUntilValid(() => {
246-
const { stats } = middlewareFunc.context;
247-
const jsonWebpackStats = stats.toJson();
248-
response.locals.jsonWebpackStats = jsonWebpackStats;
249-
});
250-
// We need to run build for notFound route
251-
const notFoundRoute = routes.find((r) => r.id === 'notFound');
252-
if (!notFoundRoute.webpackCompiler) {
253-
notFoundRoute.webpackCompiler = webpack(
254-
createConfigClient(notFoundRoute, frontStoreTailwindConfig)
255-
);
256-
}
257-
const notFoundWebpackCompiler = notFoundRoute.webpackCompiler;
258-
let notFoundMiddlewareFunc;
259-
if (!notFoundRoute.webpackMiddleware) {
260-
notFoundMiddlewareFunc = notFoundRoute.webpackMiddleware = middleware(
261-
notFoundWebpackCompiler,
232+
if (!app.locals.webpackMiddleware) {
233+
middlewareFunc = app.locals.webpackMiddleware = middleware(
234+
webpackCompiler,
262235
{
263236
serverSideRender: true,
264237
publicPath: '/',
265238
stats: 'none'
266239
}
267240
);
268-
notFoundMiddlewareFunc.context.logger.info = () => {};
269-
} else {
270-
notFoundMiddlewareFunc = notFoundRoute.webpackMiddleware;
271-
}
272-
273-
// We need to run build for adminNotFound route
274-
const adminNotFoundRoute = routes.find((r) => r.id === 'adminNotFound');
275-
if (!adminNotFoundRoute.webpackCompiler) {
276-
adminNotFoundRoute.webpackCompiler = webpack(
277-
createConfigClient(adminNotFoundRoute, adminTailwindConfig)
278-
);
279-
}
280-
const adminNotFoundWebpackCompiler = adminNotFoundRoute.webpackCompiler;
281-
let adminNotFoundMiddlewareFunc;
282-
if (!adminNotFoundRoute.webpackMiddleware) {
283-
adminNotFoundMiddlewareFunc = adminNotFoundRoute.webpackMiddleware =
284-
middleware(adminNotFoundWebpackCompiler, {
285-
serverSideRender: true,
286-
publicPath: '/',
287-
stats: 'none'
288-
});
289-
adminNotFoundMiddlewareFunc.context.logger.info = () => {};
241+
middlewareFunc.context.logger.info = () => {};
290242
} else {
291-
adminNotFoundMiddlewareFunc = adminNotFoundRoute.webpackMiddleware;
243+
middlewareFunc = app.locals.webpackMiddleware;
292244
}
293-
294-
middlewareFunc(request, response, () => {
295-
notFoundMiddlewareFunc(request, response, () => {
296-
adminNotFoundMiddlewareFunc(request, response, next);
297-
});
245+
middlewareFunc.waitUntilValid(() => {
246+
const { stats } = middlewareFunc.context;
247+
const jsonWebpackStats = stats.toJson();
248+
response.locals.jsonWebpackStats = jsonWebpackStats;
298249
});
250+
251+
middlewareFunc(request, response, next);
299252
}
300253
});
301254
app.use((request, response, next) => {
302255
if (!isDevelopmentMode()) {
303256
return next();
304257
}
305-
const routes = getRoutes();
306258
const route = findRoute(request);
307259
request.currentRoute = route;
308260
if (!isBuildRequired(route)) {
309261
return next();
310262
}
311-
if (!route.hotMiddleware) {
312-
const { webpackCompiler } = route;
263+
if (!app.locals.hotMiddleware) {
264+
const { webpackCompiler } = app.locals;
313265
const hotMiddleware = webpackHotMiddleware(webpackCompiler, {
314-
path: `/eHot/${route.id}`
266+
path: `/eHot`
315267
});
316-
route.hotMiddleware = hotMiddleware;
268+
app.locals.hotMiddleware = hotMiddleware;
317269
}
318-
return route.hotMiddleware(request, response, () => {
270+
return app.locals.hotMiddleware(request, response, () => {
319271
next();
320272
});
321273
});

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,17 @@ export async function buildEntry(routes, clientOnly = false) {
7171
const url = route.isAdmin
7272
? pathToFileURL(widget.settingComponent).toString()
7373
: pathToFileURL(widget.component).toString();
74-
imports.push(`import ${widget.type} from '${url}';`);
75-
areas['*'][widget.type] = {
76-
id: widget.type,
74+
const id = generateComponentKey(
75+
route.isAdmin
76+
? `admin_widget_${widget.type}`
77+
: `widget_${widget.type}`
78+
);
79+
imports.push(`import ${id} from '${url}';`);
80+
areas['*'][id] = {
81+
id,
7782
sortOrder: widget.sortOrder || 0,
7883
component: {
79-
default: `---${widget.type}---`
84+
default: `---${id}---`
8085
}
8186
};
8287
});

packages/evershop/src/bin/lib/findRoute.js renamed to packages/evershop/src/bin/lib/findRoute.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ export function findRoute(request) {
1616
routes.find((r) => r.id === id) ||
1717
routes.find((r) => r.id === 'notFound')
1818
);
19-
} else if (path.includes('/eHot/')) {
20-
const id = path.split('/').pop();
21-
return routes.find((r) => r.id === id);
19+
} else if (path.includes('/eHot')) {
20+
return routes.find((r) => r.id === 'homepage');
2221
} else {
2322
return routes.find((r) => r.id === 'notFound');
2423
}

packages/evershop/src/components/common/Area.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useAppState } from '@components/common/context/app.js';
2+
import { generateComponentKey } from '@evershop/evershop/lib/webpack/util/keyGenerator.js';
23
import React from 'react';
34
import type { ElementType } from 'react';
45

@@ -56,7 +57,9 @@ function Area(props: AreaProps) {
5657
const assignedWidgets: Component[] = [];
5758

5859
widgets.forEach((widget: Widget) => {
59-
const w = wildCardWidgets[widget.type];
60+
const adminKey = generateComponentKey(`admin_widget_${widget.type}`);
61+
const frontKey = generateComponentKey(`widget_${widget.type}`);
62+
const w = wildCardWidgets[adminKey] || wildCardWidgets[frontKey];
6063
if (widget.areaId.includes(id) && w !== undefined) {
6164
assignedWidgets.push({
6265
id: widget.id,

packages/evershop/src/components/common/react/server/Server.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import Area from '@components/common/Area.js';
22
import { Alert } from '@components/common/modal/Alert.js';
33
import React from 'react';
4+
import { Route } from '../../../../types/route.js';
45

56
interface ServerHtmlProps {
7+
route: Route;
68
css: string[];
79
js: string[];
810
appContext: string;
911
}
10-
function ServerHtml({ css, js, appContext }: ServerHtmlProps) {
12+
function ServerHtml({ route, css, js, appContext }: ServerHtmlProps) {
13+
const classes = route.isAdmin
14+
? `admin ${route.id}`
15+
: `frontStore ${route.id}`;
1116
return (
1217
<>
1318
<head>
@@ -18,8 +23,8 @@ function ServerHtml({ css, js, appContext }: ServerHtmlProps) {
1823
))}
1924
<Area noOuter id="head" />
2025
</head>
21-
<body id="body">
22-
<div id="app" className="bg-background">
26+
<body id="body" className={classes}>
27+
<div id="app">
2328
<Alert>
2429
<Area id="body" className="wrapper" />
2530
</Alert>

packages/evershop/src/lib/componee/getComponentsByRoute.js renamed to packages/evershop/src/lib/componee/getComponentsByRoute.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { resolve } from 'path';
22
import { getEnabledExtensions } from '../../bin/extension/index.js';
33
import { getCoreModules } from '../../bin/lib/loadModules.js';
4-
import { CONSTANTS } from '../helpers.js';
4+
import { getRoutes } from '../router/Router.js';
55
import { getEnabledTheme } from '../util/getEnabledTheme.js';
66
import { getEnabledWidgets } from '../widget/widgetManager.js';
7-
import { scanRouteComponents } from './scanForComponents.js';
7+
import { ComponentsMap, scanRouteComponents } from './scanForComponents.js';
88

99
export function getComponentsByRoute(route) {
1010
const modules = [...getCoreModules(), ...getEnabledExtensions()];
@@ -29,3 +29,21 @@ export function getComponentsByRoute(route) {
2929
);
3030
}
3131
}
32+
33+
interface AllRouteComponentsMap {
34+
[routeId: string]: ComponentsMap;
35+
}
36+
37+
/**
38+
* Scan components for all routes
39+
* @returns A map of route IDs to their components
40+
*/
41+
export function getAllRouteComponents(): AllRouteComponentsMap {
42+
const allComponents: AllRouteComponentsMap = {};
43+
const routes = getRoutes();
44+
routes.forEach((route) => {
45+
allComponents[route.id] = getComponentsByRoute(route);
46+
});
47+
48+
return allComponents;
49+
}

0 commit comments

Comments
 (0)