@arcgis/components-build-utils 5.1.0-next.108 → 5.1.0-next.109

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/index.cjs CHANGED
@@ -250,7 +250,8 @@ function detectPackageManager(cwd = process.cwd()) {
250
250
  function vitePresetPlugin({
251
251
  dtsOptions = {},
252
252
  externalize,
253
- bundleIn
253
+ bundleIn,
254
+ isApplication
254
255
  } = {
255
256
  externalize: [],
256
257
  dtsOptions: {}
@@ -281,7 +282,8 @@ function vitePresetPlugin({
281
282
  },
282
283
  externalizeDependencies({
283
284
  externalize,
284
- bundleIn
285
+ bundleIn,
286
+ isApplication
285
287
  }),
286
288
  // This dependency pulls in many others. Since components-build-utils has a
287
289
  // single entry point, we load a large module tree needlessly. To avoid,
@@ -340,24 +342,33 @@ function shouldSkip(id) {
340
342
  return id.includes("__test") || id.includes(".e2e.") || id.includes(".spec.") || id.includes(".test.") || id.includes(".stories.");
341
343
  }
342
344
  function externalizeDependencies(options) {
343
- const packageJson = retrievePackageJson();
345
+ return externalizeDependenciesImplementation(options, retrievePackageJson());
346
+ }
347
+ function externalizeDependenciesImplementation(options, packageJson) {
344
348
  const externalDependencies = Object.keys({
345
349
  ...packageJson.dependencies,
346
350
  ...packageJson.peerDependencies,
347
351
  ...packageJson.optionalDependencies
348
352
  });
353
+ const isStrictBundling = toPosixPathSeparators(void 0).includes(
354
+ "support-packages/components-build-utils"
355
+ );
349
356
  const bundleIn = options.bundleIn?.map(stringToStartsWithGlob);
357
+ const explicitExternalize = options.externalize?.map(stringToStartsWithGlob) ?? [];
350
358
  const externalize = [
351
- ...options.externalize?.map(stringToStartsWithGlob) ?? [],
359
+ ...explicitExternalize,
360
+ // BUG: we shouldn't silently externalize node in browser packages.
361
+ // Consider erroring instead
352
362
  /^node:/u,
353
363
  new RegExp(
354
- `^(?:${externalDependencies.join("|")}${externalDependencies.length === 0 ? "" : "|"}${node_module.builtinModules.join("|")})(?:/.+)?$`,
364
+ `^(?:${externalDependencies.join("|")}${externalDependencies.length === 0 ? "" : "|"}${node_module.builtinModules.join("|")})(?:/|$)`,
355
365
  "u"
356
366
  )
357
367
  ];
358
368
  const plugin = {
359
- name: "@arcgis/components-build-utils:externalize-dependencies",
369
+ name: pluginName,
360
370
  apply: "build",
371
+ // Externalize before Vite's default resolution runs
361
372
  enforce: "pre",
362
373
  // Rolldown also has "external" option, which can be provided regexes.
363
374
  // Theoretically that would be more efficient due to less communication
@@ -367,21 +378,62 @@ function externalizeDependencies(options) {
367
378
  resolveId: {
368
379
  filter: {
369
380
  id: {
370
- include: externalize,
381
+ include: [
382
+ // In most cases, we want all dependencies in library packages to be
383
+ // externalized. Thus, this regex matches all non-relative imports.
384
+ nonRelativeSpecifierPattern,
385
+ // Also include explicitExternalize because those may target relative
386
+ // paths (e.g. ./draconvert.js in mock-services).
387
+ ...explicitExternalize
388
+ ],
371
389
  exclude: bundleIn
372
390
  }
373
391
  },
374
- handler() {
375
- return false;
392
+ handler(id, importer, resolveOptions) {
393
+ if (matchesAny(id, externalize)) {
394
+ return false;
395
+ }
396
+ if (
397
+ // Entrypoints look like src/components/button/button.tsx, so are
398
+ // matched by the nonRelativeSpecifierPattern
399
+ resolveOptions.isEntry || // Virtual specifiers are handled by plugins
400
+ id.startsWith("\0") || // data: node: virtual:
401
+ id.includes(":") || // ?raw ?url ?worker - resolved by other plugins
402
+ id.includes("?") || // Applications can bundle in anything
403
+ options.isApplication === true
404
+ ) {
405
+ return;
406
+ }
407
+ const error = `[${pluginName}] Vite tried to bundle in "${id}" (imported by ${importer}).
408
+ This is likely undesirable. To externalize it, declare this dependency as a "dependency", "peerDependency" or "optionalDependency" in package.json.
409
+ If this is intentional, add it to the build.dependencies.bundleIn option in useLumina() or bundleIn option in the vitePresetPlugin().
410
+ If this is an application rather than a library, pass isApplication:true in vitePresetPlugin().`;
411
+ if (isStrictBundling) {
412
+ throw Error(error);
413
+ } else {
414
+ console.error(node_util.styleText("red", `${error}
415
+ This will be an error in future version.`));
416
+ return;
417
+ }
376
418
  }
377
419
  }
378
420
  };
379
421
  return plugin;
380
422
  }
423
+ const pluginName = "@arcgis/components-build-utils:externalize-dependencies";
381
424
  const stringToStartsWithGlob = (option) => typeof option === "string" ? new RegExp(
382
425
  `^${option.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")}${option.endsWith("/") ? "(?:.+)?" : "(?:/.+)?"}$`,
383
426
  "u"
384
427
  ) : option;
428
+ const nonRelativeSpecifierPattern = /^[^\.\/]/u;
429
+ function matchesAny(id, patterns) {
430
+ for (let index = 0; index < patterns.length; ++index) {
431
+ if (patterns[index].test(id)) {
432
+ return true;
433
+ }
434
+ }
435
+ return false;
436
+ }
385
437
  exports.asyncFindPath = asyncFindPath;
386
438
  exports.asyncRetrievePackageJson = asyncRetrievePackageJson;
387
439
  exports.asyncSh = asyncSh;
package/dist/index.js CHANGED
@@ -226,7 +226,8 @@ function detectPackageManager(cwd = process.cwd()) {
226
226
  function vitePresetPlugin({
227
227
  dtsOptions = {},
228
228
  externalize,
229
- bundleIn
229
+ bundleIn,
230
+ isApplication
230
231
  } = {
231
232
  externalize: [],
232
233
  dtsOptions: {}
@@ -257,7 +258,8 @@ function vitePresetPlugin({
257
258
  },
258
259
  externalizeDependencies({
259
260
  externalize,
260
- bundleIn
261
+ bundleIn,
262
+ isApplication
261
263
  }),
262
264
  // This dependency pulls in many others. Since components-build-utils has a
263
265
  // single entry point, we load a large module tree needlessly. To avoid,
@@ -316,24 +318,33 @@ function shouldSkip(id) {
316
318
  return id.includes("__test") || id.includes(".e2e.") || id.includes(".spec.") || id.includes(".test.") || id.includes(".stories.");
317
319
  }
318
320
  function externalizeDependencies(options) {
319
- const packageJson = retrievePackageJson();
321
+ return externalizeDependenciesImplementation(options, retrievePackageJson());
322
+ }
323
+ function externalizeDependenciesImplementation(options, packageJson) {
320
324
  const externalDependencies = Object.keys({
321
325
  ...packageJson.dependencies,
322
326
  ...packageJson.peerDependencies,
323
327
  ...packageJson.optionalDependencies
324
328
  });
329
+ const isStrictBundling = toPosixPathSeparators(import.meta.dirname).includes(
330
+ "support-packages/components-build-utils"
331
+ );
325
332
  const bundleIn = options.bundleIn?.map(stringToStartsWithGlob);
333
+ const explicitExternalize = options.externalize?.map(stringToStartsWithGlob) ?? [];
326
334
  const externalize = [
327
- ...options.externalize?.map(stringToStartsWithGlob) ?? [],
335
+ ...explicitExternalize,
336
+ // BUG: we shouldn't silently externalize node in browser packages.
337
+ // Consider erroring instead
328
338
  /^node:/u,
329
339
  new RegExp(
330
- `^(?:${externalDependencies.join("|")}${externalDependencies.length === 0 ? "" : "|"}${builtinModules.join("|")})(?:/.+)?$`,
340
+ `^(?:${externalDependencies.join("|")}${externalDependencies.length === 0 ? "" : "|"}${builtinModules.join("|")})(?:/|$)`,
331
341
  "u"
332
342
  )
333
343
  ];
334
344
  const plugin = {
335
- name: "@arcgis/components-build-utils:externalize-dependencies",
345
+ name: pluginName,
336
346
  apply: "build",
347
+ // Externalize before Vite's default resolution runs
337
348
  enforce: "pre",
338
349
  // Rolldown also has "external" option, which can be provided regexes.
339
350
  // Theoretically that would be more efficient due to less communication
@@ -343,21 +354,62 @@ function externalizeDependencies(options) {
343
354
  resolveId: {
344
355
  filter: {
345
356
  id: {
346
- include: externalize,
357
+ include: [
358
+ // In most cases, we want all dependencies in library packages to be
359
+ // externalized. Thus, this regex matches all non-relative imports.
360
+ nonRelativeSpecifierPattern,
361
+ // Also include explicitExternalize because those may target relative
362
+ // paths (e.g. ./draconvert.js in mock-services).
363
+ ...explicitExternalize
364
+ ],
347
365
  exclude: bundleIn
348
366
  }
349
367
  },
350
- handler() {
351
- return false;
368
+ handler(id, importer, resolveOptions) {
369
+ if (matchesAny(id, externalize)) {
370
+ return false;
371
+ }
372
+ if (
373
+ // Entrypoints look like src/components/button/button.tsx, so are
374
+ // matched by the nonRelativeSpecifierPattern
375
+ resolveOptions.isEntry || // Virtual specifiers are handled by plugins
376
+ id.startsWith("\0") || // data: node: virtual:
377
+ id.includes(":") || // ?raw ?url ?worker - resolved by other plugins
378
+ id.includes("?") || // Applications can bundle in anything
379
+ options.isApplication === true
380
+ ) {
381
+ return;
382
+ }
383
+ const error = `[${pluginName}] Vite tried to bundle in "${id}" (imported by ${importer}).
384
+ This is likely undesirable. To externalize it, declare this dependency as a "dependency", "peerDependency" or "optionalDependency" in package.json.
385
+ If this is intentional, add it to the build.dependencies.bundleIn option in useLumina() or bundleIn option in the vitePresetPlugin().
386
+ If this is an application rather than a library, pass isApplication:true in vitePresetPlugin().`;
387
+ if (isStrictBundling) {
388
+ throw Error(error);
389
+ } else {
390
+ console.error(styleText("red", `${error}
391
+ This will be an error in future version.`));
392
+ return;
393
+ }
352
394
  }
353
395
  }
354
396
  };
355
397
  return plugin;
356
398
  }
399
+ const pluginName = "@arcgis/components-build-utils:externalize-dependencies";
357
400
  const stringToStartsWithGlob = (option) => typeof option === "string" ? new RegExp(
358
401
  `^${option.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")}${option.endsWith("/") ? "(?:.+)?" : "(?:/.+)?"}$`,
359
402
  "u"
360
403
  ) : option;
404
+ const nonRelativeSpecifierPattern = /^[^\.\/]/u;
405
+ function matchesAny(id, patterns) {
406
+ for (let index = 0; index < patterns.length; ++index) {
407
+ if (patterns[index].test(id)) {
408
+ return true;
409
+ }
410
+ }
411
+ return false;
412
+ }
361
413
  export {
362
414
  asyncFindPath,
363
415
  asyncRetrievePackageJson,
@@ -13,6 +13,8 @@ export type PackageJson = {
13
13
  "module"?: string;
14
14
  "types"?: string;
15
15
  "files"?: string[];
16
+ "bin"?: Record<string, string> | string;
17
+ "man"?: string[] | string;
16
18
  "dependencies"?: Record<string, string>;
17
19
  "devDependencies"?: Record<string, string>;
18
20
  "peerDependencies"?: Record<string, string>;
@@ -13,6 +13,8 @@ export type PackageJson = {
13
13
  "module"?: string;
14
14
  "types"?: string;
15
15
  "files"?: string[];
16
+ "bin"?: Record<string, string> | string;
17
+ "man"?: string[] | string;
16
18
  "dependencies"?: Record<string, string>;
17
19
  "devDependencies"?: Record<string, string>;
18
20
  "peerDependencies"?: Record<string, string>;
package/dist/vite.d.cts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { Plugin } from 'vite';
2
2
  import { default as dts } from 'vite-plugin-dts';
3
+ import { PackageJson } from './packageJson.ts';
3
4
  /**
4
5
  * Vite preset for all our support packages:
5
6
  * - externalizes all non-dev-dependencies
6
7
  * - generates type declarations (using `vite-plugin-dts`)
7
8
  */
8
- export declare function vitePresetPlugin({ dtsOptions, externalize, bundleIn, }?: DependencyManagementOptions & {
9
+ export declare function vitePresetPlugin({ dtsOptions, externalize, bundleIn, isApplication, }?: DependencyManagementOptions & {
9
10
  /** Additional options for `vite-plugin-dts` */
10
11
  dtsOptions?: Parameters<typeof dts>[0] | false;
11
12
  }): [Plugin, Plugin, Promise<Plugin> | undefined];
@@ -40,6 +41,14 @@ export type DependencyManagementOptions = {
40
41
  * technical reasons.
41
42
  */
42
43
  readonly externalize?: (RegExp | string)[];
44
+ /**
45
+ * By default, this plugin errors if any devDependency is used in runtime code
46
+ * to avoid bundling in dependencies in a library. In application packages,
47
+ * bundling in everything is desirable, so enable this option.
48
+ *
49
+ * @default false
50
+ */
51
+ readonly isApplication?: boolean;
43
52
  };
44
53
  /**
45
54
  * By default, Rollup will bundle-in all dependencies.
@@ -69,6 +78,24 @@ export type DependencyManagementOptions = {
69
78
  * be externalized (because all peerDependencies are externalized).
70
79
  */
71
80
  export declare function externalizeDependencies(options: DependencyManagementOptions): Plugin;
81
+ interface PluginShape extends Plugin {
82
+ resolveId: {
83
+ filter: {
84
+ id: {
85
+ include: RegExp[];
86
+ exclude: RegExp[] | undefined;
87
+ };
88
+ };
89
+ handler: (id: string, importer: string | undefined, options: {
90
+ isEntry: boolean;
91
+ }) => false | undefined;
92
+ };
93
+ }
94
+ declare function externalizeDependenciesImplementation(options: DependencyManagementOptions, packageJson: PackageJson): PluginShape;
95
+ declare function matchesAny(id: string, patterns: readonly RegExp[]): boolean;
72
96
  export declare const exportsForTests: {
73
97
  stringToStartsWithGlob: (option: RegExp | string) => RegExp;
98
+ externalizeDependenciesImplementation: typeof externalizeDependenciesImplementation;
99
+ matchesAny: typeof matchesAny;
74
100
  };
101
+ export {};
package/dist/vite.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import { Plugin } from 'vite';
2
2
  import { default as dts } from 'vite-plugin-dts';
3
+ import { PackageJson } from './packageJson.ts';
3
4
  /**
4
5
  * Vite preset for all our support packages:
5
6
  * - externalizes all non-dev-dependencies
6
7
  * - generates type declarations (using `vite-plugin-dts`)
7
8
  */
8
- export declare function vitePresetPlugin({ dtsOptions, externalize, bundleIn, }?: DependencyManagementOptions & {
9
+ export declare function vitePresetPlugin({ dtsOptions, externalize, bundleIn, isApplication, }?: DependencyManagementOptions & {
9
10
  /** Additional options for `vite-plugin-dts` */
10
11
  dtsOptions?: Parameters<typeof dts>[0] | false;
11
12
  }): [Plugin, Plugin, Promise<Plugin> | undefined];
@@ -40,6 +41,14 @@ export type DependencyManagementOptions = {
40
41
  * technical reasons.
41
42
  */
42
43
  readonly externalize?: (RegExp | string)[];
44
+ /**
45
+ * By default, this plugin errors if any devDependency is used in runtime code
46
+ * to avoid bundling in dependencies in a library. In application packages,
47
+ * bundling in everything is desirable, so enable this option.
48
+ *
49
+ * @default false
50
+ */
51
+ readonly isApplication?: boolean;
43
52
  };
44
53
  /**
45
54
  * By default, Rollup will bundle-in all dependencies.
@@ -69,6 +78,24 @@ export type DependencyManagementOptions = {
69
78
  * be externalized (because all peerDependencies are externalized).
70
79
  */
71
80
  export declare function externalizeDependencies(options: DependencyManagementOptions): Plugin;
81
+ interface PluginShape extends Plugin {
82
+ resolveId: {
83
+ filter: {
84
+ id: {
85
+ include: RegExp[];
86
+ exclude: RegExp[] | undefined;
87
+ };
88
+ };
89
+ handler: (id: string, importer: string | undefined, options: {
90
+ isEntry: boolean;
91
+ }) => false | undefined;
92
+ };
93
+ }
94
+ declare function externalizeDependenciesImplementation(options: DependencyManagementOptions, packageJson: PackageJson): PluginShape;
95
+ declare function matchesAny(id: string, patterns: readonly RegExp[]): boolean;
72
96
  export declare const exportsForTests: {
73
97
  stringToStartsWithGlob: (option: RegExp | string) => RegExp;
98
+ externalizeDependenciesImplementation: typeof externalizeDependenciesImplementation;
99
+ matchesAny: typeof matchesAny;
74
100
  };
101
+ export {};
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@arcgis/components-build-utils",
3
- "version": "5.1.0-next.108",
3
+ "version": "5.1.0-next.109",
4
4
  "description": "Collection of common internal build-time patterns and utilities for ArcGIS Maps SDK for JavaScript components.",
5
5
  "homepage": "https://developers.arcgis.com/javascript/latest/",
6
6
  "type": "module",
7
- "main": "dist/index.cjs",
8
- "module": "dist/index.js",
9
- "types": "dist/index.d.ts",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
@@ -20,6 +20,7 @@
20
20
  ],
21
21
  "license": "SEE LICENSE IN LICENSE.md",
22
22
  "dependencies": {
23
+ "@types/node": "^24.10.0",
23
24
  "tslib": "^2.8.1",
24
25
  "vite": "^7.3.2",
25
26
  "vite-plugin-dts": "^4.5.4"