@modern-js/runtime 2.71.0 → 2.71.1
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/dist/cjs/core/server/stream/beforeTemplate.js +1 -1
- package/dist/cjs/core/server/string/loadable.js +1 -7
- package/dist/cjs/core/server/utils.js +26 -0
- package/dist/esm/core/server/stream/beforeTemplate.js +2 -2
- package/dist/esm/core/server/string/loadable.js +3 -26
- package/dist/esm/core/server/utils.js +27 -0
- package/dist/esm-node/core/server/stream/beforeTemplate.js +2 -2
- package/dist/esm-node/core/server/string/loadable.js +2 -8
- package/dist/esm-node/core/server/utils.js +25 -0
- package/dist/types/core/server/utils.d.ts +7 -0
- package/package.json +12 -12
|
@@ -91,7 +91,7 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
|
|
|
91
91
|
}
|
|
92
92
|
const cssChunks = matchedRouteManifests ? matchedRouteManifests === null || matchedRouteManifests === void 0 ? void 0 : matchedRouteManifests.reduce((chunks, routeManifest2) => {
|
|
93
93
|
const { referenceCssAssets = [] } = routeManifest2;
|
|
94
|
-
const _cssChunks = referenceCssAssets.filter((asset) => (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !
|
|
94
|
+
const _cssChunks = referenceCssAssets.filter((asset) => (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !(0, import_utils.hasStylesheetLink)(template, asset));
|
|
95
95
|
return [
|
|
96
96
|
...chunks,
|
|
97
97
|
..._cssChunks
|
|
@@ -145,15 +145,9 @@ class LoadableCollector {
|
|
|
145
145
|
const { template, chunkSet, config, entryName } = this.options;
|
|
146
146
|
const { enableInlineStyles } = config;
|
|
147
147
|
const atrributes = (0, import_utils.attributesToString)(this.generateAttributes());
|
|
148
|
-
const linkRegExp = /<link .*?href="([^"]+)".*?>/g;
|
|
149
|
-
const matchs = template.matchAll(linkRegExp);
|
|
150
|
-
const existedLinks = [];
|
|
151
|
-
for (const match of matchs) {
|
|
152
|
-
existedLinks.push(match[1]);
|
|
153
|
-
}
|
|
154
148
|
const css = await Promise.all(chunks.filter((chunk) => {
|
|
155
149
|
var _this_existsAssets;
|
|
156
|
-
return !
|
|
150
|
+
return !(0, import_utils.hasStylesheetLink)(template, chunk.url) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
|
|
157
151
|
}).map(async (chunk) => {
|
|
158
152
|
const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
|
|
159
153
|
if ((0, import_utils.checkIsNode)() && checkIsInline(chunk, enableInlineStyles)) {
|
|
@@ -22,6 +22,7 @@ __export(utils_exports, {
|
|
|
22
22
|
checkIsNode: () => checkIsNode,
|
|
23
23
|
getSSRConfigByEntry: () => getSSRConfigByEntry,
|
|
24
24
|
getSSRMode: () => getSSRMode,
|
|
25
|
+
hasStylesheetLink: () => hasStylesheetLink,
|
|
25
26
|
safeReplace: () => safeReplace,
|
|
26
27
|
serializeErrors: () => serializeErrors
|
|
27
28
|
});
|
|
@@ -75,12 +76,37 @@ function getSSRMode(ssrConfig) {
|
|
|
75
76
|
}
|
|
76
77
|
return (ssrConfig === null || ssrConfig === void 0 ? void 0 : ssrConfig.mode) === "stream" ? "stream" : "string";
|
|
77
78
|
}
|
|
79
|
+
const getLinkAttributes = (linkTag) => {
|
|
80
|
+
const attributes = /* @__PURE__ */ new Map();
|
|
81
|
+
const attributeRegExp = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
82
|
+
let match;
|
|
83
|
+
while (match = attributeRegExp.exec(linkTag)) {
|
|
84
|
+
const [, name, doubleQuotedValue, singleQuotedValue, unquotedValue] = match;
|
|
85
|
+
if (name.toLowerCase() === "link") {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
var _ref, _ref1;
|
|
89
|
+
attributes.set(name.toLowerCase(), (_ref1 = (_ref = doubleQuotedValue !== null && doubleQuotedValue !== void 0 ? doubleQuotedValue : singleQuotedValue) !== null && _ref !== void 0 ? _ref : unquotedValue) !== null && _ref1 !== void 0 ? _ref1 : "");
|
|
90
|
+
}
|
|
91
|
+
return attributes;
|
|
92
|
+
};
|
|
93
|
+
const hasStylesheetLink = (template, href) => {
|
|
94
|
+
var _template_match;
|
|
95
|
+
const linkTags = (_template_match = template.match(/<link\b[^>]*>/gi)) !== null && _template_match !== void 0 ? _template_match : [];
|
|
96
|
+
return linkTags.some((linkTag) => {
|
|
97
|
+
const attributes = getLinkAttributes(linkTag);
|
|
98
|
+
const linkHref = attributes.get("href");
|
|
99
|
+
const rel = attributes.get("rel");
|
|
100
|
+
return linkHref === href && (rel === null || rel === void 0 ? void 0 : rel.split(/\s+/).some((relToken) => relToken.toLowerCase() === "stylesheet"));
|
|
101
|
+
});
|
|
102
|
+
};
|
|
78
103
|
// Annotate the CommonJS export names for ESM import in node:
|
|
79
104
|
0 && (module.exports = {
|
|
80
105
|
attributesToString,
|
|
81
106
|
checkIsNode,
|
|
82
107
|
getSSRConfigByEntry,
|
|
83
108
|
getSSRMode,
|
|
109
|
+
hasStylesheetLink,
|
|
84
110
|
safeReplace,
|
|
85
111
|
serializeErrors
|
|
86
112
|
});
|
|
@@ -6,7 +6,7 @@ import { matchRoutes } from "@modern-js/runtime-utils/router";
|
|
|
6
6
|
import { CHUNK_CSS_PLACEHOLDER } from "../constants";
|
|
7
7
|
import { createReplaceHelemt } from "../helmet";
|
|
8
8
|
import { buildHtml } from "../shared";
|
|
9
|
-
import { checkIsNode, safeReplace } from "../utils";
|
|
9
|
+
import { checkIsNode, hasStylesheetLink, safeReplace } from "../utils";
|
|
10
10
|
var readAsset = function() {
|
|
11
11
|
var _ref = _async_to_generator(function(chunk) {
|
|
12
12
|
var fs, path, filepath;
|
|
@@ -95,7 +95,7 @@ function _buildShellBeforeTemplate() {
|
|
|
95
95
|
cssChunks = matchedRouteManifests ? matchedRouteManifests === null || matchedRouteManifests === void 0 ? void 0 : matchedRouteManifests.reduce(function(chunks, routeManifest2) {
|
|
96
96
|
var _routeManifest_referenceCssAssets = routeManifest2.referenceCssAssets, referenceCssAssets = _routeManifest_referenceCssAssets === void 0 ? [] : _routeManifest_referenceCssAssets;
|
|
97
97
|
var _cssChunks = referenceCssAssets.filter(function(asset) {
|
|
98
|
-
return (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !template
|
|
98
|
+
return (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !hasStylesheetLink(template, asset);
|
|
99
99
|
});
|
|
100
100
|
return _to_consumable_array(chunks).concat(_to_consumable_array(_cssChunks));
|
|
101
101
|
}, []) : [];
|
|
@@ -6,7 +6,7 @@ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
|
|
|
6
6
|
import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
|
|
7
7
|
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
|
|
8
8
|
import { ChunkExtractor } from "@loadable/server";
|
|
9
|
-
import { attributesToString, checkIsNode } from "../utils";
|
|
9
|
+
import { attributesToString, checkIsNode, hasStylesheetLink } from "../utils";
|
|
10
10
|
var extname = function(uri) {
|
|
11
11
|
if (typeof uri !== "string" || !uri.includes(".")) {
|
|
12
12
|
return "";
|
|
@@ -232,41 +232,18 @@ var LoadableCollector = /* @__PURE__ */ function() {
|
|
|
232
232
|
_proto.emitStyleAssets = function emitStyleAssets(chunks) {
|
|
233
233
|
var _this = this;
|
|
234
234
|
return _async_to_generator(function() {
|
|
235
|
-
var _this_options, template, chunkSet, config, entryName, enableInlineStyles, atrributes,
|
|
235
|
+
var _this_options, template, chunkSet, config, entryName, enableInlineStyles, atrributes, css;
|
|
236
236
|
return _ts_generator(this, function(_state) {
|
|
237
237
|
switch (_state.label) {
|
|
238
238
|
case 0:
|
|
239
239
|
_this_options = _this.options, template = _this_options.template, chunkSet = _this_options.chunkSet, config = _this_options.config, entryName = _this_options.entryName;
|
|
240
240
|
enableInlineStyles = config.enableInlineStyles;
|
|
241
241
|
atrributes = attributesToString(_this.generateAttributes());
|
|
242
|
-
linkRegExp = /<link .*?href="([^"]+)".*?>/g;
|
|
243
|
-
matchs = template.matchAll(linkRegExp);
|
|
244
|
-
existedLinks = [];
|
|
245
|
-
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
246
|
-
try {
|
|
247
|
-
for (_iterator = matchs[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
248
|
-
match = _step.value;
|
|
249
|
-
existedLinks.push(match[1]);
|
|
250
|
-
}
|
|
251
|
-
} catch (err) {
|
|
252
|
-
_didIteratorError = true;
|
|
253
|
-
_iteratorError = err;
|
|
254
|
-
} finally {
|
|
255
|
-
try {
|
|
256
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
257
|
-
_iterator.return();
|
|
258
|
-
}
|
|
259
|
-
} finally {
|
|
260
|
-
if (_didIteratorError) {
|
|
261
|
-
throw _iteratorError;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
242
|
return [
|
|
266
243
|
4,
|
|
267
244
|
Promise.all(chunks.filter(function(chunk) {
|
|
268
245
|
var _this_existsAssets;
|
|
269
|
-
return !
|
|
246
|
+
return !hasStylesheetLink(template, chunk.url) && !((_this_existsAssets = _this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
|
|
270
247
|
}).map(function() {
|
|
271
248
|
var _ref = _async_to_generator(function(chunk) {
|
|
272
249
|
var link;
|
|
@@ -70,11 +70,38 @@ function getSSRMode(ssrConfig) {
|
|
|
70
70
|
}
|
|
71
71
|
return (ssrConfig === null || ssrConfig === void 0 ? void 0 : ssrConfig.mode) === "stream" ? "stream" : "string";
|
|
72
72
|
}
|
|
73
|
+
var getLinkAttributes = function(linkTag) {
|
|
74
|
+
var attributes = /* @__PURE__ */ new Map();
|
|
75
|
+
var attributeRegExp = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
76
|
+
var match;
|
|
77
|
+
while (match = attributeRegExp.exec(linkTag)) {
|
|
78
|
+
var _match = _sliced_to_array(match, 5), name = _match[1], doubleQuotedValue = _match[2], singleQuotedValue = _match[3], unquotedValue = _match[4];
|
|
79
|
+
if (name.toLowerCase() === "link") {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
var _ref, _ref1;
|
|
83
|
+
attributes.set(name.toLowerCase(), (_ref1 = (_ref = doubleQuotedValue !== null && doubleQuotedValue !== void 0 ? doubleQuotedValue : singleQuotedValue) !== null && _ref !== void 0 ? _ref : unquotedValue) !== null && _ref1 !== void 0 ? _ref1 : "");
|
|
84
|
+
}
|
|
85
|
+
return attributes;
|
|
86
|
+
};
|
|
87
|
+
var hasStylesheetLink = function(template, href) {
|
|
88
|
+
var _template_match;
|
|
89
|
+
var linkTags = (_template_match = template.match(/<link\b[^>]*>/gi)) !== null && _template_match !== void 0 ? _template_match : [];
|
|
90
|
+
return linkTags.some(function(linkTag) {
|
|
91
|
+
var attributes = getLinkAttributes(linkTag);
|
|
92
|
+
var linkHref = attributes.get("href");
|
|
93
|
+
var rel = attributes.get("rel");
|
|
94
|
+
return linkHref === href && (rel === null || rel === void 0 ? void 0 : rel.split(/\s+/).some(function(relToken) {
|
|
95
|
+
return relToken.toLowerCase() === "stylesheet";
|
|
96
|
+
}));
|
|
97
|
+
});
|
|
98
|
+
};
|
|
73
99
|
export {
|
|
74
100
|
attributesToString,
|
|
75
101
|
checkIsNode,
|
|
76
102
|
getSSRConfigByEntry,
|
|
77
103
|
getSSRMode,
|
|
104
|
+
hasStylesheetLink,
|
|
78
105
|
safeReplace,
|
|
79
106
|
serializeErrors
|
|
80
107
|
};
|
|
@@ -2,7 +2,7 @@ import { matchRoutes } from "@modern-js/runtime-utils/router";
|
|
|
2
2
|
import { CHUNK_CSS_PLACEHOLDER } from "../constants";
|
|
3
3
|
import { createReplaceHelemt } from "../helmet";
|
|
4
4
|
import { buildHtml } from "../shared";
|
|
5
|
-
import { checkIsNode, safeReplace } from "../utils";
|
|
5
|
+
import { checkIsNode, hasStylesheetLink, safeReplace } from "../utils";
|
|
6
6
|
const readAsset = async (chunk) => {
|
|
7
7
|
const fs = await import("fs/promises");
|
|
8
8
|
const path = await import("path");
|
|
@@ -58,7 +58,7 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
|
|
|
58
58
|
}
|
|
59
59
|
const cssChunks = matchedRouteManifests ? matchedRouteManifests === null || matchedRouteManifests === void 0 ? void 0 : matchedRouteManifests.reduce((chunks, routeManifest2) => {
|
|
60
60
|
const { referenceCssAssets = [] } = routeManifest2;
|
|
61
|
-
const _cssChunks = referenceCssAssets.filter((asset) => (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !template
|
|
61
|
+
const _cssChunks = referenceCssAssets.filter((asset) => (asset === null || asset === void 0 ? void 0 : asset.endsWith(".css")) && !hasStylesheetLink(template, asset));
|
|
62
62
|
return [
|
|
63
63
|
...chunks,
|
|
64
64
|
..._cssChunks
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChunkExtractor } from "@loadable/server";
|
|
2
|
-
import { attributesToString, checkIsNode } from "../utils";
|
|
2
|
+
import { attributesToString, checkIsNode, hasStylesheetLink } from "../utils";
|
|
3
3
|
const extname = (uri) => {
|
|
4
4
|
if (typeof uri !== "string" || !uri.includes(".")) {
|
|
5
5
|
return "";
|
|
@@ -112,15 +112,9 @@ class LoadableCollector {
|
|
|
112
112
|
const { template, chunkSet, config, entryName } = this.options;
|
|
113
113
|
const { enableInlineStyles } = config;
|
|
114
114
|
const atrributes = attributesToString(this.generateAttributes());
|
|
115
|
-
const linkRegExp = /<link .*?href="([^"]+)".*?>/g;
|
|
116
|
-
const matchs = template.matchAll(linkRegExp);
|
|
117
|
-
const existedLinks = [];
|
|
118
|
-
for (const match of matchs) {
|
|
119
|
-
existedLinks.push(match[1]);
|
|
120
|
-
}
|
|
121
115
|
const css = await Promise.all(chunks.filter((chunk) => {
|
|
122
116
|
var _this_existsAssets;
|
|
123
|
-
return !
|
|
117
|
+
return !hasStylesheetLink(template, chunk.url) && !((_this_existsAssets = this.existsAssets) === null || _this_existsAssets === void 0 ? void 0 : _this_existsAssets.includes(chunk.path));
|
|
124
118
|
}).map(async (chunk) => {
|
|
125
119
|
const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
|
|
126
120
|
if (checkIsNode() && checkIsInline(chunk, enableInlineStyles)) {
|
|
@@ -47,11 +47,36 @@ function getSSRMode(ssrConfig) {
|
|
|
47
47
|
}
|
|
48
48
|
return (ssrConfig === null || ssrConfig === void 0 ? void 0 : ssrConfig.mode) === "stream" ? "stream" : "string";
|
|
49
49
|
}
|
|
50
|
+
const getLinkAttributes = (linkTag) => {
|
|
51
|
+
const attributes = /* @__PURE__ */ new Map();
|
|
52
|
+
const attributeRegExp = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
53
|
+
let match;
|
|
54
|
+
while (match = attributeRegExp.exec(linkTag)) {
|
|
55
|
+
const [, name, doubleQuotedValue, singleQuotedValue, unquotedValue] = match;
|
|
56
|
+
if (name.toLowerCase() === "link") {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
var _ref, _ref1;
|
|
60
|
+
attributes.set(name.toLowerCase(), (_ref1 = (_ref = doubleQuotedValue !== null && doubleQuotedValue !== void 0 ? doubleQuotedValue : singleQuotedValue) !== null && _ref !== void 0 ? _ref : unquotedValue) !== null && _ref1 !== void 0 ? _ref1 : "");
|
|
61
|
+
}
|
|
62
|
+
return attributes;
|
|
63
|
+
};
|
|
64
|
+
const hasStylesheetLink = (template, href) => {
|
|
65
|
+
var _template_match;
|
|
66
|
+
const linkTags = (_template_match = template.match(/<link\b[^>]*>/gi)) !== null && _template_match !== void 0 ? _template_match : [];
|
|
67
|
+
return linkTags.some((linkTag) => {
|
|
68
|
+
const attributes = getLinkAttributes(linkTag);
|
|
69
|
+
const linkHref = attributes.get("href");
|
|
70
|
+
const rel = attributes.get("rel");
|
|
71
|
+
return linkHref === href && (rel === null || rel === void 0 ? void 0 : rel.split(/\s+/).some((relToken) => relToken.toLowerCase() === "stylesheet"));
|
|
72
|
+
});
|
|
73
|
+
};
|
|
50
74
|
export {
|
|
51
75
|
attributesToString,
|
|
52
76
|
checkIsNode,
|
|
53
77
|
getSSRConfigByEntry,
|
|
54
78
|
getSSRMode,
|
|
79
|
+
hasStylesheetLink,
|
|
55
80
|
safeReplace,
|
|
56
81
|
serializeErrors
|
|
57
82
|
};
|
|
@@ -24,3 +24,10 @@ export declare function getSSRConfigByEntry(entryName: string, ssr?: ServerUserC
|
|
|
24
24
|
loaderFailureMode?: "clientRender" | "errorBoundary";
|
|
25
25
|
};
|
|
26
26
|
export declare function getSSRMode(ssrConfig?: SSRConfig): 'string' | 'stream' | false;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the template already contains a `<link rel="stylesheet">` for `href`.
|
|
29
|
+
* Other link rels (e.g. `<link rel="prefetch">` emitted by `performance.prefetch`,
|
|
30
|
+
* or `<link rel="preload" as="style">`) may reference the same css URL but do not
|
|
31
|
+
* apply styles, so they must not block stylesheet injection during SSR.
|
|
32
|
+
*/
|
|
33
|
+
export declare const hasStylesheetLink: (template: string, href: string) => boolean;
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "2.71.
|
|
18
|
+
"version": "2.71.1",
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=14.17.6"
|
|
21
21
|
},
|
|
@@ -218,13 +218,13 @@
|
|
|
218
218
|
"react-is": "^18",
|
|
219
219
|
"react-side-effect": "^2.1.2",
|
|
220
220
|
"styled-components": "^5.3.1",
|
|
221
|
-
"@modern-js/plugin
|
|
222
|
-
"@modern-js/plugin": "2.71.
|
|
223
|
-
"@modern-js/
|
|
224
|
-
"@modern-js/
|
|
225
|
-
"@modern-js/
|
|
226
|
-
"@modern-js/types": "2.71.
|
|
227
|
-
"@modern-js/utils": "2.71.
|
|
221
|
+
"@modern-js/plugin": "2.71.1",
|
|
222
|
+
"@modern-js/plugin-data-loader": "2.71.1",
|
|
223
|
+
"@modern-js/plugin-v2": "2.71.1",
|
|
224
|
+
"@modern-js/render": "2.71.1",
|
|
225
|
+
"@modern-js/runtime-utils": "2.71.1",
|
|
226
|
+
"@modern-js/types": "2.71.1",
|
|
227
|
+
"@modern-js/utils": "2.71.1"
|
|
228
228
|
},
|
|
229
229
|
"peerDependencies": {
|
|
230
230
|
"react": ">=17",
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
},
|
|
233
233
|
"devDependencies": {
|
|
234
234
|
"@remix-run/web-fetch": "^4.1.3",
|
|
235
|
-
"@rsbuild/core": "1.7.
|
|
235
|
+
"@rsbuild/core": "1.7.6",
|
|
236
236
|
"@testing-library/react": "^13.4.0",
|
|
237
237
|
"@types/cookie": "0.6.0",
|
|
238
238
|
"@types/invariant": "^2.2.30",
|
|
@@ -247,11 +247,11 @@
|
|
|
247
247
|
"ts-jest": "^29.1.0",
|
|
248
248
|
"ts-node": "^10.9.1",
|
|
249
249
|
"typescript": "^5",
|
|
250
|
-
"webpack": "^5.
|
|
251
|
-
"@modern-js/app-tools": "2.71.
|
|
250
|
+
"webpack": "^5.108.0",
|
|
251
|
+
"@modern-js/app-tools": "2.71.1",
|
|
252
252
|
"@scripts/build": "2.66.0",
|
|
253
253
|
"@scripts/jest-config": "2.66.0",
|
|
254
|
-
"@modern-js/core": "2.71.
|
|
254
|
+
"@modern-js/core": "2.71.1"
|
|
255
255
|
},
|
|
256
256
|
"sideEffects": false,
|
|
257
257
|
"publishConfig": {
|