@jsenv/core 41.5.2 → 41.5.4
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 +58 -15
- package/dist/start_dev_server/start_dev_server.js +45 -9
- package/package.json +6 -6
- package/src/build/build.js +13 -6
- package/src/kitchen/web_workers.js +4 -1
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +13 -6
- package/src/plugins/plugins.js +5 -1
- package/src/plugins/resolution_node_esm/jsenv_plugin_node_esm_resolution.js +5 -0
- package/src/plugins/resolution_node_esm/node_esm_resolver.js +18 -1
package/dist/build/build.js
CHANGED
|
@@ -5589,7 +5589,10 @@ const decideLinkExpectedType = (linkReference, htmlUrlInfo) => {
|
|
|
5589
5589
|
// - new SharedWorker()
|
|
5590
5590
|
// - navigator.serviceWorker.register()
|
|
5591
5591
|
const isWebWorkerEntryPointReference = (reference) => {
|
|
5592
|
-
if (
|
|
5592
|
+
if (
|
|
5593
|
+
reference.subtype === "new_url_first_arg" ||
|
|
5594
|
+
reference.subtype === "import_meta_resolve"
|
|
5595
|
+
) {
|
|
5593
5596
|
return ["worker", "service_worker", "shared_worker"].includes(
|
|
5594
5597
|
reference.expectedSubtype,
|
|
5595
5598
|
);
|
|
@@ -6020,6 +6023,8 @@ const createNodeEsmResolver = ({
|
|
|
6020
6023
|
packageDirectory,
|
|
6021
6024
|
runtimeCompat,
|
|
6022
6025
|
rootDirectoryUrl,
|
|
6026
|
+
dev,
|
|
6027
|
+
build,
|
|
6023
6028
|
packageConditions = {},
|
|
6024
6029
|
packageConditionsConfig,
|
|
6025
6030
|
preservesSymlink,
|
|
@@ -6037,6 +6042,8 @@ const createNodeEsmResolver = ({
|
|
|
6037
6042
|
packageConditionsConfig,
|
|
6038
6043
|
rootDirectoryUrl,
|
|
6039
6044
|
runtimeCompat,
|
|
6045
|
+
dev,
|
|
6046
|
+
build,
|
|
6040
6047
|
preservesSymlink,
|
|
6041
6048
|
},
|
|
6042
6049
|
);
|
|
@@ -6198,6 +6205,8 @@ const createBuildPackageConditions = (
|
|
|
6198
6205
|
packageConditionsConfig,
|
|
6199
6206
|
rootDirectoryUrl,
|
|
6200
6207
|
runtimeCompat,
|
|
6208
|
+
dev,
|
|
6209
|
+
build,
|
|
6201
6210
|
preservesSymlink,
|
|
6202
6211
|
},
|
|
6203
6212
|
) => {
|
|
@@ -6287,8 +6296,19 @@ const createBuildPackageConditions = (
|
|
|
6287
6296
|
};
|
|
6288
6297
|
|
|
6289
6298
|
const conditionDefaultResolvers = {
|
|
6299
|
+
// "dev:*" conditions target packages under active development: they
|
|
6300
|
+
// apply to files resolved outside node_modules (sources, workspace
|
|
6301
|
+
// symlinks), never to installed packages.
|
|
6290
6302
|
"dev:*": devResolver,
|
|
6291
|
-
"development"
|
|
6303
|
+
// "development"/"production" follow the ecosystem semantics
|
|
6304
|
+
// (Vite, webpack): they describe how the app runs, not where the
|
|
6305
|
+
// package lives, so they apply to every package, node_modules
|
|
6306
|
+
// included. Dev server resolves "development"; build resolves
|
|
6307
|
+
// "production", unless the build is dev-flavored
|
|
6308
|
+
// (build({ entryPoints: { "./file.js": { dev: true } } }))
|
|
6309
|
+
// in which case it resolves "development" too.
|
|
6310
|
+
"development": Boolean(dev),
|
|
6311
|
+
"production": Boolean(build) && !dev,
|
|
6292
6312
|
"node": nodeRuntimeEnabled,
|
|
6293
6313
|
"browser": !nodeRuntimeEnabled,
|
|
6294
6314
|
"import": true,
|
|
@@ -6502,6 +6522,7 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
6502
6522
|
resolutionConfig = {},
|
|
6503
6523
|
packageConditions,
|
|
6504
6524
|
packageConditionsConfig = {},
|
|
6525
|
+
dev,
|
|
6505
6526
|
}) => {
|
|
6506
6527
|
let nodeEsmResolverDefault;
|
|
6507
6528
|
const resolverMap = new Map();
|
|
@@ -6523,6 +6544,8 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
6523
6544
|
packageDirectory,
|
|
6524
6545
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
6525
6546
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
6547
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
6548
|
+
build: kitchenContext.build,
|
|
6526
6549
|
packageConditions,
|
|
6527
6550
|
packageConditionsConfig: {
|
|
6528
6551
|
...kitchenContext.packageConditionsConfig,
|
|
@@ -6540,6 +6563,8 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
6540
6563
|
packageDirectory,
|
|
6541
6564
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
6542
6565
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
6566
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
6567
|
+
build: kitchenContext.build,
|
|
6543
6568
|
// preservesSymlink: true,
|
|
6544
6569
|
packageConditions,
|
|
6545
6570
|
packageConditionsConfig: {
|
|
@@ -8186,11 +8211,16 @@ const babelPluginMetadataExpressionPaths = (
|
|
|
8186
8211
|
* - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
|
|
8187
8212
|
* - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
|
|
8188
8213
|
*
|
|
8214
|
+
* A build can also be dev-flavored (build({ entryPoints: { "./file.js": { dev: true } } })):
|
|
8215
|
+
* import.meta.dev is then replaced by true, so a package can publish a build
|
|
8216
|
+
* that keeps its dev-only code, exposed to consumers via the "development"
|
|
8217
|
+
* package export condition.
|
|
8218
|
+
*
|
|
8189
8219
|
* TODO: ideally during dev we would keep import.meta.dev and ensure we set it to true rather than replacing it with true?
|
|
8190
8220
|
*/
|
|
8191
8221
|
|
|
8192
8222
|
|
|
8193
|
-
const jsenvPluginImportMetaScenarios = () => {
|
|
8223
|
+
const jsenvPluginImportMetaScenarios = ({ dev } = {}) => {
|
|
8194
8224
|
return {
|
|
8195
8225
|
name: "jsenv:import_meta_scenario",
|
|
8196
8226
|
appliesDuring: "*",
|
|
@@ -8220,17 +8250,19 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
8220
8250
|
}
|
|
8221
8251
|
},
|
|
8222
8252
|
});
|
|
8223
|
-
const
|
|
8253
|
+
const devNodes = importMetaScenarioNodes.dev;
|
|
8254
|
+
const buildNodes = importMetaScenarioNodes.build;
|
|
8224
8255
|
const replacements = [];
|
|
8225
8256
|
const replace = (node, value) => {
|
|
8226
8257
|
replacements.push({ node, value });
|
|
8227
8258
|
};
|
|
8228
8259
|
if (urlInfo.context.build) {
|
|
8229
8260
|
// during build ensure replacement for tree-shaking
|
|
8230
|
-
|
|
8231
|
-
|
|
8261
|
+
// (or for keeping dev code when the build is dev-flavored)
|
|
8262
|
+
devNodes.forEach((node) => {
|
|
8263
|
+
replace(node, dev ? "true" : "undefined");
|
|
8232
8264
|
});
|
|
8233
|
-
|
|
8265
|
+
buildNodes.forEach((node) => {
|
|
8234
8266
|
replace(node, "true");
|
|
8235
8267
|
});
|
|
8236
8268
|
} else {
|
|
@@ -8238,7 +8270,7 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
8238
8270
|
// it will be evaluated to undefined.
|
|
8239
8271
|
// Moreover it can be surprising to see some "undefined"
|
|
8240
8272
|
// when source file contains "import.meta.build"
|
|
8241
|
-
|
|
8273
|
+
devNodes.forEach((node) => {
|
|
8242
8274
|
replace(node, "true");
|
|
8243
8275
|
});
|
|
8244
8276
|
}
|
|
@@ -10116,6 +10148,9 @@ const getCorePlugins = ({
|
|
|
10116
10148
|
runtimeCompat,
|
|
10117
10149
|
packageDirectory,
|
|
10118
10150
|
sourceFilesConfig,
|
|
10151
|
+
// during build, a dev-flavored entry point sets dev: true
|
|
10152
|
+
// (during dev the kitchen context already says so, no need to pass it)
|
|
10153
|
+
dev,
|
|
10119
10154
|
|
|
10120
10155
|
referenceAnalysis = {},
|
|
10121
10156
|
nodeEsmResolution = {},
|
|
@@ -10212,6 +10247,7 @@ const getCorePlugins = ({
|
|
|
10212
10247
|
resolutionConfig: nodeEsmResolution,
|
|
10213
10248
|
packageConditions,
|
|
10214
10249
|
packageConditionsConfig,
|
|
10250
|
+
dev,
|
|
10215
10251
|
}),
|
|
10216
10252
|
]
|
|
10217
10253
|
: []),
|
|
@@ -10229,7 +10265,7 @@ const getCorePlugins = ({
|
|
|
10229
10265
|
|
|
10230
10266
|
jsenvPluginImportMetaCss(),
|
|
10231
10267
|
jsenvPluginCommonJsGlobals(),
|
|
10232
|
-
jsenvPluginImportMetaScenarios(),
|
|
10268
|
+
jsenvPluginImportMetaScenarios({ dev }),
|
|
10233
10269
|
...(scenarioPlaceholders ? [jsenvPluginGlobalScenarios()] : []),
|
|
10234
10270
|
jsenvPluginNodeRuntime({ runtimeCompat }),
|
|
10235
10271
|
|
|
@@ -12410,6 +12446,12 @@ const jsenvPluginMappings = (mappings) => {
|
|
|
12410
12446
|
* Relative URL where this entry point will be written in the build directory
|
|
12411
12447
|
* @param {object} [entryPoint.runtimeCompat]
|
|
12412
12448
|
* Runtime compatibility configuration for this entry point
|
|
12449
|
+
* @param {boolean} [entryPoint.dev=false]
|
|
12450
|
+
* Produce a dev-flavored build: import.meta.dev is replaced by true
|
|
12451
|
+
* (instead of undefined) and dependencies resolve their "development"
|
|
12452
|
+
* package export condition (instead of "production"). Meant for packages
|
|
12453
|
+
* publishing two flavors, the dev one exposed to consumers via the
|
|
12454
|
+
* "development" condition in their package.json "exports"
|
|
12413
12455
|
* @param {string} [entryPoint.assetsDirectory]
|
|
12414
12456
|
* Directory where asset files will be written for this entry point
|
|
12415
12457
|
* @param {string|url} [entryPoint.base]
|
|
@@ -12533,12 +12575,10 @@ entryPoints: {
|
|
|
12533
12575
|
let runtimeType;
|
|
12534
12576
|
{
|
|
12535
12577
|
if (isBareSpecifier(key)) {
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
"import",
|
|
12541
|
-
];
|
|
12578
|
+
// "development" is not resolved here on purpose: it points at a
|
|
12579
|
+
// package's dev-flavored dist, which is not a build input;
|
|
12580
|
+
// "dev:*" points at sources, which are.
|
|
12581
|
+
const packageConditions = ["dev:*", "node", "import"];
|
|
12542
12582
|
try {
|
|
12543
12583
|
const { url, type } = applyNodeEsmResolution({
|
|
12544
12584
|
conditions: packageConditions,
|
|
@@ -13270,6 +13310,7 @@ entryPoints: {
|
|
|
13270
13310
|
const entryPointDefaultParams = {
|
|
13271
13311
|
buildRelativeUrl: undefined,
|
|
13272
13312
|
mode: undefined,
|
|
13313
|
+
dev: false,
|
|
13273
13314
|
runtimeCompat: undefined,
|
|
13274
13315
|
plugins: [],
|
|
13275
13316
|
mappings: undefined,
|
|
@@ -13325,6 +13366,7 @@ const prepareEntryPointBuild = async (
|
|
|
13325
13366
|
let {
|
|
13326
13367
|
buildRelativeUrl,
|
|
13327
13368
|
mode,
|
|
13369
|
+
dev,
|
|
13328
13370
|
runtimeCompat,
|
|
13329
13371
|
plugins,
|
|
13330
13372
|
mappings,
|
|
@@ -13505,6 +13547,7 @@ const prepareEntryPointBuild = async (
|
|
|
13505
13547
|
packageDirectory,
|
|
13506
13548
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
13507
13549
|
runtimeCompat,
|
|
13550
|
+
dev,
|
|
13508
13551
|
referenceAnalysis,
|
|
13509
13552
|
nodeEsmResolution,
|
|
13510
13553
|
packageConditions,
|
|
@@ -2236,7 +2236,10 @@ const decideLinkExpectedType = (linkReference, htmlUrlInfo) => {
|
|
|
2236
2236
|
// - new SharedWorker()
|
|
2237
2237
|
// - navigator.serviceWorker.register()
|
|
2238
2238
|
const isWebWorkerEntryPointReference = (reference) => {
|
|
2239
|
-
if (
|
|
2239
|
+
if (
|
|
2240
|
+
reference.subtype === "new_url_first_arg" ||
|
|
2241
|
+
reference.subtype === "import_meta_resolve"
|
|
2242
|
+
) {
|
|
2240
2243
|
return ["worker", "service_worker", "shared_worker"].includes(
|
|
2241
2244
|
reference.expectedSubtype,
|
|
2242
2245
|
);
|
|
@@ -2686,6 +2689,8 @@ const createNodeEsmResolver = ({
|
|
|
2686
2689
|
packageDirectory,
|
|
2687
2690
|
runtimeCompat,
|
|
2688
2691
|
rootDirectoryUrl,
|
|
2692
|
+
dev,
|
|
2693
|
+
build,
|
|
2689
2694
|
packageConditions = {},
|
|
2690
2695
|
packageConditionsConfig,
|
|
2691
2696
|
preservesSymlink,
|
|
@@ -2703,6 +2708,8 @@ const createNodeEsmResolver = ({
|
|
|
2703
2708
|
packageConditionsConfig,
|
|
2704
2709
|
rootDirectoryUrl,
|
|
2705
2710
|
runtimeCompat,
|
|
2711
|
+
dev,
|
|
2712
|
+
build,
|
|
2706
2713
|
preservesSymlink,
|
|
2707
2714
|
},
|
|
2708
2715
|
);
|
|
@@ -2864,6 +2871,8 @@ const createBuildPackageConditions = (
|
|
|
2864
2871
|
packageConditionsConfig,
|
|
2865
2872
|
rootDirectoryUrl,
|
|
2866
2873
|
runtimeCompat,
|
|
2874
|
+
dev,
|
|
2875
|
+
build,
|
|
2867
2876
|
preservesSymlink,
|
|
2868
2877
|
},
|
|
2869
2878
|
) => {
|
|
@@ -2953,8 +2962,19 @@ const createBuildPackageConditions = (
|
|
|
2953
2962
|
};
|
|
2954
2963
|
|
|
2955
2964
|
const conditionDefaultResolvers = {
|
|
2965
|
+
// "dev:*" conditions target packages under active development: they
|
|
2966
|
+
// apply to files resolved outside node_modules (sources, workspace
|
|
2967
|
+
// symlinks), never to installed packages.
|
|
2956
2968
|
"dev:*": devResolver,
|
|
2957
|
-
"development"
|
|
2969
|
+
// "development"/"production" follow the ecosystem semantics
|
|
2970
|
+
// (Vite, webpack): they describe how the app runs, not where the
|
|
2971
|
+
// package lives, so they apply to every package, node_modules
|
|
2972
|
+
// included. Dev server resolves "development"; build resolves
|
|
2973
|
+
// "production", unless the build is dev-flavored
|
|
2974
|
+
// (build({ entryPoints: { "./file.js": { dev: true } } }))
|
|
2975
|
+
// in which case it resolves "development" too.
|
|
2976
|
+
"development": Boolean(dev),
|
|
2977
|
+
"production": Boolean(build) && !dev,
|
|
2958
2978
|
"node": nodeRuntimeEnabled,
|
|
2959
2979
|
"browser": !nodeRuntimeEnabled,
|
|
2960
2980
|
"import": true,
|
|
@@ -3168,6 +3188,7 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
3168
3188
|
resolutionConfig = {},
|
|
3169
3189
|
packageConditions,
|
|
3170
3190
|
packageConditionsConfig = {},
|
|
3191
|
+
dev,
|
|
3171
3192
|
}) => {
|
|
3172
3193
|
let nodeEsmResolverDefault;
|
|
3173
3194
|
const resolverMap = new Map();
|
|
@@ -3189,6 +3210,8 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
3189
3210
|
packageDirectory,
|
|
3190
3211
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
3191
3212
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
3213
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
3214
|
+
build: kitchenContext.build,
|
|
3192
3215
|
packageConditions,
|
|
3193
3216
|
packageConditionsConfig: {
|
|
3194
3217
|
...kitchenContext.packageConditionsConfig,
|
|
@@ -3206,6 +3229,8 @@ const jsenvPluginNodeEsmResolution = ({
|
|
|
3206
3229
|
packageDirectory,
|
|
3207
3230
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
3208
3231
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
3232
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
3233
|
+
build: kitchenContext.build,
|
|
3209
3234
|
// preservesSymlink: true,
|
|
3210
3235
|
packageConditions,
|
|
3211
3236
|
packageConditionsConfig: {
|
|
@@ -5991,11 +6016,16 @@ const babelPluginMetadataExpressionPaths = (
|
|
|
5991
6016
|
* - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
|
|
5992
6017
|
* - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
|
|
5993
6018
|
*
|
|
6019
|
+
* A build can also be dev-flavored (build({ entryPoints: { "./file.js": { dev: true } } })):
|
|
6020
|
+
* import.meta.dev is then replaced by true, so a package can publish a build
|
|
6021
|
+
* that keeps its dev-only code, exposed to consumers via the "development"
|
|
6022
|
+
* package export condition.
|
|
6023
|
+
*
|
|
5994
6024
|
* TODO: ideally during dev we would keep import.meta.dev and ensure we set it to true rather than replacing it with true?
|
|
5995
6025
|
*/
|
|
5996
6026
|
|
|
5997
6027
|
|
|
5998
|
-
const jsenvPluginImportMetaScenarios = () => {
|
|
6028
|
+
const jsenvPluginImportMetaScenarios = ({ dev } = {}) => {
|
|
5999
6029
|
return {
|
|
6000
6030
|
name: "jsenv:import_meta_scenario",
|
|
6001
6031
|
appliesDuring: "*",
|
|
@@ -6025,17 +6055,19 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
6025
6055
|
}
|
|
6026
6056
|
},
|
|
6027
6057
|
});
|
|
6028
|
-
const
|
|
6058
|
+
const devNodes = importMetaScenarioNodes.dev;
|
|
6059
|
+
const buildNodes = importMetaScenarioNodes.build;
|
|
6029
6060
|
const replacements = [];
|
|
6030
6061
|
const replace = (node, value) => {
|
|
6031
6062
|
replacements.push({ node, value });
|
|
6032
6063
|
};
|
|
6033
6064
|
if (urlInfo.context.build) {
|
|
6034
6065
|
// during build ensure replacement for tree-shaking
|
|
6035
|
-
|
|
6036
|
-
|
|
6066
|
+
// (or for keeping dev code when the build is dev-flavored)
|
|
6067
|
+
devNodes.forEach((node) => {
|
|
6068
|
+
replace(node, dev ? "true" : "undefined");
|
|
6037
6069
|
});
|
|
6038
|
-
|
|
6070
|
+
buildNodes.forEach((node) => {
|
|
6039
6071
|
replace(node, "true");
|
|
6040
6072
|
});
|
|
6041
6073
|
} else {
|
|
@@ -6043,7 +6075,7 @@ const jsenvPluginImportMetaScenarios = () => {
|
|
|
6043
6075
|
// it will be evaluated to undefined.
|
|
6044
6076
|
// Moreover it can be surprising to see some "undefined"
|
|
6045
6077
|
// when source file contains "import.meta.build"
|
|
6046
|
-
|
|
6078
|
+
devNodes.forEach((node) => {
|
|
6047
6079
|
replace(node, "true");
|
|
6048
6080
|
});
|
|
6049
6081
|
}
|
|
@@ -7981,6 +8013,9 @@ const getCorePlugins = ({
|
|
|
7981
8013
|
runtimeCompat,
|
|
7982
8014
|
packageDirectory,
|
|
7983
8015
|
sourceFilesConfig,
|
|
8016
|
+
// during build, a dev-flavored entry point sets dev: true
|
|
8017
|
+
// (during dev the kitchen context already says so, no need to pass it)
|
|
8018
|
+
dev,
|
|
7984
8019
|
|
|
7985
8020
|
referenceAnalysis = {},
|
|
7986
8021
|
nodeEsmResolution = {},
|
|
@@ -8077,6 +8112,7 @@ const getCorePlugins = ({
|
|
|
8077
8112
|
resolutionConfig: nodeEsmResolution,
|
|
8078
8113
|
packageConditions,
|
|
8079
8114
|
packageConditionsConfig,
|
|
8115
|
+
dev,
|
|
8080
8116
|
}),
|
|
8081
8117
|
]
|
|
8082
8118
|
: []),
|
|
@@ -8094,7 +8130,7 @@ const getCorePlugins = ({
|
|
|
8094
8130
|
|
|
8095
8131
|
jsenvPluginImportMetaCss(),
|
|
8096
8132
|
jsenvPluginCommonJsGlobals(),
|
|
8097
|
-
jsenvPluginImportMetaScenarios(),
|
|
8133
|
+
jsenvPluginImportMetaScenarios({ dev }),
|
|
8098
8134
|
...(scenarioPlaceholders ? [jsenvPluginGlobalScenarios()] : []),
|
|
8099
8135
|
jsenvPluginNodeRuntime({ runtimeCompat }),
|
|
8100
8136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/core",
|
|
3
|
-
"version": "41.5.
|
|
3
|
+
"version": "41.5.4",
|
|
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.10.
|
|
77
|
-
"@jsenv/js-module-fallback": "1.6.
|
|
76
|
+
"@jsenv/ast": "6.10.1",
|
|
77
|
+
"@jsenv/js-module-fallback": "1.6.2",
|
|
78
78
|
"@jsenv/plugin-bundling": "2.10.20",
|
|
79
|
-
"@jsenv/plugin-minification": "1.7.
|
|
80
|
-
"@jsenv/plugin-supervisor": "1.8.
|
|
81
|
-
"@jsenv/plugin-transpilation": "1.7.
|
|
79
|
+
"@jsenv/plugin-minification": "1.7.15",
|
|
80
|
+
"@jsenv/plugin-supervisor": "1.8.17",
|
|
81
|
+
"@jsenv/plugin-transpilation": "1.7.2",
|
|
82
82
|
"@jsenv/server": "17.6.3",
|
|
83
83
|
"@jsenv/sourcemap": "1.4.3",
|
|
84
84
|
"react-table": "7.8.0"
|
package/src/build/build.js
CHANGED
|
@@ -117,6 +117,12 @@ import { jsenvPluginMappings } from "./jsenv_plugin_mappings.js";
|
|
|
117
117
|
* Relative URL where this entry point will be written in the build directory
|
|
118
118
|
* @param {object} [entryPoint.runtimeCompat]
|
|
119
119
|
* Runtime compatibility configuration for this entry point
|
|
120
|
+
* @param {boolean} [entryPoint.dev=false]
|
|
121
|
+
* Produce a dev-flavored build: import.meta.dev is replaced by true
|
|
122
|
+
* (instead of undefined) and dependencies resolve their "development"
|
|
123
|
+
* package export condition (instead of "production"). Meant for packages
|
|
124
|
+
* publishing two flavors, the dev one exposed to consumers via the
|
|
125
|
+
* "development" condition in their package.json "exports"
|
|
120
126
|
* @param {string} [entryPoint.assetsDirectory]
|
|
121
127
|
* Directory where asset files will be written for this entry point
|
|
122
128
|
* @param {string|url} [entryPoint.base]
|
|
@@ -240,12 +246,10 @@ entryPoints: {
|
|
|
240
246
|
let runtimeType;
|
|
241
247
|
{
|
|
242
248
|
if (isBareSpecifier(key)) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
"import",
|
|
248
|
-
];
|
|
249
|
+
// "development" is not resolved here on purpose: it points at a
|
|
250
|
+
// package's dev-flavored dist, which is not a build input;
|
|
251
|
+
// "dev:*" points at sources, which are.
|
|
252
|
+
const packageConditions = ["dev:*", "node", "import"];
|
|
249
253
|
try {
|
|
250
254
|
const { url, type } = applyNodeEsmResolution({
|
|
251
255
|
conditions: packageConditions,
|
|
@@ -979,6 +983,7 @@ entryPoints: {
|
|
|
979
983
|
const entryPointDefaultParams = {
|
|
980
984
|
buildRelativeUrl: undefined,
|
|
981
985
|
mode: undefined,
|
|
986
|
+
dev: false,
|
|
982
987
|
runtimeCompat: undefined,
|
|
983
988
|
plugins: [],
|
|
984
989
|
mappings: undefined,
|
|
@@ -1034,6 +1039,7 @@ const prepareEntryPointBuild = async (
|
|
|
1034
1039
|
let {
|
|
1035
1040
|
buildRelativeUrl,
|
|
1036
1041
|
mode,
|
|
1042
|
+
dev,
|
|
1037
1043
|
runtimeCompat,
|
|
1038
1044
|
plugins,
|
|
1039
1045
|
mappings,
|
|
@@ -1214,6 +1220,7 @@ const prepareEntryPointBuild = async (
|
|
|
1214
1220
|
packageDirectory,
|
|
1215
1221
|
rootDirectoryUrl: sourceDirectoryUrl,
|
|
1216
1222
|
runtimeCompat,
|
|
1223
|
+
dev,
|
|
1217
1224
|
referenceAnalysis,
|
|
1218
1225
|
nodeEsmResolution,
|
|
1219
1226
|
packageConditions,
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
// - new SharedWorker()
|
|
4
4
|
// - navigator.serviceWorker.register()
|
|
5
5
|
export const isWebWorkerEntryPointReference = (reference) => {
|
|
6
|
-
if (
|
|
6
|
+
if (
|
|
7
|
+
reference.subtype === "new_url_first_arg" ||
|
|
8
|
+
reference.subtype === "import_meta_resolve"
|
|
9
|
+
) {
|
|
7
10
|
return ["worker", "service_worker", "shared_worker"].includes(
|
|
8
11
|
reference.expectedSubtype,
|
|
9
12
|
);
|
|
@@ -7,13 +7,18 @@
|
|
|
7
7
|
* - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
|
|
8
8
|
* - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
|
|
9
9
|
*
|
|
10
|
+
* A build can also be dev-flavored (build({ entryPoints: { "./file.js": { dev: true } } })):
|
|
11
|
+
* import.meta.dev is then replaced by true, so a package can publish a build
|
|
12
|
+
* that keeps its dev-only code, exposed to consumers via the "development"
|
|
13
|
+
* package export condition.
|
|
14
|
+
*
|
|
10
15
|
* TODO: ideally during dev we would keep import.meta.dev and ensure we set it to true rather than replacing it with true?
|
|
11
16
|
*/
|
|
12
17
|
|
|
13
18
|
import { getImportMetaPropertyName, visitJsAst } from "@jsenv/ast";
|
|
14
19
|
import { createMagicSource } from "@jsenv/sourcemap";
|
|
15
20
|
|
|
16
|
-
export const jsenvPluginImportMetaScenarios = () => {
|
|
21
|
+
export const jsenvPluginImportMetaScenarios = ({ dev } = {}) => {
|
|
17
22
|
return {
|
|
18
23
|
name: "jsenv:import_meta_scenario",
|
|
19
24
|
appliesDuring: "*",
|
|
@@ -43,17 +48,19 @@ export const jsenvPluginImportMetaScenarios = () => {
|
|
|
43
48
|
}
|
|
44
49
|
},
|
|
45
50
|
});
|
|
46
|
-
const
|
|
51
|
+
const devNodes = importMetaScenarioNodes.dev;
|
|
52
|
+
const buildNodes = importMetaScenarioNodes.build;
|
|
47
53
|
const replacements = [];
|
|
48
54
|
const replace = (node, value) => {
|
|
49
55
|
replacements.push({ node, value });
|
|
50
56
|
};
|
|
51
57
|
if (urlInfo.context.build) {
|
|
52
58
|
// during build ensure replacement for tree-shaking
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
// (or for keeping dev code when the build is dev-flavored)
|
|
60
|
+
devNodes.forEach((node) => {
|
|
61
|
+
replace(node, dev ? "true" : "undefined");
|
|
55
62
|
});
|
|
56
|
-
|
|
63
|
+
buildNodes.forEach((node) => {
|
|
57
64
|
replace(node, "true");
|
|
58
65
|
});
|
|
59
66
|
} else {
|
|
@@ -61,7 +68,7 @@ export const jsenvPluginImportMetaScenarios = () => {
|
|
|
61
68
|
// it will be evaluated to undefined.
|
|
62
69
|
// Moreover it can be surprising to see some "undefined"
|
|
63
70
|
// when source file contains "import.meta.build"
|
|
64
|
-
|
|
71
|
+
devNodes.forEach((node) => {
|
|
65
72
|
replace(node, "true");
|
|
66
73
|
});
|
|
67
74
|
}
|
package/src/plugins/plugins.js
CHANGED
|
@@ -38,6 +38,9 @@ export const getCorePlugins = ({
|
|
|
38
38
|
runtimeCompat,
|
|
39
39
|
packageDirectory,
|
|
40
40
|
sourceFilesConfig,
|
|
41
|
+
// during build, a dev-flavored entry point sets dev: true
|
|
42
|
+
// (during dev the kitchen context already says so, no need to pass it)
|
|
43
|
+
dev,
|
|
41
44
|
|
|
42
45
|
referenceAnalysis = {},
|
|
43
46
|
nodeEsmResolution = {},
|
|
@@ -134,6 +137,7 @@ export const getCorePlugins = ({
|
|
|
134
137
|
resolutionConfig: nodeEsmResolution,
|
|
135
138
|
packageConditions,
|
|
136
139
|
packageConditionsConfig,
|
|
140
|
+
dev,
|
|
137
141
|
}),
|
|
138
142
|
]
|
|
139
143
|
: []),
|
|
@@ -151,7 +155,7 @@ export const getCorePlugins = ({
|
|
|
151
155
|
|
|
152
156
|
jsenvPluginImportMetaCss(),
|
|
153
157
|
jsenvPluginCommonJsGlobals(),
|
|
154
|
-
jsenvPluginImportMetaScenarios(),
|
|
158
|
+
jsenvPluginImportMetaScenarios({ dev }),
|
|
155
159
|
...(scenarioPlaceholders ? [jsenvPluginGlobalScenarios()] : []),
|
|
156
160
|
jsenvPluginNodeRuntime({ runtimeCompat }),
|
|
157
161
|
|
|
@@ -5,6 +5,7 @@ export const jsenvPluginNodeEsmResolution = ({
|
|
|
5
5
|
resolutionConfig = {},
|
|
6
6
|
packageConditions,
|
|
7
7
|
packageConditionsConfig = {},
|
|
8
|
+
dev,
|
|
8
9
|
}) => {
|
|
9
10
|
let nodeEsmResolverDefault;
|
|
10
11
|
const resolverMap = new Map();
|
|
@@ -26,6 +27,8 @@ export const jsenvPluginNodeEsmResolution = ({
|
|
|
26
27
|
packageDirectory,
|
|
27
28
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
28
29
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
30
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
31
|
+
build: kitchenContext.build,
|
|
29
32
|
packageConditions,
|
|
30
33
|
packageConditionsConfig: {
|
|
31
34
|
...kitchenContext.packageConditionsConfig,
|
|
@@ -43,6 +46,8 @@ export const jsenvPluginNodeEsmResolution = ({
|
|
|
43
46
|
packageDirectory,
|
|
44
47
|
runtimeCompat: kitchenContext.runtimeCompat,
|
|
45
48
|
rootDirectoryUrl: kitchenContext.rootDirectoryUrl,
|
|
49
|
+
dev: dev === undefined ? kitchenContext.dev : dev,
|
|
50
|
+
build: kitchenContext.build,
|
|
46
51
|
// preservesSymlink: true,
|
|
47
52
|
packageConditions,
|
|
48
53
|
packageConditionsConfig: {
|
|
@@ -20,6 +20,8 @@ export const createNodeEsmResolver = ({
|
|
|
20
20
|
packageDirectory,
|
|
21
21
|
runtimeCompat,
|
|
22
22
|
rootDirectoryUrl,
|
|
23
|
+
dev,
|
|
24
|
+
build,
|
|
23
25
|
packageConditions = {},
|
|
24
26
|
packageConditionsConfig,
|
|
25
27
|
preservesSymlink,
|
|
@@ -37,6 +39,8 @@ export const createNodeEsmResolver = ({
|
|
|
37
39
|
packageConditionsConfig,
|
|
38
40
|
rootDirectoryUrl,
|
|
39
41
|
runtimeCompat,
|
|
42
|
+
dev,
|
|
43
|
+
build,
|
|
40
44
|
preservesSymlink,
|
|
41
45
|
},
|
|
42
46
|
);
|
|
@@ -198,6 +202,8 @@ const createBuildPackageConditions = (
|
|
|
198
202
|
packageConditionsConfig,
|
|
199
203
|
rootDirectoryUrl,
|
|
200
204
|
runtimeCompat,
|
|
205
|
+
dev,
|
|
206
|
+
build,
|
|
201
207
|
preservesSymlink,
|
|
202
208
|
},
|
|
203
209
|
) => {
|
|
@@ -287,8 +293,19 @@ const createBuildPackageConditions = (
|
|
|
287
293
|
};
|
|
288
294
|
|
|
289
295
|
const conditionDefaultResolvers = {
|
|
296
|
+
// "dev:*" conditions target packages under active development: they
|
|
297
|
+
// apply to files resolved outside node_modules (sources, workspace
|
|
298
|
+
// symlinks), never to installed packages.
|
|
290
299
|
"dev:*": devResolver,
|
|
291
|
-
"development"
|
|
300
|
+
// "development"/"production" follow the ecosystem semantics
|
|
301
|
+
// (Vite, webpack): they describe how the app runs, not where the
|
|
302
|
+
// package lives, so they apply to every package, node_modules
|
|
303
|
+
// included. Dev server resolves "development"; build resolves
|
|
304
|
+
// "production", unless the build is dev-flavored
|
|
305
|
+
// (build({ entryPoints: { "./file.js": { dev: true } } }))
|
|
306
|
+
// in which case it resolves "development" too.
|
|
307
|
+
"development": Boolean(dev),
|
|
308
|
+
"production": Boolean(build) && !dev,
|
|
292
309
|
"node": nodeRuntimeEnabled,
|
|
293
310
|
"browser": !nodeRuntimeEnabled,
|
|
294
311
|
"import": true,
|