@jsenv/core 41.4.25 → 41.4.27
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/build/build.js +46 -4
- package/dist/start_dev_server/start_dev_server.js +67 -5
- package/package.json +6 -6
- package/src/dev/dev_server_plugins/dev_server_plugin_serve_source_files.js +21 -1
- package/src/plugins/import_meta_css/jsenv_plugin_import_meta_css.js +34 -0
- package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +16 -4
package/dist/build/build.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseHtml, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, stringifyHtmlAst, applyBabelPlugins, generateUrlForInlineContent, injectJsenvScript, parseJsWithAcorn, visitHtmlNodes, analyzeScriptNode, getHtmlNodeText, getHtmlNodeAttribute, getHtmlNodePosition, getUrlForContentInsideHtml, setHtmlNodeAttributes, setHtmlNodeText, parseCssUrls, getHtmlNodeAttributePosition, parseSrcSet, removeHtmlNodeText, parseJsUrls, getUrlForContentInsideJs, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, findHtmlNode, removeHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
1
|
+
import { parseHtml, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, stringifyHtmlAst, applyBabelPlugins, generateUrlForInlineContent, injectJsenvScript, parseJsWithAcorn, visitHtmlNodes, analyzeScriptNode, getHtmlNodeText, getHtmlNodeAttribute, getHtmlNodePosition, getUrlForContentInsideHtml, setHtmlNodeAttributes, setHtmlNodeText, parseCssUrls, getHtmlNodeAttributePosition, parseSrcSet, removeHtmlNodeText, parseJsUrls, getUrlForContentInsideJs, renderCssTemplateLiteral, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, findHtmlNode, removeHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
|
|
2
2
|
import { bundleJsModules, jsenvPluginBundling } from "@jsenv/plugin-bundling";
|
|
3
3
|
import { jsenvPluginMinification } from "@jsenv/plugin-minification";
|
|
4
4
|
import { jsenvPluginTranspilation, jsenvPluginJsModuleFallback } from "@jsenv/plugin-transpilation";
|
|
@@ -5689,9 +5689,17 @@ const parseAndTransformJsReferences = async (
|
|
|
5689
5689
|
|
|
5690
5690
|
sequentialActions.push(async () => {
|
|
5691
5691
|
await inlineUrlInfo.cook();
|
|
5692
|
-
const
|
|
5693
|
-
|
|
5694
|
-
|
|
5692
|
+
const { substitutions } = inlineReferenceInfo;
|
|
5693
|
+
const replacement = substitutions
|
|
5694
|
+
? // the expressions the template holds take their placeholder's place
|
|
5695
|
+
// back; a template literal is written whatever the runtime supports,
|
|
5696
|
+
// transpilation runs after and lowers it when it has to
|
|
5697
|
+
renderCssTemplateLiteral(inlineUrlInfo.content, substitutions)
|
|
5698
|
+
: JS_QUOTES.escapeSpecialChars(inlineUrlInfo.content, { quote });
|
|
5699
|
+
if (replacement === null) {
|
|
5700
|
+
// a placeholder did not survive: the source stays as it was written
|
|
5701
|
+
return;
|
|
5702
|
+
}
|
|
5695
5703
|
magicSource.replace({
|
|
5696
5704
|
start: inlineReferenceInfo.start,
|
|
5697
5705
|
end: inlineReferenceInfo.end,
|
|
@@ -8314,6 +8322,12 @@ const jsenvPluginNodeRuntime = ({ runtimeCompat }) => {
|
|
|
8314
8322
|
* import.meta.css = css;
|
|
8315
8323
|
* ```
|
|
8316
8324
|
*
|
|
8325
|
+
* "jsenv:js_reference_analysis" reads the css assigned here as an inline css and
|
|
8326
|
+
* sends it through the css pipeline: transpilation, url() resolution, minification,
|
|
8327
|
+
* comments. A "${}" standing where a css value stands is swapped for a placeholder
|
|
8328
|
+
* and put back afterwards; anywhere else it makes the template unreadable and the
|
|
8329
|
+
* css is shipped exactly as written, with everything the pipeline does lost.
|
|
8330
|
+
*
|
|
8317
8331
|
*/
|
|
8318
8332
|
|
|
8319
8333
|
|
|
@@ -8346,6 +8360,12 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
8346
8360
|
return null;
|
|
8347
8361
|
}
|
|
8348
8362
|
if (urlInfo.context.build) {
|
|
8363
|
+
if (hasModuleScopeAssignment(urlInfo.contentAst)) {
|
|
8364
|
+
urlInfo.contentSideEffects.push({
|
|
8365
|
+
has: true,
|
|
8366
|
+
reason: "import.meta.css assigned at module scope",
|
|
8367
|
+
});
|
|
8368
|
+
}
|
|
8349
8369
|
const packageName = urlInfo.packageName;
|
|
8350
8370
|
const packageDirectoryUrl =
|
|
8351
8371
|
urlInfo.packageDirectoryUrl || urlInfo.context.rootDirectoryUrl;
|
|
@@ -8389,6 +8409,28 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
8389
8409
|
};
|
|
8390
8410
|
};
|
|
8391
8411
|
|
|
8412
|
+
// A stylesheet assigned at module scope is adopted when the module runs: that
|
|
8413
|
+
// assignment IS the module's side effect. It has to be told, because a
|
|
8414
|
+
// package.json "sideEffects" list is authoritative once it exists — a module
|
|
8415
|
+
// it does not name is dropped whole when it is imported for nothing else, and
|
|
8416
|
+
// its css silently leaves the build.
|
|
8417
|
+
const hasModuleScopeAssignment = (ast) => {
|
|
8418
|
+
for (const node of ast.body) {
|
|
8419
|
+
if (node.type !== "ExpressionStatement") {
|
|
8420
|
+
continue;
|
|
8421
|
+
}
|
|
8422
|
+
const { expression } = node;
|
|
8423
|
+
if (
|
|
8424
|
+
expression.type === "AssignmentExpression" &&
|
|
8425
|
+
expression.operator === "=" &&
|
|
8426
|
+
getImportMetaPropertyName(expression.left) === "css"
|
|
8427
|
+
) {
|
|
8428
|
+
return true;
|
|
8429
|
+
}
|
|
8430
|
+
}
|
|
8431
|
+
return false;
|
|
8432
|
+
};
|
|
8433
|
+
|
|
8392
8434
|
const babelPluginRewriteImportMetaCssAssignment = (
|
|
8393
8435
|
{ types: t },
|
|
8394
8436
|
{ relativeUrl },
|
|
@@ -3,7 +3,7 @@ import { existsSync, readFileSync, realpathSync, readdirSync, lstatSync, statSyn
|
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import { urlToRelativeUrl, registerFileLifecycle, lookupPackageDirectory, readPackageAtOrNull, generateContentFrame, errorToHTML, DATA_URL, CONTENT_TYPE, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, urlToExtension, urlToBasename, applyNodeEsmResolution, URL_META, readCustomConditionsFromProcessArgs, urlIsOrIsInsideOf, collectFiles, registerDirectoryLifecycle, readEntryStatSync, applyFileSystemMagicResolution, getExtensionsToTry, urlToFilename, asUrlWithoutSearch, ensurePathnameTrailingSlash, compareFileUrls, setUrlExtension, createDetailedMessage, stringifyUrlSite, injectQueryParamsIntoSpecifier, isSpecifierForNodeBuiltin, injectQueryParams, urlToFileSystemPath, writeFileSync, moveUrl, ensureWindowsDriveLetter, validateResponseIntegrity, setUrlFilename, getCallerPosition, asSpecifierWithoutSearch, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, createLogger, normalizeUrl, ANSI, RUNTIME_COMPAT, formatError, assertAndNormalizeDirectoryUrl, createTaskLog } from "./jsenv_core_packages.js";
|
|
5
5
|
import { createPluginsController } from "@jsenv/server/src/plugins_controller.js";
|
|
6
|
-
import { parseHtml, injectJsenvScript, stringifyHtmlAst, parseCssUrls, getHtmlNodeAttribute, getHtmlNodePosition, getHtmlNodeAttributePosition, setHtmlNodeAttributes, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, getHtmlNodeText, analyzeScriptNode, visitHtmlNodes, parseJsUrls, getUrlForContentInsideJs, applyBabelPlugins, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn } from "@jsenv/ast";
|
|
6
|
+
import { parseHtml, injectJsenvScript, stringifyHtmlAst, parseCssUrls, getHtmlNodeAttribute, getHtmlNodePosition, getHtmlNodeAttributePosition, setHtmlNodeAttributes, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, getHtmlNodeText, analyzeScriptNode, visitHtmlNodes, parseJsUrls, getUrlForContentInsideJs, renderCssTemplateLiteral, applyBabelPlugins, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn } from "@jsenv/ast";
|
|
7
7
|
import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
|
|
8
8
|
import { jsenvPluginTranspilation } from "@jsenv/plugin-transpilation";
|
|
9
9
|
import { createMagicSource, composeTwoSourcemaps, generateSourcemapFileUrl, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
|
|
@@ -2369,9 +2369,17 @@ const parseAndTransformJsReferences = async (
|
|
|
2369
2369
|
|
|
2370
2370
|
sequentialActions.push(async () => {
|
|
2371
2371
|
await inlineUrlInfo.cook();
|
|
2372
|
-
const
|
|
2373
|
-
|
|
2374
|
-
|
|
2372
|
+
const { substitutions } = inlineReferenceInfo;
|
|
2373
|
+
const replacement = substitutions
|
|
2374
|
+
? // the expressions the template holds take their placeholder's place
|
|
2375
|
+
// back; a template literal is written whatever the runtime supports,
|
|
2376
|
+
// transpilation runs after and lowers it when it has to
|
|
2377
|
+
renderCssTemplateLiteral(inlineUrlInfo.content, substitutions)
|
|
2378
|
+
: JS_QUOTES.escapeSpecialChars(inlineUrlInfo.content, { quote });
|
|
2379
|
+
if (replacement === null) {
|
|
2380
|
+
// a placeholder did not survive: the source stays as it was written
|
|
2381
|
+
return;
|
|
2382
|
+
}
|
|
2375
2383
|
magicSource.replace({
|
|
2376
2384
|
start: inlineReferenceInfo.start,
|
|
2377
2385
|
end: inlineReferenceInfo.end,
|
|
@@ -6133,6 +6141,12 @@ const jsenvPluginNodeRuntime = ({ runtimeCompat }) => {
|
|
|
6133
6141
|
* import.meta.css = css;
|
|
6134
6142
|
* ```
|
|
6135
6143
|
*
|
|
6144
|
+
* "jsenv:js_reference_analysis" reads the css assigned here as an inline css and
|
|
6145
|
+
* sends it through the css pipeline: transpilation, url() resolution, minification,
|
|
6146
|
+
* comments. A "${}" standing where a css value stands is swapped for a placeholder
|
|
6147
|
+
* and put back afterwards; anywhere else it makes the template unreadable and the
|
|
6148
|
+
* css is shipped exactly as written, with everything the pipeline does lost.
|
|
6149
|
+
*
|
|
6136
6150
|
*/
|
|
6137
6151
|
|
|
6138
6152
|
|
|
@@ -6165,6 +6179,12 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
6165
6179
|
return null;
|
|
6166
6180
|
}
|
|
6167
6181
|
if (urlInfo.context.build) {
|
|
6182
|
+
if (hasModuleScopeAssignment(urlInfo.contentAst)) {
|
|
6183
|
+
urlInfo.contentSideEffects.push({
|
|
6184
|
+
has: true,
|
|
6185
|
+
reason: "import.meta.css assigned at module scope",
|
|
6186
|
+
});
|
|
6187
|
+
}
|
|
6168
6188
|
const packageName = urlInfo.packageName;
|
|
6169
6189
|
const packageDirectoryUrl =
|
|
6170
6190
|
urlInfo.packageDirectoryUrl || urlInfo.context.rootDirectoryUrl;
|
|
@@ -6208,6 +6228,28 @@ const jsenvPluginImportMetaCss = () => {
|
|
|
6208
6228
|
};
|
|
6209
6229
|
};
|
|
6210
6230
|
|
|
6231
|
+
// A stylesheet assigned at module scope is adopted when the module runs: that
|
|
6232
|
+
// assignment IS the module's side effect. It has to be told, because a
|
|
6233
|
+
// package.json "sideEffects" list is authoritative once it exists — a module
|
|
6234
|
+
// it does not name is dropped whole when it is imported for nothing else, and
|
|
6235
|
+
// its css silently leaves the build.
|
|
6236
|
+
const hasModuleScopeAssignment = (ast) => {
|
|
6237
|
+
for (const node of ast.body) {
|
|
6238
|
+
if (node.type !== "ExpressionStatement") {
|
|
6239
|
+
continue;
|
|
6240
|
+
}
|
|
6241
|
+
const { expression } = node;
|
|
6242
|
+
if (
|
|
6243
|
+
expression.type === "AssignmentExpression" &&
|
|
6244
|
+
expression.operator === "=" &&
|
|
6245
|
+
getImportMetaPropertyName(expression.left) === "css"
|
|
6246
|
+
) {
|
|
6247
|
+
return true;
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
return false;
|
|
6251
|
+
};
|
|
6252
|
+
|
|
6211
6253
|
const babelPluginRewriteImportMetaCssAssignment = (
|
|
6212
6254
|
{ types: t },
|
|
6213
6255
|
{ relativeUrl },
|
|
@@ -11660,7 +11702,17 @@ const devServerPluginServeSourceFiles = ({
|
|
|
11660
11702
|
// so it is derived from the url and cooked first.
|
|
11661
11703
|
const inlineParentUrl = getInlineContentParentUrl(requestedUrl);
|
|
11662
11704
|
if (inlineParentUrl) {
|
|
11663
|
-
|
|
11705
|
+
const inlineParentUrlInfo =
|
|
11706
|
+
kitchen.graph.getUrlInfo(inlineParentUrl);
|
|
11707
|
+
// A parent cooked before the file changed still holds the
|
|
11708
|
+
// references it had then; the inline content is as fresh as its
|
|
11709
|
+
// parent, so the parent is cooked again before being asked.
|
|
11710
|
+
if (
|
|
11711
|
+
!inlineParentUrlInfo ||
|
|
11712
|
+
inlineParentUrlInfo.content === undefined ||
|
|
11713
|
+
!inlineParentUrlInfo.contentFinalized ||
|
|
11714
|
+
!inlineParentUrlInfo.isValid()
|
|
11715
|
+
) {
|
|
11664
11716
|
const rootUrlInfo = kitchen.graph.rootUrlInfo;
|
|
11665
11717
|
const inlineParentWebUrl = WEB_URL_CONVERTER.asWebUrl(
|
|
11666
11718
|
inlineParentUrl,
|
|
@@ -11684,6 +11736,16 @@ const devServerPluginServeSourceFiles = ({
|
|
|
11684
11736
|
request.resource,
|
|
11685
11737
|
inlineParentUrl,
|
|
11686
11738
|
);
|
|
11739
|
+
if (!reference) {
|
|
11740
|
+
// The parent does not hold that inline content: the script was
|
|
11741
|
+
// edited out of the html. What the graph kept under this url is
|
|
11742
|
+
// what the parent used to say, it must not be served.
|
|
11743
|
+
return {
|
|
11744
|
+
url: requestedUrl,
|
|
11745
|
+
status: 404,
|
|
11746
|
+
statusText: "no inline content at this position",
|
|
11747
|
+
};
|
|
11748
|
+
}
|
|
11687
11749
|
}
|
|
11688
11750
|
}
|
|
11689
11751
|
if (reference) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "41.4.
|
|
3
|
+
"version": "41.4.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tool to develop, test and build js projects",
|
|
6
6
|
"repository": {
|
|
@@ -73,12 +73,12 @@
|
|
|
73
73
|
"test:snapshot_clear": "npx @jsenv/filesystem clear **/tests/**/side_effects/"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@jsenv/ast": "6.9.
|
|
77
|
-
"@jsenv/js-module-fallback": "1.5.
|
|
76
|
+
"@jsenv/ast": "6.9.3",
|
|
77
|
+
"@jsenv/js-module-fallback": "1.5.2",
|
|
78
78
|
"@jsenv/plugin-bundling": "2.10.18",
|
|
79
|
-
"@jsenv/plugin-minification": "1.7.
|
|
80
|
-
"@jsenv/plugin-supervisor": "1.8.
|
|
81
|
-
"@jsenv/plugin-transpilation": "1.6.
|
|
79
|
+
"@jsenv/plugin-minification": "1.7.11",
|
|
80
|
+
"@jsenv/plugin-supervisor": "1.8.14",
|
|
81
|
+
"@jsenv/plugin-transpilation": "1.6.3",
|
|
82
82
|
"@jsenv/server": "17.6.3",
|
|
83
83
|
"@jsenv/sourcemap": "1.4.2",
|
|
84
84
|
"react-table": "7.8.0"
|
|
@@ -287,7 +287,17 @@ export const devServerPluginServeSourceFiles = ({
|
|
|
287
287
|
// so it is derived from the url and cooked first.
|
|
288
288
|
const inlineParentUrl = getInlineContentParentUrl(requestedUrl);
|
|
289
289
|
if (inlineParentUrl) {
|
|
290
|
-
|
|
290
|
+
const inlineParentUrlInfo =
|
|
291
|
+
kitchen.graph.getUrlInfo(inlineParentUrl);
|
|
292
|
+
// A parent cooked before the file changed still holds the
|
|
293
|
+
// references it had then; the inline content is as fresh as its
|
|
294
|
+
// parent, so the parent is cooked again before being asked.
|
|
295
|
+
if (
|
|
296
|
+
!inlineParentUrlInfo ||
|
|
297
|
+
inlineParentUrlInfo.content === undefined ||
|
|
298
|
+
!inlineParentUrlInfo.contentFinalized ||
|
|
299
|
+
!inlineParentUrlInfo.isValid()
|
|
300
|
+
) {
|
|
291
301
|
const rootUrlInfo = kitchen.graph.rootUrlInfo;
|
|
292
302
|
const inlineParentWebUrl = WEB_URL_CONVERTER.asWebUrl(
|
|
293
303
|
inlineParentUrl,
|
|
@@ -311,6 +321,16 @@ export const devServerPluginServeSourceFiles = ({
|
|
|
311
321
|
request.resource,
|
|
312
322
|
inlineParentUrl,
|
|
313
323
|
);
|
|
324
|
+
if (!reference) {
|
|
325
|
+
// The parent does not hold that inline content: the script was
|
|
326
|
+
// edited out of the html. What the graph kept under this url is
|
|
327
|
+
// what the parent used to say, it must not be served.
|
|
328
|
+
return {
|
|
329
|
+
url: requestedUrl,
|
|
330
|
+
status: 404,
|
|
331
|
+
statusText: "no inline content at this position",
|
|
332
|
+
};
|
|
333
|
+
}
|
|
314
334
|
}
|
|
315
335
|
}
|
|
316
336
|
if (reference) {
|
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
* import.meta.css = css;
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
|
+
* "jsenv:js_reference_analysis" reads the css assigned here as an inline css and
|
|
25
|
+
* sends it through the css pipeline: transpilation, url() resolution, minification,
|
|
26
|
+
* comments. A "${}" standing where a css value stands is swapped for a placeholder
|
|
27
|
+
* and put back afterwards; anywhere else it makes the template unreadable and the
|
|
28
|
+
* css is shipped exactly as written, with everything the pipeline does lost.
|
|
29
|
+
*
|
|
24
30
|
*/
|
|
25
31
|
|
|
26
32
|
import {
|
|
@@ -58,6 +64,12 @@ export const jsenvPluginImportMetaCss = () => {
|
|
|
58
64
|
return null;
|
|
59
65
|
}
|
|
60
66
|
if (urlInfo.context.build) {
|
|
67
|
+
if (hasModuleScopeAssignment(urlInfo.contentAst)) {
|
|
68
|
+
urlInfo.contentSideEffects.push({
|
|
69
|
+
has: true,
|
|
70
|
+
reason: "import.meta.css assigned at module scope",
|
|
71
|
+
});
|
|
72
|
+
}
|
|
61
73
|
const packageName = urlInfo.packageName;
|
|
62
74
|
const packageDirectoryUrl =
|
|
63
75
|
urlInfo.packageDirectoryUrl || urlInfo.context.rootDirectoryUrl;
|
|
@@ -101,6 +113,28 @@ export const jsenvPluginImportMetaCss = () => {
|
|
|
101
113
|
};
|
|
102
114
|
};
|
|
103
115
|
|
|
116
|
+
// A stylesheet assigned at module scope is adopted when the module runs: that
|
|
117
|
+
// assignment IS the module's side effect. It has to be told, because a
|
|
118
|
+
// package.json "sideEffects" list is authoritative once it exists — a module
|
|
119
|
+
// it does not name is dropped whole when it is imported for nothing else, and
|
|
120
|
+
// its css silently leaves the build.
|
|
121
|
+
const hasModuleScopeAssignment = (ast) => {
|
|
122
|
+
for (const node of ast.body) {
|
|
123
|
+
if (node.type !== "ExpressionStatement") {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const { expression } = node;
|
|
127
|
+
if (
|
|
128
|
+
expression.type === "AssignmentExpression" &&
|
|
129
|
+
expression.operator === "=" &&
|
|
130
|
+
getImportMetaPropertyName(expression.left) === "css"
|
|
131
|
+
) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
};
|
|
137
|
+
|
|
104
138
|
const babelPluginRewriteImportMetaCssAssignment = (
|
|
105
139
|
{ types: t },
|
|
106
140
|
{ relativeUrl },
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getUrlForContentInsideJs,
|
|
3
|
+
parseJsUrls,
|
|
4
|
+
renderCssTemplateLiteral,
|
|
5
|
+
} from "@jsenv/ast";
|
|
2
6
|
import {
|
|
3
7
|
isWebWorkerEntryPointReference,
|
|
4
8
|
isWebWorkerUrlInfo,
|
|
@@ -70,9 +74,17 @@ const parseAndTransformJsReferences = async (
|
|
|
70
74
|
|
|
71
75
|
sequentialActions.push(async () => {
|
|
72
76
|
await inlineUrlInfo.cook();
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
const { substitutions } = inlineReferenceInfo;
|
|
78
|
+
const replacement = substitutions
|
|
79
|
+
? // the expressions the template holds take their placeholder's place
|
|
80
|
+
// back; a template literal is written whatever the runtime supports,
|
|
81
|
+
// transpilation runs after and lowers it when it has to
|
|
82
|
+
renderCssTemplateLiteral(inlineUrlInfo.content, substitutions)
|
|
83
|
+
: JS_QUOTES.escapeSpecialChars(inlineUrlInfo.content, { quote });
|
|
84
|
+
if (replacement === null) {
|
|
85
|
+
// a placeholder did not survive: the source stays as it was written
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
76
88
|
magicSource.replace({
|
|
77
89
|
start: inlineReferenceInfo.start,
|
|
78
90
|
end: inlineReferenceInfo.end,
|