@quintype/framework 6.3.1 → 7.0.2-gtm.0
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/CHANGELOG.md +9 -0
- package/client/start.js +25 -83
- package/docs-src/tutorials/migrate-from-v6-to-v7.md +155 -0
- package/docs-src/tutorials/tutorials.json +5 -0
- package/jsdoc.json +1 -1
- package/package.json +47 -46
- package/server/publisher-config.js +1 -1
- package/server/start.js +9 -5
- package/server/static-configuration.js +1 -1
- package/server/utils/apm.js +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [7.0.1](https://github.com/quintype/quintype-node-framework/compare/v6.3.0...v7.0.1) (2021-12-15)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* remove visual stories from amp infinite scroll ([#282](https://github.com/quintype/quintype-node-framework/issues/282)) ([719f048](https://github.com/quintype/quintype-node-framework/commit/719f0482bcd730604dcc4273cf2e8465f2232fb6))
|
|
11
|
+
|
|
12
|
+
## [7.0.0](https://github.com/quintype/quintype-node-framework/compare/v6.3.1...v7.0.0) (2021-11-30)
|
|
13
|
+
|
|
5
14
|
### [6.3.1](https://github.com/quintype/quintype-node-framework/compare/v6.3.0...v6.3.1) (2021-11-25)
|
|
6
15
|
|
|
7
16
|
|
package/client/start.js
CHANGED
|
@@ -7,12 +7,7 @@
|
|
|
7
7
|
* @module start
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
BreakingNews,
|
|
12
|
-
CLIENT_SIDE_RENDERED,
|
|
13
|
-
NAVIGATE_TO_PAGE,
|
|
14
|
-
PAGE_LOADING
|
|
15
|
-
} from "@quintype/components";
|
|
10
|
+
import { BreakingNews, CLIENT_SIDE_RENDERED, NAVIGATE_TO_PAGE, PAGE_LOADING } from "@quintype/components";
|
|
16
11
|
import { createBrowserHistory } from "history";
|
|
17
12
|
import get from "lodash/get";
|
|
18
13
|
import React from "react";
|
|
@@ -21,17 +16,12 @@ import { Provider } from "react-redux";
|
|
|
21
16
|
import { IsomorphicComponent } from "../isomorphic/component";
|
|
22
17
|
import { makePickComponentSync } from "../isomorphic/impl/make-pick-component-sync";
|
|
23
18
|
import { createQtStore } from "../store/create-store";
|
|
24
|
-
import {
|
|
25
|
-
registerPageView,
|
|
26
|
-
registerStoryShare,
|
|
27
|
-
setMemberId,
|
|
28
|
-
startAnalytics
|
|
29
|
-
} from "./analytics";
|
|
19
|
+
import { registerPageView, registerStoryShare, setMemberId, startAnalytics } from "./analytics";
|
|
30
20
|
import { initializeFCM } from "./impl/fcm";
|
|
31
21
|
import {
|
|
32
22
|
checkForServiceWorkerUpdates,
|
|
33
23
|
registerServiceWorker,
|
|
34
|
-
setupServiceWorkerUpdates
|
|
24
|
+
setupServiceWorkerUpdates,
|
|
35
25
|
} from "./impl/load-service-worker";
|
|
36
26
|
|
|
37
27
|
require("../assetify/client")();
|
|
@@ -55,28 +45,20 @@ export const app = {
|
|
|
55
45
|
};
|
|
56
46
|
|
|
57
47
|
function getRouteDataAndPath(path, mountAt) {
|
|
58
|
-
const relativePath = path.startsWith(mountAt)
|
|
59
|
-
? path.slice(mountAt.length)
|
|
60
|
-
: path;
|
|
48
|
+
const relativePath = path.startsWith(mountAt) ? path.slice(mountAt.length) : path;
|
|
61
49
|
return [`${mountAt || ""}/route-data.json`, relativePath];
|
|
62
50
|
}
|
|
63
51
|
|
|
64
|
-
function getRouteData(
|
|
65
|
-
path,
|
|
66
|
-
{ location = global.location, existingFetch, mountAt = global.qtMountAt }
|
|
67
|
-
) {
|
|
52
|
+
function getRouteData(path, { location = global.location, existingFetch, mountAt = global.qtMountAt }) {
|
|
68
53
|
// if mountAt is set, then hit /mountAt/route-data, remove mountAt from path
|
|
69
54
|
|
|
70
55
|
const [routeDataPath, relativePath] = getRouteDataAndPath(path, mountAt);
|
|
71
56
|
const url = new URL(relativePath, location.origin);
|
|
72
57
|
return (
|
|
73
58
|
existingFetch ||
|
|
74
|
-
fetch(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}`,
|
|
78
|
-
{ credentials: "same-origin" }
|
|
79
|
-
)
|
|
59
|
+
fetch(`${routeDataPath}?path=${encodeURIComponent(url.pathname)}${url.search ? `&${url.search.slice(1)}` : ""}`, {
|
|
60
|
+
credentials: "same-origin",
|
|
61
|
+
})
|
|
80
62
|
)
|
|
81
63
|
.then((response) => {
|
|
82
64
|
if (response.status == 404) {
|
|
@@ -99,11 +81,7 @@ function getRouteData(
|
|
|
99
81
|
}
|
|
100
82
|
|
|
101
83
|
function maybeBypassServiceWorker(e) {
|
|
102
|
-
if (
|
|
103
|
-
global.qtLoadedFromShell ||
|
|
104
|
-
`${location.pathname}${location.search}${location.hash}` !=
|
|
105
|
-
`${path}#bypass-sw`
|
|
106
|
-
) {
|
|
84
|
+
if (global.qtLoadedFromShell || `${location.pathname}${location.search}${location.hash}` != `${path}#bypass-sw`) {
|
|
107
85
|
location.href = `${path}#bypass-sw`;
|
|
108
86
|
location.reload();
|
|
109
87
|
}
|
|
@@ -124,8 +102,7 @@ let pickComponentWrapper = null;
|
|
|
124
102
|
* @returns {void}
|
|
125
103
|
*/
|
|
126
104
|
export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
127
|
-
const pathname =
|
|
128
|
-
!path || path === "undefined" ? global.location.pathname : path;
|
|
105
|
+
const pathname = !path || path === "undefined" ? global.location.pathname : path;
|
|
129
106
|
|
|
130
107
|
if (global.disableAjaxNavigation) {
|
|
131
108
|
global.location = pathname;
|
|
@@ -134,8 +111,7 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
134
111
|
dispatch({ type: PAGE_LOADING });
|
|
135
112
|
getRouteData(pathname, {}).then((page) => {
|
|
136
113
|
if (!page) {
|
|
137
|
-
console &&
|
|
138
|
-
console.log("Recieved a null page. Expecting the browser to redirect.");
|
|
114
|
+
console && console.log("Recieved a null page. Expecting the browser to redirect.");
|
|
139
115
|
return;
|
|
140
116
|
}
|
|
141
117
|
|
|
@@ -147,8 +123,7 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
147
123
|
}
|
|
148
124
|
|
|
149
125
|
Promise.resolve(
|
|
150
|
-
pickComponentWrapper &&
|
|
151
|
-
pickComponentWrapper.preloadComponent(page.pageType, page.subPageType)
|
|
126
|
+
pickComponentWrapper && pickComponentWrapper.preloadComponent(page.pageType, page.subPageType)
|
|
152
127
|
).then(() => {
|
|
153
128
|
dispatch({
|
|
154
129
|
type: NAVIGATE_TO_PAGE,
|
|
@@ -177,8 +152,7 @@ export function navigateToPage(dispatch, path, doNotPushPath) {
|
|
|
177
152
|
* @returns {void}
|
|
178
153
|
*/
|
|
179
154
|
export function maybeNavigateTo(path, store) {
|
|
180
|
-
if (store.getState().qt.currentPath != path)
|
|
181
|
-
navigateToPage(store.dispatch, path, true);
|
|
155
|
+
if (store.getState().qt.currentPath != path) navigateToPage(store.dispatch, path, true);
|
|
182
156
|
}
|
|
183
157
|
|
|
184
158
|
/**
|
|
@@ -205,24 +179,12 @@ export function maybeSetUrl(path, title) {
|
|
|
205
179
|
* @param {callback} callback Callback on completion
|
|
206
180
|
*/
|
|
207
181
|
export function renderComponent(clazz, container, store, props = {}, callback) {
|
|
208
|
-
const component = React.createElement(
|
|
209
|
-
Provider,
|
|
210
|
-
{ store },
|
|
211
|
-
React.createElement(clazz, props || {})
|
|
212
|
-
);
|
|
182
|
+
const component = React.createElement(Provider, { store }, React.createElement(clazz, props || {}));
|
|
213
183
|
|
|
214
184
|
if (props.hydrate) {
|
|
215
|
-
return ReactDOM.hydrate(
|
|
216
|
-
component,
|
|
217
|
-
document.getElementById(container),
|
|
218
|
-
callback
|
|
219
|
-
);
|
|
185
|
+
return ReactDOM.hydrate(component, document.getElementById(container), callback);
|
|
220
186
|
}
|
|
221
|
-
return ReactDOM.render(
|
|
222
|
-
component,
|
|
223
|
-
document.getElementById(container),
|
|
224
|
-
callback
|
|
225
|
-
);
|
|
187
|
+
return ReactDOM.render(component, document.getElementById(container), callback);
|
|
226
188
|
}
|
|
227
189
|
|
|
228
190
|
/**
|
|
@@ -233,19 +195,11 @@ export function renderComponent(clazz, container, store, props = {}, callback) {
|
|
|
233
195
|
* @param {Object} props Properties to bootstrap the component with
|
|
234
196
|
* @param {boolean} props.hydrate Hydrate the component instead of rendering it
|
|
235
197
|
*/
|
|
236
|
-
export function renderIsomorphicComponent(
|
|
237
|
-
container,
|
|
238
|
-
store,
|
|
239
|
-
pickComponent,
|
|
240
|
-
props
|
|
241
|
-
) {
|
|
198
|
+
export function renderIsomorphicComponent(container, store, pickComponent, props) {
|
|
242
199
|
if (!store.getState().qt.disableIsomorphicComponent) {
|
|
243
200
|
pickComponentWrapper = makePickComponentSync(pickComponent);
|
|
244
201
|
return pickComponentWrapper
|
|
245
|
-
.preloadComponent(
|
|
246
|
-
store.getState().qt.pageType,
|
|
247
|
-
store.getState().qt.subPageType
|
|
248
|
-
)
|
|
202
|
+
.preloadComponent(store.getState().qt.pageType, store.getState().qt.subPageType)
|
|
249
203
|
.then(() =>
|
|
250
204
|
renderComponent(
|
|
251
205
|
IsomorphicComponent,
|
|
@@ -267,12 +221,7 @@ export function renderIsomorphicComponent(
|
|
|
267
221
|
* @param {Object} props Properties to bootstrap the component with
|
|
268
222
|
*/
|
|
269
223
|
export function renderBreakingNews(container, store, view, props) {
|
|
270
|
-
return renderComponent(
|
|
271
|
-
BreakingNews,
|
|
272
|
-
container,
|
|
273
|
-
store,
|
|
274
|
-
Object.assign({ view }, props)
|
|
275
|
-
);
|
|
224
|
+
return renderComponent(BreakingNews, container, store, Object.assign({ view }, props));
|
|
276
225
|
}
|
|
277
226
|
|
|
278
227
|
function getJsonContent(id) {
|
|
@@ -306,8 +255,7 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
306
255
|
global.app = app;
|
|
307
256
|
const { location } = global;
|
|
308
257
|
const path = `${location.pathname}${location.search || ""}`;
|
|
309
|
-
const staticData =
|
|
310
|
-
global.staticPageStoreContent || getJsonContent("static-page");
|
|
258
|
+
const staticData = global.staticPageStoreContent || getJsonContent("static-page");
|
|
311
259
|
const dataPromise = staticData
|
|
312
260
|
? Promise.resolve(staticData.qt)
|
|
313
261
|
: getRouteData(path, { existingFetch: global.initialFetch });
|
|
@@ -316,10 +264,7 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
316
264
|
|
|
317
265
|
const store = createQtStore(
|
|
318
266
|
reducers,
|
|
319
|
-
(staticData && staticData.qt) ||
|
|
320
|
-
global.initialPage ||
|
|
321
|
-
getJsonContent("initial-page") ||
|
|
322
|
-
{},
|
|
267
|
+
(staticData && staticData.qt) || global.initialPage || getJsonContent("initial-page") || {},
|
|
323
268
|
{}
|
|
324
269
|
);
|
|
325
270
|
|
|
@@ -331,8 +276,7 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
331
276
|
|
|
332
277
|
function doStartApp(page, opts) {
|
|
333
278
|
if (!page) {
|
|
334
|
-
console &&
|
|
335
|
-
console.log("Received a null page. Expecting the browser to redirect.");
|
|
279
|
+
console && console.log("Received a null page. Expecting the browser to redirect.");
|
|
336
280
|
return;
|
|
337
281
|
}
|
|
338
282
|
|
|
@@ -345,20 +289,18 @@ export function startApp(renderApplication, reducers, opts) {
|
|
|
345
289
|
const { config: { "theme-attributes": pageThemeAttributes = {} } = {} } = page;
|
|
346
290
|
const version = pageThemeAttributes["cache-burst"] || app.getAppVersion();
|
|
347
291
|
|
|
348
|
-
const serviceWorkerPromise = registerServiceWorker({...opts, version});
|
|
292
|
+
const serviceWorkerPromise = registerServiceWorker({ ...opts, version });
|
|
349
293
|
|
|
350
294
|
setupServiceWorkerUpdates(serviceWorkerPromise, app, store, page, opts);
|
|
351
295
|
|
|
352
296
|
runWithTiming("qt_render", () => renderApplication(store));
|
|
353
297
|
|
|
354
|
-
history.listen((change) =>
|
|
355
|
-
app.maybeNavigateTo(`${change.pathname}${change.search || ""}`, store)
|
|
356
|
-
);
|
|
298
|
+
history.listen((change) => app.maybeNavigateTo(`${change.pathname}${change.search || ""}`, store));
|
|
357
299
|
|
|
358
300
|
registerPageView(store.getState().qt);
|
|
359
301
|
|
|
360
302
|
if (page.title) {
|
|
361
|
-
global.document.title = get(
|
|
303
|
+
global.document.title = global.pageTitle = get(
|
|
362
304
|
page,
|
|
363
305
|
["data", "customSeo", "title"],
|
|
364
306
|
get(page, ["data", "story", "seo", "meta-title"], page.title)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
## Migrate from v6 to v7 of @quintype/framework
|
|
2
|
+
|
|
3
|
+
In version 7 of @quintype/framework, we've bumped [webpack](https://www.npmjs.com/package/webpack) from version 4 to 5. Please refer webpack's official migration doc [here](https://webpack.js.org/migrate/5/)
|
|
4
|
+
|
|
5
|
+
PR in malibu for reference > https://github.com/quintype/malibu-advanced/pull/332/files
|
|
6
|
+
|
|
7
|
+
In your malibu app,
|
|
8
|
+
|
|
9
|
+
- bump `"@quintype/framework": "^7.x.x"`
|
|
10
|
+
- bump build `"@quintype/build": "^4.x.x",`
|
|
11
|
+
- bump components (if applicable) `"@quintype/components": "^3.x.x"`
|
|
12
|
+
- bump arrow (if applicable) `"@quintype/arrow": "^3.x.x"`
|
|
13
|
+
- bump SEO `"@quintype/seo": "^1.39.x"`
|
|
14
|
+
- update `react` and `react-dom` to latest minor version (16.14.0 at the time of writing)
|
|
15
|
+
- update `react-redux` to latest minor version (7.2.5 at the time of writing)
|
|
16
|
+
- you'll also need a library like [axios](https://www.npmjs.com/package/axios) or something similar to make api calls for HMR to work during development
|
|
17
|
+
- Bump following dependancies (whichever are applicable):
|
|
18
|
+
- "lint-staged": "^11.2.3",
|
|
19
|
+
"nodemon": "^2.0.14",
|
|
20
|
+
"postcss": "^8.3.11",
|
|
21
|
+
"eslint": "^8.1.0",
|
|
22
|
+
"prettier": "2.4.1",
|
|
23
|
+
"react-test-renderer": "^17.0.2",
|
|
24
|
+
"stylelint": "^14.0.0",
|
|
25
|
+
"stylelint-config-recommended-scss": "^5.0.0",
|
|
26
|
+
"stylelint-scss": "^4.0.0",
|
|
27
|
+
"svg-sprite-loader": "^6.0.10",
|
|
28
|
+
"svg-transform-loader": "^2.0.13",
|
|
29
|
+
"webpack": "^5.59.1",
|
|
30
|
+
"webpack-bundle-analyzer": "^4.5.0",
|
|
31
|
+
"webpack-cli": "4.9.1",
|
|
32
|
+
"webpack-dev-server": "^4.3.1",
|
|
33
|
+
"svgo-loader": "^3.0.0"
|
|
34
|
+
- create a file called `nodemon.json`, add following to it
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"verbose": true,
|
|
38
|
+
"delay": 2500
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
- in `app/server/helpers/index.js`, change
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
function getAsset(asset, qtAssetHelpers) {
|
|
45
|
+
const { assetPath, readAsset } = qtAssetHelpers;
|
|
46
|
+
return assetPath(asset) ? readAsset(asset) : "";
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
to
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
async function getAsset(asset, qtAssetHelpers) {
|
|
54
|
+
const { assetPath, readAsset } = qtAssetHelpers;
|
|
55
|
+
const assetAbsolutePath = assetPath(asset);
|
|
56
|
+
|
|
57
|
+
if (process.env.NODE_ENV === "development") {
|
|
58
|
+
try {
|
|
59
|
+
// using axios here, can use any other package to make below call
|
|
60
|
+
const { data } = await axios.get(assetAbsolutePath);
|
|
61
|
+
return data;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.warn("HMR chunk rendering failure");
|
|
64
|
+
console.warn(error);
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return assetAbsolutePath ? readAsset(asset) : "";
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- webpack has changed the API of `webpack.config.js` (check migration doc given above fore more info), so we gotta change the config accordingly. _Please note that your project might not need below change if you're not using SVG sprites. In that case please change the webpack config as per the new API_
|
|
74
|
+
|
|
75
|
+
change what's applicable
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const webpackConfig = require("@quintype/build/config/webpack");
|
|
79
|
+
const path = require("path");
|
|
80
|
+
|
|
81
|
+
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
|
|
82
|
+
const svgSprite = {
|
|
83
|
+
test: /\.svg$/,
|
|
84
|
+
loader: "svg-sprite-loader",
|
|
85
|
+
options: {
|
|
86
|
+
extract: true,
|
|
87
|
+
publicPath: "/",
|
|
88
|
+
symbolId: (filePath) => {
|
|
89
|
+
return path.basename(filePath).replace(".svg", "").toLowerCase();
|
|
90
|
+
},
|
|
91
|
+
spriteFilename: process.env.NODE_ENV === "production" ? "sprite-[hash].svg" : "sprite.svg",
|
|
92
|
+
esModule: false,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
webpackConfig.module.rules.push(svgSprite);
|
|
97
|
+
webpackConfig.module.rules.find((rule) => rule.loader === "file-loader").exclude = [
|
|
98
|
+
/app\/assets\/icons\/[a-z-]+\.svg$/,
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
const svgPlugin = () =>
|
|
102
|
+
new SpriteLoaderPlugin({
|
|
103
|
+
plainSprite: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
webpackConfig.plugins.push(svgPlugin());
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
...webpackConfig,
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
to
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin");
|
|
117
|
+
const path = require("path");
|
|
118
|
+
const webpackConfig = require("@quintype/build/config/webpack");
|
|
119
|
+
|
|
120
|
+
const { plugins, output, module: webpackModule } = webpackConfig;
|
|
121
|
+
if (process.env.NODE_ENV !== "production") output.path = path.resolve("./public");
|
|
122
|
+
const getSpritePlugin = () => new SpriteLoaderPlugin({ plainSprite: true });
|
|
123
|
+
const insertIntoIndex = (arr, index, newItem) => [...arr.slice(0, index), newItem, ...arr.slice(index)];
|
|
124
|
+
const enhancedPlugins = insertIntoIndex(plugins, 1, getSpritePlugin());
|
|
125
|
+
const spriteRule = {
|
|
126
|
+
test: /\.svg$/,
|
|
127
|
+
use: [
|
|
128
|
+
{
|
|
129
|
+
loader: "svg-sprite-loader",
|
|
130
|
+
options: {
|
|
131
|
+
extract: true,
|
|
132
|
+
spriteFilename: process.env.NODE_ENV === "production" ? "svg-sprite-[hash].svg" : "svg-sprite.svg",
|
|
133
|
+
esModule: false,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
"svg-transform-loader",
|
|
137
|
+
"svgo-loader",
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const enhancedRules = insertIntoIndex(webpackModule.rules, 5, spriteRule);
|
|
142
|
+
enhancedRules[8] = {
|
|
143
|
+
test: /\.(jpe?g|gif|png|woff|woff2|eot|ttf|wav|mp3|ico|mp4)$/,
|
|
144
|
+
loader: "file-loader",
|
|
145
|
+
options: { context: "./app/assets", name: "[name].[ext]" },
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
module.exports = {
|
|
149
|
+
...webpackConfig,
|
|
150
|
+
module: { ...webpackModule, ...{ rules: enhancedRules } },
|
|
151
|
+
plugins: enhancedPlugins,
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- please test thoroughly. Also webpack 5 shows warnings in browser, please resolve them if present
|
package/jsdoc.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quintype/framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.2-gtm.0",
|
|
4
4
|
"description": "Libraries to help build Quintype Node.js apps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,75 +26,76 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/quintype/quintype-node-framework#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ampproject/toolbox-optimizer": "2.8.
|
|
30
|
-
"@quintype/amp": "^2.4.
|
|
29
|
+
"@ampproject/toolbox-optimizer": "2.8.3",
|
|
30
|
+
"@quintype/amp": "^2.4.17",
|
|
31
31
|
"@quintype/backend": "^2.1.0",
|
|
32
|
-
"@quintype/components": "^
|
|
32
|
+
"@quintype/components": "^3.0.0",
|
|
33
33
|
"@quintype/prerender-node": "^3.2.24",
|
|
34
34
|
"@quintype/seo": "^1.38.1",
|
|
35
35
|
"atob": "^2.1.2",
|
|
36
|
+
"chalk": "^4.1.2",
|
|
36
37
|
"cluster": "^0.7.7",
|
|
37
38
|
"compression": "^1.7.4",
|
|
38
|
-
"ejs": "^
|
|
39
|
-
"express": "^4.
|
|
40
|
-
"firebase": "^
|
|
39
|
+
"ejs": "^3.1.6",
|
|
40
|
+
"express": "^4.17.1",
|
|
41
|
+
"firebase": "^9.1.1",
|
|
41
42
|
"get-youtube-id": "^1.0.1",
|
|
42
43
|
"grpc": "^1.21.1",
|
|
43
|
-
"http-proxy": "^1.
|
|
44
|
-
"js-yaml": "^
|
|
45
|
-
"lodash": "^4.17.
|
|
44
|
+
"http-proxy": "^1.18.1",
|
|
45
|
+
"js-yaml": "^4.1.0",
|
|
46
|
+
"lodash": "^4.17.21",
|
|
46
47
|
"mocha-snapshots": "^4.2.0",
|
|
47
|
-
"morgan": "^1.
|
|
48
|
+
"morgan": "^1.10.0",
|
|
48
49
|
"path-to-regexp": "^6.2.0",
|
|
49
|
-
"react": "^16.
|
|
50
|
-
"react-dom": "^16.
|
|
51
|
-
"react-redux": "^7.
|
|
52
|
-
"react-router": "^5.
|
|
53
|
-
"redux": "^4.
|
|
50
|
+
"react": "^16.14.0",
|
|
51
|
+
"react-dom": "^16.14.0",
|
|
52
|
+
"react-redux": "^7.2.5",
|
|
53
|
+
"react-router": "^5.2.1",
|
|
54
|
+
"redux": "^4.1.1",
|
|
54
55
|
"request-promise": "^4.2.6",
|
|
55
|
-
"sleep-promise": "^
|
|
56
|
-
"winston": "3.
|
|
56
|
+
"sleep-promise": "^9.1.0",
|
|
57
|
+
"winston": "3.3.3"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"@babel/eslint-parser": "^7.
|
|
60
|
-
"@loadable/component": "^5.
|
|
61
|
-
"@loadable/server": "^5.
|
|
62
|
-
"@quintype/build": "^3.13.
|
|
60
|
+
"@babel/eslint-parser": "^7.15.7",
|
|
61
|
+
"@loadable/component": "^5.15.0",
|
|
62
|
+
"@loadable/server": "^5.15.1",
|
|
63
|
+
"@quintype/build": "^3.13.1",
|
|
63
64
|
"babel-plugin-quintype-assets": "^1.1.1",
|
|
64
|
-
"babel-plugin-react-css-modules": "^5.2.
|
|
65
|
+
"babel-plugin-react-css-modules": "^5.2.6",
|
|
65
66
|
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
|
|
66
67
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
|
67
68
|
"babel-preset-es2015": "^6.24.1",
|
|
68
69
|
"babel-preset-es2015-tree-shaking": "^1.0.1",
|
|
69
70
|
"babel-preset-react": "^6.24.1",
|
|
70
71
|
"babel-register": "^6.26.0",
|
|
71
|
-
"better-docs": "^
|
|
72
|
-
"eslint": "^
|
|
73
|
-
"eslint-config-prettier": "^
|
|
74
|
-
"eslint-config-standard": "^
|
|
75
|
-
"eslint-plugin-import": "^2.
|
|
76
|
-
"eslint-plugin-node": "^
|
|
77
|
-
"eslint-plugin-prettier": "^
|
|
78
|
-
"eslint-plugin-promise": "^
|
|
79
|
-
"eslint-plugin-react": "^7.
|
|
80
|
-
"eslint-plugin-standard": "^4.0
|
|
81
|
-
"gh-pages": "^2.
|
|
82
|
-
"history": "^
|
|
83
|
-
"husky": "^
|
|
84
|
-
"jsdoc": "^3.6.
|
|
85
|
-
"jsdom": "^
|
|
72
|
+
"better-docs": "^2.3.2",
|
|
73
|
+
"eslint": "^7.32.0",
|
|
74
|
+
"eslint-config-prettier": "^8.3.0",
|
|
75
|
+
"eslint-config-standard": "^16.0.3",
|
|
76
|
+
"eslint-plugin-import": "^2.24.2",
|
|
77
|
+
"eslint-plugin-node": "^11.1.0",
|
|
78
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
79
|
+
"eslint-plugin-promise": "^5.1.0",
|
|
80
|
+
"eslint-plugin-react": "^7.26.1",
|
|
81
|
+
"eslint-plugin-standard": "^4.1.0",
|
|
82
|
+
"gh-pages": "^3.2.3",
|
|
83
|
+
"history": "^5.0.1",
|
|
84
|
+
"husky": "^7.0.2",
|
|
85
|
+
"jsdoc": "^3.6.7",
|
|
86
|
+
"jsdom": "^17.0.0",
|
|
86
87
|
"jsdom-global": "3.0.2",
|
|
87
|
-
"lint-staged": "^
|
|
88
|
-
"mocha": "^
|
|
89
|
-
"nyc": "^
|
|
90
|
-
"onchange": "^
|
|
88
|
+
"lint-staged": "^11.2.0",
|
|
89
|
+
"mocha": "^9.1.2",
|
|
90
|
+
"nyc": "^15.1.0",
|
|
91
|
+
"onchange": "^7.1.0",
|
|
91
92
|
"path": "^0.12.7",
|
|
92
|
-
"prettier": "^2.
|
|
93
|
-
"standard-version": "^
|
|
94
|
-
"supertest": "^
|
|
93
|
+
"prettier": "^2.4.1",
|
|
94
|
+
"standard-version": "^9.3.1",
|
|
95
|
+
"supertest": "^6.1.6"
|
|
95
96
|
},
|
|
96
97
|
"peerDependencies": {
|
|
97
|
-
"@quintype/seo": "^1.
|
|
98
|
+
"@quintype/seo": "^1.39.0"
|
|
98
99
|
},
|
|
99
100
|
"nyc": {
|
|
100
101
|
"exclude": [
|
package/server/start.js
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
// istanbul ignore file
|
|
11
11
|
// This is the start file, to be called from your start.js
|
|
12
12
|
|
|
13
|
+
const chalk = require('chalk');
|
|
13
14
|
const cluster = require("cluster");
|
|
14
15
|
const process = require("process");
|
|
15
16
|
const { initializeAllClients } = require("./api-client");
|
|
16
17
|
const logger = require("./logger");
|
|
18
|
+
const logSuccess = chalk.bold.cyanBright;
|
|
17
19
|
|
|
18
20
|
function startMaster({ workers = 4 }) {
|
|
19
21
|
let terminating = false;
|
|
@@ -62,7 +64,7 @@ function startMaster({ workers = 4 }) {
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
async function startWorker(appThunk, opts) {
|
|
65
|
-
if (process.env.NODE_ENV
|
|
67
|
+
if (process.env.NODE_ENV !== "production") {
|
|
66
68
|
require("@quintype/build")(opts);
|
|
67
69
|
}
|
|
68
70
|
require("../assetify/server")();
|
|
@@ -71,9 +73,11 @@ async function startWorker(appThunk, opts) {
|
|
|
71
73
|
const app = appThunk();
|
|
72
74
|
|
|
73
75
|
await initializeAllClients();
|
|
74
|
-
const server = app.listen(opts.port || 3000, () =>
|
|
75
|
-
console.log(
|
|
76
|
-
|
|
76
|
+
const server = app.listen(opts.port || 3000, () => {
|
|
77
|
+
console.log(logSuccess(`||=============================||`));
|
|
78
|
+
console.log(logSuccess(`|| App listening on port ${opts.port || 3000}! ||`))
|
|
79
|
+
console.log(logSuccess(`||=============================||`));
|
|
80
|
+
});
|
|
77
81
|
|
|
78
82
|
process.on("SIGTERM", () => {
|
|
79
83
|
server.close(() => {
|
|
@@ -83,7 +87,7 @@ async function startWorker(appThunk, opts) {
|
|
|
83
87
|
});
|
|
84
88
|
process.on("SIGHUP", () => {});
|
|
85
89
|
} catch (e) {
|
|
86
|
-
if (process.env.NODE_ENV
|
|
90
|
+
if (process.env.NODE_ENV !== "production") {
|
|
87
91
|
console.log(e.stack);
|
|
88
92
|
}
|
|
89
93
|
|