@jsenv/core 40.3.1 → 40.3.2

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/README.md CHANGED
@@ -2,50 +2,59 @@
2
2
 
3
3
  [![npm package](https://img.shields.io/npm/v/@jsenv/core.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/core)
4
4
 
5
- Jsenv is a suite of tools that can be used in projects involving JavaScript.
5
+ ## Overview
6
6
 
7
- The goal of `@jsenv/core` is to provide the following tools:
7
+ Jsenv is a suite of tools for JavaScript projects that prioritizes standards and simplicity, making it ideal for both beginners and those who need straightforward tools.
8
8
 
9
- 1. **dev server**; A server that serves source files, facilitating development with live reloading.
10
- 2. **build**; Optimizes source files into a specified directory for production.
11
- 3. **build server**; Serves the built files, allowing for testing and verifying the production build.
12
- 4. **test runner**; Runs test files concurrently, ensuring code reliability.
9
+ ## Installation
13
10
 
14
- Jsenv prioritizes standards and simplicity, making it ideal for both beginners and those who need straightforward tools without unnecessary complexities.
11
+ ```console
12
+ npm install --save-dev @jsenv/core
13
+ ```
14
+
15
+ > **Compatibility**: Tested on Mac, Windows, and Linux with Node.js 20. Other environments are not officially tested.
15
16
 
16
- To try jsenv on your machine, use [@jsenv/cli](./packages/related/cli/#jsenvcli).
17
+ ## Documentation
17
18
 
18
- For additional details, consult the [documentation](./docs/users/users.md)
19
+ For comprehensive documentation, see the full [user documentation](https://github.com/jsenv/core/blob/main/docs/users/users.md).
19
20
 
20
- <!-- # The best parts
21
+ ## Basic Usage
21
22
 
22
- - **Robust versioning during build**: Avoids <a href="https://bundlers.tooling.report/hashing/avoid-cascade/" target="_blank">cascading hash changes</a><sup>↗</sup>.
23
- - **Load js module with classic script**: See the [asJsClassic plugin](./docs/users/g_plugins/g_plugins.md#asjsclassic).
24
- - **Large browser support after build**: Ensures compatibility with older versions of Firefox, Chrome, and Safari.
25
- - **Advanced support of top level await**.
26
- - **Advanced support of web workers**.
27
- - **Test files are executed like standard files**.
28
- - **Isolated environment for each test file**: Ensures tests run independently, preventing side effects.
29
- - Single set of files after build: Simplifies support and deployement with a single set of files.
30
- - Execute tests in multiple browsers: Supports Chrome, Safari, and Firefox.
31
- - Extensive browser support during dev: Allows the use of various browsers beyond the latest Chrome, which is useful for reproducing browser-specific bugs. -->
23
+ Start a development server:
24
+
25
+ ```js
26
+ import { startDevServer } from "@jsenv/core";
27
+
28
+ await startDevServer({
29
+ sourceDirectoryUrl: import.meta.resolve("./"),
30
+ });
31
+ ```
32
32
 
33
- <!--
34
- The following commands can be used to skip the prompt
33
+ ## Core Features
35
34
 
36
- | Command |
37
- | ------------------------------------------- |
38
- | `npm create jsenv@latest -- --web` |
39
- | `npm create jsenv@latest -- --web-preact` |
40
- | `npm create jsenv@latest -- --web-react` |
41
- | `npm create jsenv@latest -- --node-package` |
42
- -->
35
+ `@jsenv/core` provides four main tools:
43
36
 
44
- <!-- # Installation
37
+ 1. **Dev Server**: Serves source files with live reloading to facilitate development
38
+ 2. **Build**: Optimizes source files into a specified directory for production
39
+ 3. **Build Server**: Serves the built files, allowing for testing and verifying the production build
40
+ 4. **Test Runner**: Runs test files concurrently to ensure code reliability
41
+
42
+ ## Key Advantages
43
+
44
+ - **Standards-first approach**: Built on web standards rather than custom abstractions
45
+ - **Robust versioning**: Avoids cascading hash changes during builds
46
+ - **Broad browser compatibility**: Works with modern and older browsers
47
+ - **Isolated testing**: Prevents cross-test contamination
48
+ - **Simple API**: Designed for clarity and ease of use
49
+
50
+ ## Quick Start
51
+
52
+ The easiest way to try jsenv is with the CLI:
45
53
 
46
54
  ```console
47
- npm install --save-dev @jsenv/core
55
+ npx @jsenv/cli
48
56
  ```
49
57
 
50
- _@jsenv/core_ is tested on Mac, Windows, Linux with Node.js 20.
51
- Other operating systems and Node.js versions are not tested. -->
58
+ The CLI provides templates for web applications, React projects, and Node.js packages to get you started quickly.
59
+
60
+ Read more in [@jsenv/cli](https://github.com/jsenv/core/tree/main/packages/related/cli#jsenvcli).
@@ -1,7 +1,7 @@
1
1
  import { parseHtml, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, stringifyHtmlAst, applyBabelPlugins, generateUrlForInlineContent, parseJsWithAcorn, visitHtmlNodes, analyzeScriptNode, getHtmlNodeText, getHtmlNodeAttribute, getHtmlNodePosition, getUrlForContentInsideHtml, setHtmlNodeAttributes, setHtmlNodeText, parseCssUrls, getHtmlNodeAttributePosition, parseSrcSet, removeHtmlNodeText, parseJsUrls, getUrlForContentInsideJs, analyzeLinkNode, injectJsenvScript, findHtmlNode, removeHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
2
2
  import { memoryUsage } from "node:process";
3
3
  import { readFileSync, existsSync, readdirSync, lstatSync, realpathSync } from "node:fs";
4
- import { lookupPackageDirectory$1 as lookupPackageDirectory, registerDirectoryLifecycle$1 as registerDirectoryLifecycle, urlToRelativeUrl$1 as urlToRelativeUrl, createDetailedMessage$1 as createDetailedMessage, stringifyUrlSite$1 as stringifyUrlSite, generateContentFrame$1 as generateContentFrame, validateResponseIntegrity$1 as validateResponseIntegrity, urlIsInsideOf$1 as urlIsInsideOf, ensureWindowsDriveLetter$1 as ensureWindowsDriveLetter, setUrlFilename$1 as setUrlFilename, moveUrl$1 as moveUrl, getCallerPosition$1 as getCallerPosition, urlToBasename$1 as urlToBasename, urlToExtension$1 as urlToExtension, asSpecifierWithoutSearch$1 as asSpecifierWithoutSearch, asUrlWithoutSearch$1 as asUrlWithoutSearch, injectQueryParamsIntoSpecifier$1 as injectQueryParamsIntoSpecifier, bufferToEtag$1 as bufferToEtag, isFileSystemPath$1 as isFileSystemPath, urlToPathname$1 as urlToPathname, setUrlBasename$1 as setUrlBasename, urlToFileSystemPath$1 as urlToFileSystemPath, writeFileSync$1 as writeFileSync, createLogger$1 as createLogger, URL_META$1 as URL_META, applyNodeEsmResolution$1 as applyNodeEsmResolution, RUNTIME_COMPAT$1 as RUNTIME_COMPAT, normalizeUrl$1 as normalizeUrl, ANSI$1 as ANSI, CONTENT_TYPE$1 as CONTENT_TYPE, urlToFilename$1 as urlToFilename, DATA_URL$1 as DATA_URL, errorToHTML$1 as errorToHTML, normalizeImportMap$1 as normalizeImportMap, composeTwoImportMaps$1 as composeTwoImportMaps, resolveImport$1 as resolveImport, JS_QUOTES$1 as JS_QUOTES, defaultLookupPackageScope$1 as defaultLookupPackageScope, defaultReadPackageJson$1 as defaultReadPackageJson, readCustomConditionsFromProcessArgs$1 as readCustomConditionsFromProcessArgs, readEntryStatSync$1 as readEntryStatSync, ensurePathnameTrailingSlash$1 as ensurePathnameTrailingSlash, compareFileUrls$1 as compareFileUrls, applyFileSystemMagicResolution$1 as applyFileSystemMagicResolution, getExtensionsToTry$1 as getExtensionsToTry, setUrlExtension$1 as setUrlExtension, updateJsonFileSync$1 as updateJsonFileSync, isSpecifierForNodeBuiltin$1 as isSpecifierForNodeBuiltin, jsenvPluginTranspilation$1 as jsenvPluginTranspilation, renderDetails, humanizeDuration, humanizeFileSize, renderTable, renderBigSection, distributePercentages, humanizeMemory, comparePathnames, UNICODE, escapeRegexpSpecialChars, injectQueryParamIntoSpecifierWithoutEncoding, renderUrlOrRelativeUrlFilename, assertAndNormalizeDirectoryUrl$1 as assertAndNormalizeDirectoryUrl, Abort, raceProcessTeardownEvents, startMonitoringCpuUsage, startMonitoringMemoryUsage, createLookupPackageDirectory, readPackageAtOrNull$1 as readPackageAtOrNull, inferRuntimeCompatFromClosestPackage, browserDefaultRuntimeCompat, nodeDefaultRuntimeCompat, clearDirectorySync, createTaskLog$1 as createTaskLog, jsenvPluginBundling, jsenvPluginMinification, ensureEmptyDirectory, jsenvPluginJsModuleFallback, createDynamicLog } from "../jsenv_core_packages.js";
4
+ import { lookupPackageDirectory$1 as lookupPackageDirectory, registerDirectoryLifecycle$1 as registerDirectoryLifecycle, urlToRelativeUrl$1 as urlToRelativeUrl, createDetailedMessage$1 as createDetailedMessage, stringifyUrlSite$1 as stringifyUrlSite, generateContentFrame$1 as generateContentFrame, validateResponseIntegrity$1 as validateResponseIntegrity, urlIsInsideOf$1 as urlIsInsideOf, ensureWindowsDriveLetter$1 as ensureWindowsDriveLetter, setUrlFilename$1 as setUrlFilename, moveUrl$1 as moveUrl, getCallerPosition$1 as getCallerPosition, urlToBasename$1 as urlToBasename, urlToExtension$1 as urlToExtension, asSpecifierWithoutSearch$1 as asSpecifierWithoutSearch, asUrlWithoutSearch$1 as asUrlWithoutSearch, injectQueryParamsIntoSpecifier$1 as injectQueryParamsIntoSpecifier, bufferToEtag$1 as bufferToEtag, isFileSystemPath$1 as isFileSystemPath, urlToPathname$1 as urlToPathname, setUrlBasename$1 as setUrlBasename, urlToFileSystemPath$1 as urlToFileSystemPath, writeFileSync$1 as writeFileSync, createLogger$1 as createLogger, URL_META$1 as URL_META, applyNodeEsmResolution$1 as applyNodeEsmResolution, RUNTIME_COMPAT$1 as RUNTIME_COMPAT, normalizeUrl$1 as normalizeUrl, ANSI$1 as ANSI, CONTENT_TYPE$1 as CONTENT_TYPE, urlToFilename$1 as urlToFilename, DATA_URL$1 as DATA_URL, errorToHTML$1 as errorToHTML, normalizeImportMap$1 as normalizeImportMap, composeTwoImportMaps$1 as composeTwoImportMaps, resolveImport$1 as resolveImport, JS_QUOTES$1 as JS_QUOTES, defaultLookupPackageScope$1 as defaultLookupPackageScope, defaultReadPackageJson$1 as defaultReadPackageJson, readCustomConditionsFromProcessArgs$1 as readCustomConditionsFromProcessArgs, readEntryStatSync$1 as readEntryStatSync, ensurePathnameTrailingSlash$1 as ensurePathnameTrailingSlash, compareFileUrls$1 as compareFileUrls, applyFileSystemMagicResolution$1 as applyFileSystemMagicResolution, getExtensionsToTry$1 as getExtensionsToTry, setUrlExtension$1 as setUrlExtension, isSpecifierForNodeBuiltin$1 as isSpecifierForNodeBuiltin, updateJsonFileSync$1 as updateJsonFileSync, jsenvPluginTranspilation$1 as jsenvPluginTranspilation, renderDetails, humanizeDuration, humanizeFileSize, renderTable, renderBigSection, distributePercentages, humanizeMemory, comparePathnames, UNICODE, escapeRegexpSpecialChars, injectQueryParamIntoSpecifierWithoutEncoding, renderUrlOrRelativeUrlFilename, assertAndNormalizeDirectoryUrl$1 as assertAndNormalizeDirectoryUrl, Abort, raceProcessTeardownEvents, startMonitoringCpuUsage, startMonitoringMemoryUsage, createLookupPackageDirectory, readPackageAtOrNull$1 as readPackageAtOrNull, inferRuntimeCompatFromClosestPackage, browserDefaultRuntimeCompat, nodeDefaultRuntimeCompat, clearDirectorySync, createTaskLog$1 as createTaskLog, jsenvPluginBundling, jsenvPluginMinification, ensureEmptyDirectory, jsenvPluginJsModuleFallback, createDynamicLog } from "../jsenv_core_packages.js";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
7
7
  import { performance } from "node:perf_hooks";
@@ -8229,10 +8229,6 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8229
8229
  return [];
8230
8230
  }
8231
8231
 
8232
- const sideEffectFileUrlSet = new Set();
8233
- const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
8234
- .href;
8235
-
8236
8232
  const normalizeSideEffectFileUrl = (url) => {
8237
8233
  const urlRelativeToPackage = urlToRelativeUrl(url, packageDirectory.url);
8238
8234
  return urlRelativeToPackage[0] === "."
@@ -8240,6 +8236,20 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8240
8236
  : `./${urlRelativeToPackage}`;
8241
8237
  };
8242
8238
 
8239
+ const updatePackageSideEffects = (sideEffectBuildFileUrls) => {
8240
+ const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
8241
+ .href;
8242
+ const sideEffectRelativeUrlArray = [];
8243
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8244
+ sideEffectRelativeUrlArray.push(
8245
+ normalizeSideEffectFileUrl(sideEffectBuildUrl),
8246
+ );
8247
+ }
8248
+ updateJsonFileSync(packageJsonFileUrl, {
8249
+ sideEffects: sideEffectRelativeUrlArray,
8250
+ });
8251
+ };
8252
+
8243
8253
  const sideEffectBuildFileUrls = [];
8244
8254
 
8245
8255
  const packageSideEffectsCacheMap = new Map();
@@ -8375,39 +8385,43 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8375
8385
  }
8376
8386
  }
8377
8387
  },
8378
- refineBuild: () => {
8388
+ refineBuild: (kitchen) => {
8379
8389
  if (sideEffectBuildFileUrls.length === 0) {
8380
8390
  return;
8381
8391
  }
8382
- let sideEffectsToAdd = [];
8383
8392
  if (sideEffects === false) {
8384
- sideEffectsToAdd = sideEffectBuildFileUrls;
8385
- } else if (Array.isArray(sideEffects)) {
8393
+ updatePackageSideEffects(sideEffectBuildFileUrls);
8394
+ return;
8395
+ }
8396
+ const { buildDirectoryUrl } = kitchen.context;
8397
+ const sideEffectFileUrlSet = new Set();
8398
+ if (Array.isArray(sideEffects)) {
8399
+ let packageNeedsUpdate = false;
8386
8400
  for (const sideEffectFileRelativeUrl of sideEffects) {
8387
8401
  const sideEffectFileUrl = new URL(
8388
8402
  sideEffectFileRelativeUrl,
8389
8403
  packageDirectory.url,
8390
8404
  ).href;
8391
- sideEffectFileUrlSet.add(sideEffectFileUrl);
8405
+ if (
8406
+ urlIsInsideOf(sideEffectFileUrl, buildDirectoryUrl) &&
8407
+ !sideEffectBuildFileUrls.includes(sideEffectFileUrl)
8408
+ ) {
8409
+ packageNeedsUpdate = true;
8410
+ } else {
8411
+ sideEffectFileUrlSet.add(sideEffectFileUrl);
8412
+ }
8392
8413
  }
8393
- for (const url of sideEffectBuildFileUrls) {
8394
- if (sideEffectFileUrlSet.has(url)) {
8414
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8415
+ if (sideEffectFileUrlSet.has(sideEffectBuildUrl)) {
8395
8416
  continue;
8396
8417
  }
8397
- sideEffectsToAdd.push(url);
8418
+ packageNeedsUpdate = true;
8419
+ sideEffectFileUrlSet.add(sideEffectBuildUrl);
8420
+ }
8421
+ if (packageNeedsUpdate) {
8422
+ updatePackageSideEffects(sideEffectFileUrlSet);
8398
8423
  }
8399
8424
  }
8400
- if (sideEffectsToAdd.length === 0) {
8401
- return;
8402
- }
8403
-
8404
- const finalSideEffects = Array.isArray(sideEffects) ? sideEffects : [];
8405
- for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8406
- finalSideEffects.push(normalizeSideEffectFileUrl(sideEffectBuildUrl));
8407
- }
8408
- updateJsonFileSync(packageJsonFileUrl, {
8409
- sideEffects: finalSideEffects,
8410
- });
8411
8425
  },
8412
8426
  };
8413
8427
  };
@@ -11811,7 +11825,7 @@ const prepareEntryPointBuild = async (
11811
11825
  }
11812
11826
  if (refineBuildCallbackSet.size) {
11813
11827
  for (const refineBuildCallback of refineBuildCallbackSet) {
11814
- refineBuildCallback(finalKitchen.graph);
11828
+ refineBuildCallback(finalKitchen);
11815
11829
  }
11816
11830
  }
11817
11831
  }
@@ -1,6 +1,6 @@
1
1
  import { WebSocketResponse, pickContentType, ServerEvents, jsenvServiceCORS, jsenvAccessControlAllowedHeaders, composeTwoResponses, serveDirectory, jsenvServiceErrorHandler, startServer } from "@jsenv/server";
2
2
  import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js";
3
- import { lookupPackageDirectory, registerDirectoryLifecycle, urlToRelativeUrl, moveUrl, urlIsInsideOf, ensureWindowsDriveLetter, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, setUrlFilename, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, RUNTIME_COMPAT, normalizeUrl, ANSI, CONTENT_TYPE, errorToHTML, DATA_URL, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, defaultLookupPackageScope, defaultReadPackageJson, readCustomConditionsFromProcessArgs, readEntryStatSync, urlToFilename, ensurePathnameTrailingSlash, compareFileUrls, applyFileSystemMagicResolution, getExtensionsToTry, setUrlExtension, updateJsonFileSync, isSpecifierForNodeBuiltin, jsenvPluginTranspilation, memoizeByFirstArgument, assertAndNormalizeDirectoryUrl, createTaskLog, readPackageAtOrNull } from "../jsenv_core_packages.js";
3
+ import { lookupPackageDirectory, registerDirectoryLifecycle, urlToRelativeUrl, moveUrl, urlIsInsideOf, ensureWindowsDriveLetter, createDetailedMessage, stringifyUrlSite, generateContentFrame, validateResponseIntegrity, setUrlFilename, getCallerPosition, urlToBasename, urlToExtension, asSpecifierWithoutSearch, asUrlWithoutSearch, injectQueryParamsIntoSpecifier, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, urlToFileSystemPath, writeFileSync, createLogger, URL_META, applyNodeEsmResolution, RUNTIME_COMPAT, normalizeUrl, ANSI, CONTENT_TYPE, errorToHTML, DATA_URL, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, defaultLookupPackageScope, defaultReadPackageJson, readCustomConditionsFromProcessArgs, readEntryStatSync, urlToFilename, ensurePathnameTrailingSlash, compareFileUrls, applyFileSystemMagicResolution, getExtensionsToTry, setUrlExtension, isSpecifierForNodeBuiltin, updateJsonFileSync, jsenvPluginTranspilation, memoizeByFirstArgument, assertAndNormalizeDirectoryUrl, createTaskLog, readPackageAtOrNull } from "../jsenv_core_packages.js";
4
4
  import { readFileSync, existsSync, readdirSync, lstatSync, realpathSync } from "node:fs";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import { generateSourcemapFileUrl, createMagicSource, composeTwoSourcemaps, generateSourcemapDataUrl, SOURCEMAP } from "@jsenv/sourcemap";
@@ -8270,10 +8270,6 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8270
8270
  return [];
8271
8271
  }
8272
8272
 
8273
- const sideEffectFileUrlSet = new Set();
8274
- const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
8275
- .href;
8276
-
8277
8273
  const normalizeSideEffectFileUrl = (url) => {
8278
8274
  const urlRelativeToPackage = urlToRelativeUrl(url, packageDirectory.url);
8279
8275
  return urlRelativeToPackage[0] === "."
@@ -8281,6 +8277,20 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8281
8277
  : `./${urlRelativeToPackage}`;
8282
8278
  };
8283
8279
 
8280
+ const updatePackageSideEffects = (sideEffectBuildFileUrls) => {
8281
+ const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
8282
+ .href;
8283
+ const sideEffectRelativeUrlArray = [];
8284
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8285
+ sideEffectRelativeUrlArray.push(
8286
+ normalizeSideEffectFileUrl(sideEffectBuildUrl),
8287
+ );
8288
+ }
8289
+ updateJsonFileSync(packageJsonFileUrl, {
8290
+ sideEffects: sideEffectRelativeUrlArray,
8291
+ });
8292
+ };
8293
+
8284
8294
  const sideEffectBuildFileUrls = [];
8285
8295
 
8286
8296
  const packageSideEffectsCacheMap = new Map();
@@ -8416,39 +8426,43 @@ const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
8416
8426
  }
8417
8427
  }
8418
8428
  },
8419
- refineBuild: () => {
8429
+ refineBuild: (kitchen) => {
8420
8430
  if (sideEffectBuildFileUrls.length === 0) {
8421
8431
  return;
8422
8432
  }
8423
- let sideEffectsToAdd = [];
8424
8433
  if (sideEffects === false) {
8425
- sideEffectsToAdd = sideEffectBuildFileUrls;
8426
- } else if (Array.isArray(sideEffects)) {
8434
+ updatePackageSideEffects(sideEffectBuildFileUrls);
8435
+ return;
8436
+ }
8437
+ const { buildDirectoryUrl } = kitchen.context;
8438
+ const sideEffectFileUrlSet = new Set();
8439
+ if (Array.isArray(sideEffects)) {
8440
+ let packageNeedsUpdate = false;
8427
8441
  for (const sideEffectFileRelativeUrl of sideEffects) {
8428
8442
  const sideEffectFileUrl = new URL(
8429
8443
  sideEffectFileRelativeUrl,
8430
8444
  packageDirectory.url,
8431
8445
  ).href;
8432
- sideEffectFileUrlSet.add(sideEffectFileUrl);
8446
+ if (
8447
+ urlIsInsideOf(sideEffectFileUrl, buildDirectoryUrl) &&
8448
+ !sideEffectBuildFileUrls.includes(sideEffectFileUrl)
8449
+ ) {
8450
+ packageNeedsUpdate = true;
8451
+ } else {
8452
+ sideEffectFileUrlSet.add(sideEffectFileUrl);
8453
+ }
8433
8454
  }
8434
- for (const url of sideEffectBuildFileUrls) {
8435
- if (sideEffectFileUrlSet.has(url)) {
8455
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8456
+ if (sideEffectFileUrlSet.has(sideEffectBuildUrl)) {
8436
8457
  continue;
8437
8458
  }
8438
- sideEffectsToAdd.push(url);
8459
+ packageNeedsUpdate = true;
8460
+ sideEffectFileUrlSet.add(sideEffectBuildUrl);
8461
+ }
8462
+ if (packageNeedsUpdate) {
8463
+ updatePackageSideEffects(sideEffectFileUrlSet);
8439
8464
  }
8440
8465
  }
8441
- if (sideEffectsToAdd.length === 0) {
8442
- return;
8443
- }
8444
-
8445
- const finalSideEffects = Array.isArray(sideEffects) ? sideEffects : [];
8446
- for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
8447
- finalSideEffects.push(normalizeSideEffectFileUrl(sideEffectBuildUrl));
8448
- }
8449
- updateJsonFileSync(packageJsonFileUrl, {
8450
- sideEffects: finalSideEffects,
8451
- });
8452
8466
  },
8453
8467
  };
8454
8468
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "40.3.1",
3
+ "version": "40.3.2",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -50,10 +50,8 @@
50
50
  "sideEffects": [
51
51
  "./src/kitchen/client/inline_content.js",
52
52
  "./dist/client/inline_content/inline_content.js",
53
- "./dist/client/directory_listing/jsenv_core_node_modules.js",
54
53
  "./dist/jsenv_core_node_modules.js",
55
- "./dist/client/new_stylesheet/new_stylesheet.js",
56
- "./dist/client/inline_content/inline_content.js"
54
+ "./dist/client/new_stylesheet/new_stylesheet.js"
57
55
  ],
58
56
  "scripts": {
59
57
  "eslint": "npx eslint .",
@@ -130,4 +128,4 @@
130
128
  "prettier-plugin-organize-imports": "4.1.0",
131
129
  "strip-ansi": "7.1.0"
132
130
  }
133
- }
131
+ }
@@ -1339,7 +1339,7 @@ const prepareEntryPointBuild = async (
1339
1339
  }
1340
1340
  if (refineBuildCallbackSet.size) {
1341
1341
  for (const refineBuildCallback of refineBuildCallbackSet) {
1342
- refineBuildCallback(finalKitchen.graph);
1342
+ refineBuildCallback(finalKitchen);
1343
1343
  }
1344
1344
  }
1345
1345
  }
@@ -14,7 +14,7 @@
14
14
  import { updateJsonFileSync } from "@jsenv/filesystem";
15
15
  import { isSpecifierForNodeBuiltin } from "@jsenv/node-esm-resolution/src/node_builtin_specifiers.js";
16
16
  import { URL_META } from "@jsenv/url-meta";
17
- import { urlToRelativeUrl } from "@jsenv/urls";
17
+ import { urlIsInsideOf, urlToRelativeUrl } from "@jsenv/urls";
18
18
 
19
19
  export const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
20
20
  if (!packageDirectory.url) {
@@ -29,10 +29,6 @@ export const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
29
29
  return [];
30
30
  }
31
31
 
32
- const sideEffectFileUrlSet = new Set();
33
- const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
34
- .href;
35
-
36
32
  const normalizeSideEffectFileUrl = (url) => {
37
33
  const urlRelativeToPackage = urlToRelativeUrl(url, packageDirectory.url);
38
34
  return urlRelativeToPackage[0] === "."
@@ -40,6 +36,20 @@ export const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
40
36
  : `./${urlRelativeToPackage}`;
41
37
  };
42
38
 
39
+ const updatePackageSideEffects = (sideEffectBuildFileUrls) => {
40
+ const packageJsonFileUrl = new URL("./package.json", packageDirectory.url)
41
+ .href;
42
+ const sideEffectRelativeUrlArray = [];
43
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
44
+ sideEffectRelativeUrlArray.push(
45
+ normalizeSideEffectFileUrl(sideEffectBuildUrl),
46
+ );
47
+ }
48
+ updateJsonFileSync(packageJsonFileUrl, {
49
+ sideEffects: sideEffectRelativeUrlArray,
50
+ });
51
+ };
52
+
43
53
  const sideEffectBuildFileUrls = [];
44
54
 
45
55
  const packageSideEffectsCacheMap = new Map();
@@ -175,39 +185,43 @@ export const jsenvPluginPackageSideEffects = ({ packageDirectory }) => {
175
185
  }
176
186
  }
177
187
  },
178
- refineBuild: () => {
188
+ refineBuild: (kitchen) => {
179
189
  if (sideEffectBuildFileUrls.length === 0) {
180
190
  return;
181
191
  }
182
- let sideEffectsToAdd = [];
183
192
  if (sideEffects === false) {
184
- sideEffectsToAdd = sideEffectBuildFileUrls;
185
- } else if (Array.isArray(sideEffects)) {
193
+ updatePackageSideEffects(sideEffectBuildFileUrls);
194
+ return;
195
+ }
196
+ const { buildDirectoryUrl } = kitchen.context;
197
+ const sideEffectFileUrlSet = new Set();
198
+ if (Array.isArray(sideEffects)) {
199
+ let packageNeedsUpdate = false;
186
200
  for (const sideEffectFileRelativeUrl of sideEffects) {
187
201
  const sideEffectFileUrl = new URL(
188
202
  sideEffectFileRelativeUrl,
189
203
  packageDirectory.url,
190
204
  ).href;
191
- sideEffectFileUrlSet.add(sideEffectFileUrl);
205
+ if (
206
+ urlIsInsideOf(sideEffectFileUrl, buildDirectoryUrl) &&
207
+ !sideEffectBuildFileUrls.includes(sideEffectFileUrl)
208
+ ) {
209
+ packageNeedsUpdate = true;
210
+ } else {
211
+ sideEffectFileUrlSet.add(sideEffectFileUrl);
212
+ }
192
213
  }
193
- for (const url of sideEffectBuildFileUrls) {
194
- if (sideEffectFileUrlSet.has(url)) {
214
+ for (const sideEffectBuildUrl of sideEffectBuildFileUrls) {
215
+ if (sideEffectFileUrlSet.has(sideEffectBuildUrl)) {
195
216
  continue;
196
217
  }
197
- sideEffectsToAdd.push(url);
218
+ packageNeedsUpdate = true;
219
+ sideEffectFileUrlSet.add(sideEffectBuildUrl);
220
+ }
221
+ if (packageNeedsUpdate) {
222
+ updatePackageSideEffects(sideEffectFileUrlSet);
198
223
  }
199
224
  }
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
225
  },
212
226
  };
213
227
  };