@jsenv/core 40.2.0 → 40.3.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/build/build.js +355 -133
- package/dist/client/directory_listing/jsenv_core_node_modules.js +2 -2
- package/dist/client/html_syntax_error/html_syntax_error.html +1 -1
- package/dist/jsenv_core_packages.js +282 -129
- package/dist/start_dev_server/start_dev_server.js +284 -28
- package/package.json +21 -18
- package/src/build/build.js +70 -76
- package/src/build/build_specifier_manager.js +10 -29
- package/src/dev/start_dev_server.js +9 -0
- package/src/kitchen/kitchen.js +11 -0
- package/src/kitchen/url_graph/references.js +13 -13
- package/src/kitchen/url_graph/url_graph.js +21 -1
- package/src/plugins/html_syntax_error_fallback/client/html_syntax_error.html +1 -1
- package/src/plugins/html_syntax_error_fallback/jsenv_plugin_html_syntax_error_fallback.js +2 -10
- package/src/plugins/package_side_effects/jsenv_plugin_package_side_effects.js +213 -0
- package/src/plugins/plugin_controller.js +5 -2
- package/src/plugins/plugins.js +7 -0
- package/src/plugins/protocol_file/jsenv_plugin_directory_listing.js +6 -5
- package/src/plugins/protocol_file/jsenv_plugin_protocol_file.js +2 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lorsqu'on bundle un package ayant pas le field sideEffects
|
|
3
|
+
* alors on fini potentiellement par dire
|
|
4
|
+
* sideEffect: false
|
|
5
|
+
* sur le package racine alors qu'on en sait rien
|
|
6
|
+
* on pourrait mettre un package.json dans dist dans ce cas
|
|
7
|
+
* qui ne déclare pas le field side effect afin
|
|
8
|
+
* d'override le package.json du project qui lui dit qu'il ny en a pas
|
|
9
|
+
*
|
|
10
|
+
* On part du principe pour le moment que c'est la respo du package racine de déclarer cela
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { updateJsonFileSync } from "@jsenv/filesystem";
|
|
15
|
+
import { isSpecifierForNodeBuiltin } from "@jsenv/node-esm-resolution/src/node_builtin_specifiers.js";
|
|
16
|
+
import { URL_META } from "@jsenv/url-meta";
|
|
17
|
+
import { urlToRelativeUrl } from "@jsenv/urls";
|
|
18
|
+
|
|
19
|
+
export const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
|
|
20
|
+
if (!packageDirectory.url) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const packageJson = packageDirectory.read(packageDirectory.url);
|
|
24
|
+
if (!packageJson) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
const { sideEffects } = packageJson;
|
|
28
|
+
if (sideEffects !== false && !Array.isArray(sideEffects)) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const sideEffectFileUrlSet = new Set();
|
|
33
|
+
const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
|
|
34
|
+
.href;
|
|
35
|
+
|
|
36
|
+
const normalizeSideEffectFileUrl = (url) => {
|
|
37
|
+
const urlRelativeToPackage = urlToRelativeUrl(url, packageDirectory.url);
|
|
38
|
+
return urlRelativeToPackage[0] === "."
|
|
39
|
+
? urlRelativeToPackage
|
|
40
|
+
: `./${urlRelativeToPackage}`;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const sideEffectBuildFileUrls = [];
|
|
44
|
+
|
|
45
|
+
const packageSideEffectsCacheMap = new Map();
|
|
46
|
+
const readSideEffectInfoFromClosestPackage = (urlInfo) => {
|
|
47
|
+
const closestPackageDirectoryUrl = urlInfo.packageDirectoryUrl;
|
|
48
|
+
const closestPackageJSON = urlInfo.packageJSON;
|
|
49
|
+
if (!closestPackageJSON) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
const fromCache = packageSideEffectsCacheMap.get(
|
|
53
|
+
closestPackageDirectoryUrl,
|
|
54
|
+
);
|
|
55
|
+
if (fromCache) {
|
|
56
|
+
return fromCache.value;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return storePackageSideEffect(
|
|
60
|
+
closestPackageDirectoryUrl,
|
|
61
|
+
closestPackageJSON,
|
|
62
|
+
);
|
|
63
|
+
} catch {
|
|
64
|
+
return storePackageSideEffect(closestPackageDirectoryUrl, null);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const storePackageSideEffect = (packageDirectoryUrl, packageJSON) => {
|
|
68
|
+
if (!packageJSON) {
|
|
69
|
+
packageSideEffectsCacheMap.set(packageDirectoryUrl, { value: undefined });
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const value = packageJSON.sideEffects;
|
|
73
|
+
if (Array.isArray(value)) {
|
|
74
|
+
const noSideEffect = {
|
|
75
|
+
has: false,
|
|
76
|
+
reason: "not listed in package.json side effects",
|
|
77
|
+
packageDirectoryUrl,
|
|
78
|
+
};
|
|
79
|
+
const hasSideEffect = {
|
|
80
|
+
has: true,
|
|
81
|
+
reason: "listed in package.json side effects",
|
|
82
|
+
packageDirectoryUrl,
|
|
83
|
+
};
|
|
84
|
+
const sideEffectPatterns = {};
|
|
85
|
+
for (const v of value) {
|
|
86
|
+
sideEffectPatterns[v] = v;
|
|
87
|
+
}
|
|
88
|
+
const associations = URL_META.resolveAssociations(
|
|
89
|
+
{ sideEffects: sideEffectPatterns },
|
|
90
|
+
packageDirectoryUrl,
|
|
91
|
+
);
|
|
92
|
+
const getSideEffectInfo = (urlInfo) => {
|
|
93
|
+
const meta = URL_META.applyAssociations({
|
|
94
|
+
url: urlInfo.url,
|
|
95
|
+
associations,
|
|
96
|
+
});
|
|
97
|
+
const sideEffectKey = meta.sideEffects;
|
|
98
|
+
if (sideEffectKey) {
|
|
99
|
+
return {
|
|
100
|
+
...hasSideEffect,
|
|
101
|
+
reason: `"${sideEffectKey}" listed in package.json side effects`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return noSideEffect;
|
|
105
|
+
};
|
|
106
|
+
packageSideEffectsCacheMap.set(packageDirectoryUrl, {
|
|
107
|
+
value: getSideEffectInfo,
|
|
108
|
+
});
|
|
109
|
+
return getSideEffectInfo;
|
|
110
|
+
}
|
|
111
|
+
if (value === false) {
|
|
112
|
+
const noSideEffect = {
|
|
113
|
+
has: false,
|
|
114
|
+
reason: "package.json side effects is false",
|
|
115
|
+
packageDirectoryUrl,
|
|
116
|
+
};
|
|
117
|
+
packageSideEffectsCacheMap.set(packageDirectoryUrl, {
|
|
118
|
+
value: noSideEffect,
|
|
119
|
+
});
|
|
120
|
+
return noSideEffect;
|
|
121
|
+
}
|
|
122
|
+
const hasSideEffect = {
|
|
123
|
+
has: true,
|
|
124
|
+
reason: "package.json side effects is true",
|
|
125
|
+
packageDirectoryUrl,
|
|
126
|
+
};
|
|
127
|
+
packageSideEffectsCacheMap.set(packageDirectoryUrl, {
|
|
128
|
+
value: hasSideEffect,
|
|
129
|
+
});
|
|
130
|
+
return hasSideEffect;
|
|
131
|
+
};
|
|
132
|
+
const getSideEffectInfoFromClosestPackage = (urlInfo) => {
|
|
133
|
+
const sideEffectInfoFromClosestPackage =
|
|
134
|
+
readSideEffectInfoFromClosestPackage(urlInfo);
|
|
135
|
+
if (sideEffectInfoFromClosestPackage === undefined) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
if (typeof sideEffectInfoFromClosestPackage === "function") {
|
|
139
|
+
return sideEffectInfoFromClosestPackage(urlInfo);
|
|
140
|
+
}
|
|
141
|
+
return sideEffectInfoFromClosestPackage;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
name: "jsenv:package_side_effects",
|
|
146
|
+
appliesDuring: "build",
|
|
147
|
+
urlInfoCreated: (urlInfo) => {
|
|
148
|
+
const url = urlInfo.url;
|
|
149
|
+
if (isSpecifierForNodeBuiltin(url)) {
|
|
150
|
+
urlInfo.contentSideEffects.push({
|
|
151
|
+
sideEffect: "no",
|
|
152
|
+
reason: "node builtin module",
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (url.startsWith("file:")) {
|
|
157
|
+
const sideEffectFromClosestPackage =
|
|
158
|
+
getSideEffectInfoFromClosestPackage(urlInfo);
|
|
159
|
+
if (sideEffectFromClosestPackage) {
|
|
160
|
+
// if (sideEffectFromClosestPackage.has) {
|
|
161
|
+
// console.log(`have side effect: ${url}`);
|
|
162
|
+
// } else {
|
|
163
|
+
// console.log(`no side effect: ${url}`);
|
|
164
|
+
// }
|
|
165
|
+
urlInfo.contentSideEffects.push(sideEffectFromClosestPackage);
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
refineBuildUrlContent: (buildUrlInfo, { buildUrl }) => {
|
|
171
|
+
for (const sideEffect of buildUrlInfo.contentSideEffects) {
|
|
172
|
+
if (sideEffect.has) {
|
|
173
|
+
sideEffectBuildFileUrls.push(buildUrl);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
refineBuild: () => {
|
|
179
|
+
if (sideEffectBuildFileUrls.length === 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
let sideEffectsToAdd = [];
|
|
183
|
+
if (sideEffects === false) {
|
|
184
|
+
sideEffectsToAdd = sideEffectBuildFileUrls;
|
|
185
|
+
} else if (Array.isArray(sideEffects)) {
|
|
186
|
+
for (const sideEffectFileRelativeUrl of sideEffects) {
|
|
187
|
+
const sideEffectFileUrl = new URL(
|
|
188
|
+
sideEffectFileRelativeUrl,
|
|
189
|
+
packageDirectory.url,
|
|
190
|
+
).href;
|
|
191
|
+
sideEffectFileUrlSet.add(sideEffectFileUrl);
|
|
192
|
+
}
|
|
193
|
+
for (const url of sideEffectBuildFileUrls) {
|
|
194
|
+
if (sideEffectFileUrlSet.has(url)) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
sideEffectsToAdd.push(url);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (sideEffectsToAdd.length === 0) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const finalSideEffects = Array.isArray(sideEffects) ? sideEffects : [];
|
|
205
|
+
for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
|
|
206
|
+
finalSideEffects.push(normalizeSideEffectFileUrl(sideEffectBuildUrl));
|
|
207
|
+
}
|
|
208
|
+
updateJsonFileSync(packageJsonFileUrl, {
|
|
209
|
+
sideEffects: finalSideEffects,
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
};
|
|
@@ -289,15 +289,18 @@ const HOOK_NAMES = [
|
|
|
289
289
|
"redirectReference",
|
|
290
290
|
"transformReferenceSearchParams",
|
|
291
291
|
"formatReference",
|
|
292
|
+
"urlInfoCreated",
|
|
292
293
|
"fetchUrlContent",
|
|
293
294
|
"transformUrlContent",
|
|
294
295
|
"finalizeUrlContent",
|
|
295
296
|
"bundle", // is called only during build
|
|
296
|
-
"
|
|
297
|
+
"optimizeBuildUrlContent", // is called only during build
|
|
297
298
|
"cooked",
|
|
298
299
|
"augmentResponse", // is called only during dev/tests
|
|
299
300
|
"destroy",
|
|
300
301
|
"effect",
|
|
302
|
+
"refineBuildUrlContent", // called only during build
|
|
303
|
+
"refineBuild", // called only during build
|
|
301
304
|
];
|
|
302
305
|
|
|
303
306
|
const testAppliesDuring = (plugin, kitchen) => {
|
|
@@ -408,7 +411,7 @@ const returnValueAssertions = [
|
|
|
408
411
|
"fetchUrlContent",
|
|
409
412
|
"transformUrlContent",
|
|
410
413
|
"finalizeUrlContent",
|
|
411
|
-
"
|
|
414
|
+
"optimizeBuildUrlContent",
|
|
412
415
|
],
|
|
413
416
|
assertion: (valueReturned, urlInfo, { hook }) => {
|
|
414
417
|
if (typeof valueReturned === "string" || Buffer.isBuffer(valueReturned)) {
|
package/src/plugins/plugins.js
CHANGED
|
@@ -25,11 +25,13 @@ import { jsenvPluginRibbon } from "./ribbon/jsenv_plugin_ribbon.js";
|
|
|
25
25
|
import { jsenvPluginCleanHTML } from "./clean_html/jsenv_plugin_clean_html.js";
|
|
26
26
|
import { jsenvPluginChromeDevtoolsJson } from "./chrome_devtools_json/jsenv_plugin_chrome_devtools_json.js";
|
|
27
27
|
import { jsenvPluginAutoreloadOnServerRestart } from "./autoreload_on_server_restart/jsenv_plugin_autoreload_on_server_restart.js";
|
|
28
|
+
import { jsenvPluginPackageSideEffects } from "./package_side_effects/jsenv_plugin_package_side_effects.js";
|
|
28
29
|
|
|
29
30
|
export const getCorePlugins = ({
|
|
30
31
|
rootDirectoryUrl,
|
|
31
32
|
mainFilePath,
|
|
32
33
|
runtimeCompat,
|
|
34
|
+
packageDirectory,
|
|
33
35
|
sourceFilesConfig,
|
|
34
36
|
|
|
35
37
|
referenceAnalysis = {},
|
|
@@ -50,6 +52,7 @@ export const getCorePlugins = ({
|
|
|
50
52
|
cacheControl,
|
|
51
53
|
scenarioPlaceholders = true,
|
|
52
54
|
ribbon = true,
|
|
55
|
+
packageSideEffects = false,
|
|
53
56
|
} = {}) => {
|
|
54
57
|
if (cacheControl === true) {
|
|
55
58
|
cacheControl = {};
|
|
@@ -90,6 +93,7 @@ export const getCorePlugins = ({
|
|
|
90
93
|
directoryListing,
|
|
91
94
|
rootDirectoryUrl,
|
|
92
95
|
mainFilePath,
|
|
96
|
+
packageDirectory,
|
|
93
97
|
sourceFilesConfig,
|
|
94
98
|
}),
|
|
95
99
|
{
|
|
@@ -133,5 +137,8 @@ export const getCorePlugins = ({
|
|
|
133
137
|
...(ribbon ? [jsenvPluginRibbon({ rootDirectoryUrl, ...ribbon })] : []),
|
|
134
138
|
jsenvPluginCleanHTML(),
|
|
135
139
|
jsenvPluginChromeDevtoolsJson(),
|
|
140
|
+
...(packageSideEffects
|
|
141
|
+
? [jsenvPluginPackageSideEffects({ rootDirectoryUrl, packageDirectory })]
|
|
142
|
+
: []),
|
|
136
143
|
];
|
|
137
144
|
};
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
|
|
25
25
|
import {
|
|
26
26
|
compareFileUrls,
|
|
27
|
-
lookupPackageDirectory,
|
|
28
27
|
readEntryStatSync,
|
|
29
28
|
registerDirectoryLifecycle,
|
|
30
29
|
} from "@jsenv/filesystem";
|
|
@@ -49,6 +48,7 @@ export const jsenvPluginDirectoryListing = ({
|
|
|
49
48
|
urlMocks = false,
|
|
50
49
|
autoreload = true,
|
|
51
50
|
directoryContentMagicName,
|
|
51
|
+
packageDirectory,
|
|
52
52
|
rootDirectoryUrl,
|
|
53
53
|
mainFilePath,
|
|
54
54
|
sourceFilesConfig,
|
|
@@ -134,6 +134,7 @@ export const jsenvPluginDirectoryListing = ({
|
|
|
134
134
|
directoryContentMagicName,
|
|
135
135
|
rootDirectoryUrl,
|
|
136
136
|
mainFilePath,
|
|
137
|
+
packageDirectory,
|
|
137
138
|
enoent,
|
|
138
139
|
}),
|
|
139
140
|
},
|
|
@@ -221,6 +222,7 @@ const generateDirectoryListingInjection = (
|
|
|
221
222
|
{
|
|
222
223
|
rootDirectoryUrl,
|
|
223
224
|
mainFilePath,
|
|
225
|
+
packageDirectory,
|
|
224
226
|
request,
|
|
225
227
|
urlMocks,
|
|
226
228
|
directoryContentMagicName,
|
|
@@ -240,14 +242,13 @@ const generateDirectoryListingInjection = (
|
|
|
240
242
|
firstExistingDirectoryUrl,
|
|
241
243
|
});
|
|
242
244
|
package_workspaces: {
|
|
243
|
-
|
|
244
|
-
if (!packageDirectoryUrl) {
|
|
245
|
+
if (!packageDirectory.url) {
|
|
245
246
|
break package_workspaces;
|
|
246
247
|
}
|
|
247
|
-
if (String(
|
|
248
|
+
if (String(packageDirectory.url) === String(serverRootDirectoryUrl)) {
|
|
248
249
|
break package_workspaces;
|
|
249
250
|
}
|
|
250
|
-
rootDirectoryUrl =
|
|
251
|
+
rootDirectoryUrl = packageDirectory.url;
|
|
251
252
|
// if (String(firstExistingDirectoryUrl) === String(serverRootDirectoryUrl)) {
|
|
252
253
|
// let packageContent;
|
|
253
254
|
// try {
|
|
@@ -15,6 +15,7 @@ export const jsenvPluginProtocolFile = ({
|
|
|
15
15
|
directoryListing,
|
|
16
16
|
rootDirectoryUrl,
|
|
17
17
|
mainFilePath,
|
|
18
|
+
packageDirectory,
|
|
18
19
|
sourceFilesConfig,
|
|
19
20
|
}) => {
|
|
20
21
|
return [
|
|
@@ -78,6 +79,7 @@ export const jsenvPluginProtocolFile = ({
|
|
|
78
79
|
directoryContentMagicName,
|
|
79
80
|
rootDirectoryUrl,
|
|
80
81
|
mainFilePath,
|
|
82
|
+
packageDirectory,
|
|
81
83
|
sourceFilesConfig,
|
|
82
84
|
}),
|
|
83
85
|
]
|