@atlaspack/packager-js 2.14.5-dev.1c70d50f9.99 → 2.14.5-dev.69

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/CHANGELOG.md CHANGED
@@ -1,62 +1,5 @@
1
1
  # @atlaspack/packager-js
2
2
 
3
- ## 2.16.1
4
-
5
- ### Patch Changes
6
-
7
- - Updated dependencies [[`644b157`](https://github.com/atlassian-labs/atlaspack/commit/644b157dee72a871acc2d0facf0b87b8eea51956)]:
8
- - @atlaspack/feature-flags@2.18.2
9
- - @atlaspack/utils@2.15.2
10
- - @atlaspack/types@2.15.4
11
- - @atlaspack/plugin@2.14.14
12
-
13
- ## 2.16.0
14
-
15
- ### Minor Changes
16
-
17
- - [#644](https://github.com/atlassian-labs/atlaspack/pull/644) [`fc59be7`](https://github.com/atlassian-labs/atlaspack/commit/fc59be71f43dd87d3e6fb7f3f50c424d2b664858) Thanks [@marcins](https://github.com/marcins)! - Removes the unused unstable `forceSkipWrapAssets` feature
18
-
19
- ### Patch Changes
20
-
21
- - [#633](https://github.com/atlassian-labs/atlaspack/pull/633) [`26aa9c5`](https://github.com/atlassian-labs/atlaspack/commit/26aa9c599d2be45ce1438a74c5fa22f39b9b554b) Thanks [@sbhuiyan-atlassian](https://github.com/sbhuiyan-atlassian)! - Ported various HMR changes from Parcel
22
-
23
- - Updated dependencies [[`26aa9c5`](https://github.com/atlassian-labs/atlaspack/commit/26aa9c599d2be45ce1438a74c5fa22f39b9b554b), [`0501255`](https://github.com/atlassian-labs/atlaspack/commit/05012550da35b05ce7d356a8cc29311e7f9afdca)]:
24
- - @atlaspack/feature-flags@2.18.1
25
- - @atlaspack/types@2.15.3
26
- - @atlaspack/utils@2.15.1
27
- - @atlaspack/plugin@2.14.13
28
-
29
- ## 2.15.0
30
-
31
- ### Minor Changes
32
-
33
- - [#627](https://github.com/atlassian-labs/atlaspack/pull/627) [`85c52d3`](https://github.com/atlassian-labs/atlaspack/commit/85c52d3f7717b3c84a118d18ab98cfbfd71dcbd2) Thanks [@benjervis](https://github.com/benjervis)! - Expands the situations where scope hoisting may be applied to include assets with no dependencies, regardless of whether if they have a wrapped ancestor.
34
-
35
- Can be enabled with the `applyScopeHoistingImprovement` feature flag.
36
-
37
- ### Patch Changes
38
-
39
- - [#632](https://github.com/atlassian-labs/atlaspack/pull/632) [`10fbcfb`](https://github.com/atlassian-labs/atlaspack/commit/10fbcfbfa49c7a83da5d7c40983e36e87f524a75) Thanks [@marcins](https://github.com/marcins)! - Added a new feature flag `inlineConstOptimisationFix` which when enabled changes the behaviour for output of constant modules. This fixes two issues with constant modules:
40
-
41
- - Previously constant modules, if they needed a namespace anywhere, would have a namespace everywhere, with this change they only have a namespace in the bundles where needed.
42
- - Previously in the case of wrapped assets, a constant module dependnecy of that wrapped asset would be rendered after the module - which meant the minifier would not be able to inline the constants safely. With this flag all constant modules are rendered at the top of the bundle.
43
-
44
- - Updated dependencies [[`10fbcfb`](https://github.com/atlassian-labs/atlaspack/commit/10fbcfbfa49c7a83da5d7c40983e36e87f524a75), [`85c52d3`](https://github.com/atlassian-labs/atlaspack/commit/85c52d3f7717b3c84a118d18ab98cfbfd71dcbd2), [`e39c6cf`](https://github.com/atlassian-labs/atlaspack/commit/e39c6cf05f7e95ce5420dbcea66f401b1cbd397c)]:
45
- - @atlaspack/feature-flags@2.18.0
46
- - @atlaspack/utils@2.15.0
47
- - @atlaspack/types@2.15.2
48
- - @atlaspack/plugin@2.14.12
49
-
50
- ## 2.14.11
51
-
52
- ### Patch Changes
53
-
54
- - Updated dependencies [[`73ea3c4`](https://github.com/atlassian-labs/atlaspack/commit/73ea3c4d85d4401fdd15abcbf988237e890e7ad3), [`b1b3693`](https://github.com/atlassian-labs/atlaspack/commit/b1b369317c66f8a431c170df2ebba4fa5b2e38ef)]:
55
- - @atlaspack/feature-flags@2.17.0
56
- - @atlaspack/utils@2.14.11
57
- - @atlaspack/types@2.15.1
58
- - @atlaspack/plugin@2.14.11
59
-
60
3
  ## 2.14.10
61
4
 
62
5
  ### Patch Changes
@@ -18,13 +18,6 @@ function _sourceMap() {
18
18
  };
19
19
  return data;
20
20
  }
21
- function _featureFlags() {
22
- const data = require("@atlaspack/feature-flags");
23
- _featureFlags = function () {
24
- return data;
25
- };
26
- return data;
27
- }
28
21
  function _assert() {
29
22
  const data = _interopRequireDefault(require("assert"));
30
23
  _assert = function () {
@@ -115,17 +108,6 @@ class DevPackager {
115
108
  deps[specifier] = dep.specifier;
116
109
  }
117
110
  }
118
- if ((0, _featureFlags().getFeatureFlag)('hmrImprovements')) {
119
- // Add dependencies for parcelRequire calls added by runtimes
120
- // so that the HMR runtime can correctly traverse parents.
121
- let hmrDeps = asset.meta.hmrDeps;
122
- if (this.options.hmrOptions && Array.isArray(hmrDeps)) {
123
- for (let id of hmrDeps) {
124
- (0, _assert().default)(typeof id === 'string');
125
- deps[id] = id;
126
- }
127
- }
128
- }
129
111
  let {
130
112
  code,
131
113
  mapBuffer
@@ -99,12 +99,14 @@ class ScopeHoistingPackager {
99
99
  needsPrelude = false;
100
100
  usedHelpers = new Set();
101
101
  externalAssets = new Set();
102
- constructor(options, bundleGraph, bundle, parcelRequireName, useAsyncBundleRuntime, logger) {
102
+ forceSkipWrapAssets = [];
103
+ constructor(options, bundleGraph, bundle, parcelRequireName, useAsyncBundleRuntime, forceSkipWrapAssets, logger) {
103
104
  this.options = options;
104
105
  this.bundleGraph = bundleGraph;
105
106
  this.bundle = bundle;
106
107
  this.parcelRequireName = parcelRequireName;
107
108
  this.useAsyncBundleRuntime = useAsyncBundleRuntime;
109
+ this.forceSkipWrapAssets = forceSkipWrapAssets ?? [];
108
110
  this.logger = logger;
109
111
  let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
110
112
  this.outputFormat = new OutputFormat(this);
@@ -113,10 +115,7 @@ class ScopeHoistingPackager {
113
115
  }
114
116
  async package() {
115
117
  var _sourceMap;
116
- let {
117
- wrapped: wrappedAssets,
118
- constant: constantAssets
119
- } = await this.loadAssets();
118
+ let wrappedAssets = await this.loadAssets();
120
119
  this.buildExportedSymbols();
121
120
 
122
121
  // If building a library, the target is actually another bundler rather
@@ -128,6 +127,12 @@ class ScopeHoistingPackager {
128
127
  for (let b of this.bundleGraph.getReferencedBundles(this.bundle, {
129
128
  recursive: false
130
129
  })) {
130
+ // If the referenced bundle is a native node bundle then don't require it as
131
+ // an external as we don't want to require native node bundles from other
132
+ // OS architectures
133
+ if (process.env.ATLASPACK_SUPER_BUILD === 'true' && b.type === 'node') {
134
+ continue;
135
+ }
131
136
  this.externals.set((0, _utils().relativeBundlePath)(this.bundle, b), new Map());
132
137
  }
133
138
  }
@@ -144,14 +149,6 @@ class ScopeHoistingPackager {
144
149
  res += content + '\n';
145
150
  lineCount += lines + 1;
146
151
  };
147
- if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
148
- // Write out all constant modules used by this bundle
149
- for (let asset of constantAssets) {
150
- if (!this.seenAssets.has(asset.id)) {
151
- processAsset(asset);
152
- }
153
- }
154
- }
155
152
 
156
153
  // Hoist wrapped asset to the top of the bundle to ensure that they are registered
157
154
  // before they are used.
@@ -274,7 +271,6 @@ class ScopeHoistingPackager {
274
271
  maxConcurrent: 32
275
272
  });
276
273
  let wrapped = [];
277
- let constant = [];
278
274
  this.bundle.traverseAssets(asset => {
279
275
  queue.add(async () => {
280
276
  let [code, map] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap ? asset.getMapBuffer() : null]);
@@ -288,64 +284,38 @@ class ScopeHoistingPackager {
288
284
  if (!asset.meta.isConstantModule || this.bundleGraph.getIncomingDependencies(asset).some(dep => dep.priority === 'lazy')) {
289
285
  this.wrappedAssets.add(asset.id);
290
286
  wrapped.push(asset);
291
- } else if (((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) && asset.meta.isConstantModule) {
292
- constant.push(asset);
293
287
  }
294
288
  }
295
289
  });
296
- if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
297
- // Tracks which assets have been assigned to a wrap group
298
- let assignedAssets = new Set();
299
- for (let wrappedAsset of wrapped) {
300
- this.bundle.traverseAssets((asset, _, actions) => {
301
- if (asset === wrappedAsset) {
302
- return;
303
- }
304
- if (this.wrappedAssets.has(asset.id)) {
305
- actions.skipChildren();
306
- return;
307
- }
308
- if (!asset.meta.isConstantModule && (assignedAssets.has(asset) || this.isReExported(asset))) {
309
- wrapped.push(asset);
310
- this.wrappedAssets.add(asset.id);
311
- actions.skipChildren();
312
- return;
313
- }
314
- assignedAssets.add(asset);
315
- }, wrappedAsset);
316
- }
317
- } else {
318
- for (let wrappedAssetRoot of [...wrapped]) {
319
- this.bundle.traverseAssets((asset, _, actions) => {
320
- if (asset === wrappedAssetRoot) {
321
- return;
322
- }
323
- if (this.wrappedAssets.has(asset.id)) {
324
- actions.skipChildren();
325
- return;
326
- }
327
- if (!asset.meta.isConstantModule) {
328
- this.wrappedAssets.add(asset.id);
329
- wrapped.push(asset);
330
- }
331
- }, wrappedAssetRoot);
332
- }
290
+ for (let wrappedAssetRoot of [...wrapped]) {
291
+ this.bundle.traverseAssets((asset, _, actions) => {
292
+ if (asset === wrappedAssetRoot) {
293
+ return;
294
+ }
295
+ if (this.wrappedAssets.has(asset.id)) {
296
+ actions.skipChildren();
297
+ return;
298
+ }
299
+ // This prevents children of a wrapped asset also being wrapped - it's an "unsafe" optimisation
300
+ // that should only be used when you know (or think you know) what you're doing.
301
+ //
302
+ // In particular this can force an async bundle to be scope hoisted where it previously would not be
303
+ // due to the entry asset being wrapped.
304
+ if (this.forceSkipWrapAssets.length > 0 && this.forceSkipWrapAssets.some(p => p === _path().default.relative(this.options.projectRoot, asset.filePath))) {
305
+ this.logger.verbose({
306
+ message: `Force skipping wrapping of ${_path().default.relative(this.options.projectRoot, asset.filePath)}`
307
+ });
308
+ actions.skipChildren();
309
+ return;
310
+ }
311
+ if (!asset.meta.isConstantModule) {
312
+ this.wrappedAssets.add(asset.id);
313
+ wrapped.push(asset);
314
+ }
315
+ }, wrappedAssetRoot);
333
316
  }
334
317
  this.assetOutputs = new Map(await queue.run());
335
- return {
336
- wrapped,
337
- constant
338
- };
339
- }
340
- isReExported(asset) {
341
- let parentSymbols = this.bundleGraph.getIncomingDependencies(asset).map(dep => this.bundleGraph.getAssetWithDependency(dep)).flatMap(parent => {
342
- if (parent == null) {
343
- return [];
344
- }
345
- return this.bundleGraph.getExportedSymbols(parent, this.bundle);
346
- });
347
- let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
348
- return assetSymbols.some(assetSymbol => parentSymbols.some(parentSymbol => parentSymbol.symbol === assetSymbol.symbol));
318
+ return wrapped;
349
319
  }
350
320
  buildExportedSymbols() {
351
321
  if (!this.bundle.env.isLibrary || this.bundle.env.outputFormat !== 'esmodule') {
@@ -525,22 +495,13 @@ class ScopeHoistingPackager {
525
495
  // outside our parcelRequire.register wrapper. This is safe because all
526
496
  // assets referenced by this asset will also be wrapped. Otherwise, inline the
527
497
  // asset content where the import statement was.
528
- if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
529
- if (!resolved.meta.isConstantModule && !this.wrappedAssets.has(resolved.id)) {
530
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
531
- res = depCode + '\n' + res;
532
- lines += 1 + depLines;
533
- map = depMap;
534
- }
498
+ if (shouldWrap) {
499
+ depContent.push(this.visitAsset(resolved));
535
500
  } else {
536
- if (shouldWrap) {
537
- depContent.push(this.visitAsset(resolved));
538
- } else {
539
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
540
- res = depCode + '\n' + res;
541
- lines += 1 + depLines;
542
- map = depMap;
543
- }
501
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
502
+ res = depCode + '\n' + res;
503
+ lines += 1 + depLines;
504
+ map = depMap;
544
505
  }
545
506
  }
546
507
 
@@ -633,6 +594,14 @@ ${code}
633
594
  this.externalAssets.add(resolved);
634
595
  continue;
635
596
  }
597
+
598
+ // If the referencedBundle is a native node import then require it
599
+ // directly
600
+ // Only enabled for internal builds for now
601
+ if (process.env.ATLASPACK_SUPER_BUILD === 'true' && referencedBundle && referencedBundle.type === 'node') {
602
+ replacements.set((0, _nullthrows().default)(dep.symbols.get('*')).local, `require('${(0, _utils().relativeBundlePath)(this.bundle, referencedBundle)}')`);
603
+ continue;
604
+ }
636
605
  }
637
606
  for (let [imported, {
638
607
  local
@@ -919,26 +888,20 @@ ${code}
919
888
  // If there's no __esModule flag, and default is a used symbol, we need
920
889
  // to insert an interop helper.
921
890
  let defaultInterop = asset.symbols.hasExportSymbol('*') && usedSymbols.has('default') && !asset.symbols.hasExportSymbol('__esModule');
922
- let usedNamespace;
923
- if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') && asset.meta.isConstantModule) {
924
- // Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
925
- usedNamespace = this.bundleGraph.getIncomingDependencies(asset).some(dep => this.bundle.hasDependency(dep) && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'));
926
- } else {
927
- usedNamespace =
928
- // If the asset has * in its used symbols, we might need the exports namespace.
929
- // The one case where this isn't true is in ESM library entries, where the only
930
- // dependency on * is the entry dependency. In this case, we will use ESM exports
931
- // instead of the namespace object.
932
- usedSymbols.has('*') && (this.bundle.env.outputFormat !== 'esmodule' || !this.bundle.env.isLibrary || asset !== this.bundle.getMainEntry() || this.bundleGraph.getIncomingDependencies(asset).some(dep => !dep.isEntry && this.bundle.hasDependency(dep) && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'))) ||
933
- // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
934
- // we fallback on the namespace object.
935
- asset.symbols.hasExportSymbol('*') && [...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s)) ||
936
- // If the exports has this asset's namespace (e.g. ESM output from CJS input),
937
- // include the namespace object for the default export.
938
- this.exportedSymbols.has(`$${assetId}$exports`) ||
939
- // CommonJS library bundle entries always need a namespace.
940
- this.bundle.env.isLibrary && this.bundle.env.outputFormat === 'commonjs' && asset === this.bundle.getMainEntry();
941
- }
891
+ let usedNamespace =
892
+ // If the asset has * in its used symbols, we might need the exports namespace.
893
+ // The one case where this isn't true is in ESM library entries, where the only
894
+ // dependency on * is the entry dependency. In this case, we will use ESM exports
895
+ // instead of the namespace object.
896
+ usedSymbols.has('*') && (this.bundle.env.outputFormat !== 'esmodule' || !this.bundle.env.isLibrary || asset !== this.bundle.getMainEntry() || this.bundleGraph.getIncomingDependencies(asset).some(dep => !dep.isEntry && this.bundle.hasDependency(dep) && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'))) ||
897
+ // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
898
+ // we fallback on the namespace object.
899
+ asset.symbols.hasExportSymbol('*') && [...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s)) ||
900
+ // If the exports has this asset's namespace (e.g. ESM output from CJS input),
901
+ // include the namespace object for the default export.
902
+ this.exportedSymbols.has(`$${assetId}$exports`) ||
903
+ // CommonJS library bundle entries always need a namespace.
904
+ this.bundle.env.isLibrary && this.bundle.env.outputFormat === 'commonjs' && asset === this.bundle.getMainEntry();
942
905
 
943
906
  // If the asset doesn't have static exports, should wrap, the namespace is used,
944
907
  // or we need default interop, then we need to synthesize a namespace object for
package/lib/index.js CHANGED
@@ -47,6 +47,12 @@ const CONFIG_SCHEMA = {
47
47
  properties: {
48
48
  unstable_asyncBundleRuntime: {
49
49
  type: 'boolean'
50
+ },
51
+ unstable_forceSkipWrapAssets: {
52
+ type: 'array',
53
+ items: {
54
+ type: 'string'
55
+ }
50
56
  }
51
57
  },
52
58
  additionalProperties: false
@@ -56,7 +62,7 @@ var _default = exports.default = new (_plugin().Packager)({
56
62
  config,
57
63
  options
58
64
  }) {
59
- var _conf$contents;
65
+ var _conf$contents, _conf$contents2;
60
66
  let packageKey = '@atlaspack/packager-js';
61
67
  let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
62
68
  packageKey
@@ -78,7 +84,8 @@ var _default = exports.default = new (_plugin().Packager)({
78
84
  let name = (packageName === null || packageName === void 0 ? void 0 : packageName.contents) ?? '';
79
85
  return {
80
86
  parcelRequireName: 'parcelRequire' + (0, _rust().hashString)(name).slice(-4),
81
- unstable_asyncBundleRuntime: Boolean(conf === null || conf === void 0 || (_conf$contents = conf.contents) === null || _conf$contents === void 0 ? void 0 : _conf$contents.unstable_asyncBundleRuntime)
87
+ unstable_asyncBundleRuntime: Boolean(conf === null || conf === void 0 || (_conf$contents = conf.contents) === null || _conf$contents === void 0 ? void 0 : _conf$contents.unstable_asyncBundleRuntime),
88
+ unstable_forceSkipWrapAssets: (conf === null || conf === void 0 || (_conf$contents2 = conf.contents) === null || _conf$contents2 === void 0 ? void 0 : _conf$contents2.unstable_forceSkipWrapAssets) ?? []
82
89
  };
83
90
  },
84
91
  async package({
@@ -101,7 +108,7 @@ var _default = exports.default = new (_plugin().Packager)({
101
108
  }
102
109
  }
103
110
  if (contents == null) {
104
- let packager = bundle.env.shouldScopeHoist ? new _ScopeHoistingPackager.ScopeHoistingPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName, (0, _nullthrows().default)(config).unstable_asyncBundleRuntime, logger) : new _DevPackager.DevPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName);
111
+ let packager = bundle.env.shouldScopeHoist ? new _ScopeHoistingPackager.ScopeHoistingPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName, (0, _nullthrows().default)(config).unstable_asyncBundleRuntime, (0, _nullthrows().default)(config).unstable_forceSkipWrapAssets, logger) : new _DevPackager.DevPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName);
105
112
  ({
106
113
  contents,
107
114
  map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/packager-js",
3
- "version": "2.14.5-dev.1c70d50f9.99+1c70d50f9",
3
+ "version": "2.14.5-dev.69+67cb517ae",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -15,16 +15,16 @@
15
15
  "node": ">= 16.0.0"
16
16
  },
17
17
  "dependencies": {
18
- "@atlaspack/diagnostic": "2.14.1-dev.1c70d50f9.167+1c70d50f9",
19
- "@atlaspack/feature-flags": "2.14.1-dev.1c70d50f9.167+1c70d50f9",
20
- "@atlaspack/plugin": "2.14.5-dev.1c70d50f9.99+1c70d50f9",
21
- "@atlaspack/rust": "3.2.1-dev.1c70d50f9.99+1c70d50f9",
22
- "@atlaspack/types": "2.14.5-dev.1c70d50f9.99+1c70d50f9",
23
- "@atlaspack/utils": "2.14.5-dev.1c70d50f9.99+1c70d50f9",
18
+ "@atlaspack/diagnostic": "2.14.1-dev.137+67cb517ae",
19
+ "@atlaspack/feature-flags": "2.14.1-dev.137+67cb517ae",
20
+ "@atlaspack/plugin": "2.14.5-dev.69+67cb517ae",
21
+ "@atlaspack/rust": "3.2.1-dev.69+67cb517ae",
22
+ "@atlaspack/types": "2.14.5-dev.69+67cb517ae",
23
+ "@atlaspack/utils": "2.14.5-dev.69+67cb517ae",
24
24
  "@parcel/source-map": "^2.1.1",
25
25
  "globals": "^13.2.0",
26
26
  "nullthrows": "^1.1.1"
27
27
  },
28
28
  "type": "commonjs",
29
- "gitHead": "1c70d50f914cb662515b0b61053e51a06f3af234"
29
+ "gitHead": "67cb517ae793046fb5a0d2ef02ba74510fefccf3"
30
30
  }
@@ -8,7 +8,6 @@ import {
8
8
  normalizeSeparators,
9
9
  } from '@atlaspack/utils';
10
10
  import SourceMap from '@parcel/source-map';
11
- import {getFeatureFlag} from '@atlaspack/feature-flags';
12
11
  import invariant from 'assert';
13
12
  import path from 'path';
14
13
  import fs from 'fs';
@@ -113,18 +112,6 @@ export class DevPackager {
113
112
  }
114
113
  }
115
114
 
116
- if (getFeatureFlag('hmrImprovements')) {
117
- // Add dependencies for parcelRequire calls added by runtimes
118
- // so that the HMR runtime can correctly traverse parents.
119
- let hmrDeps = asset.meta.hmrDeps;
120
- if (this.options.hmrOptions && Array.isArray(hmrDeps)) {
121
- for (let id of hmrDeps) {
122
- invariant(typeof id === 'string');
123
- deps[id] = id;
124
- }
125
- }
126
- }
127
-
128
115
  let {code, mapBuffer} = results[i];
129
116
  let output = code || '';
130
117
  wrapped +=
@@ -102,6 +102,7 @@ export class ScopeHoistingPackager {
102
102
  needsPrelude: boolean = false;
103
103
  usedHelpers: Set<string> = new Set();
104
104
  externalAssets: Set<Asset> = new Set();
105
+ forceSkipWrapAssets: Array<string> = [];
105
106
  logger: PluginLogger;
106
107
 
107
108
  constructor(
@@ -110,6 +111,7 @@ export class ScopeHoistingPackager {
110
111
  bundle: NamedBundle,
111
112
  parcelRequireName: string,
112
113
  useAsyncBundleRuntime: boolean,
114
+ forceSkipWrapAssets: Array<string>,
113
115
  logger: PluginLogger,
114
116
  ) {
115
117
  this.options = options;
@@ -117,6 +119,7 @@ export class ScopeHoistingPackager {
117
119
  this.bundle = bundle;
118
120
  this.parcelRequireName = parcelRequireName;
119
121
  this.useAsyncBundleRuntime = useAsyncBundleRuntime;
122
+ this.forceSkipWrapAssets = forceSkipWrapAssets ?? [];
120
123
  this.logger = logger;
121
124
 
122
125
  let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
@@ -131,8 +134,7 @@ export class ScopeHoistingPackager {
131
134
  }
132
135
 
133
136
  async package(): Promise<{|contents: string, map: ?SourceMap|}> {
134
- let {wrapped: wrappedAssets, constant: constantAssets} =
135
- await this.loadAssets();
137
+ let wrappedAssets = await this.loadAssets();
136
138
  this.buildExportedSymbols();
137
139
 
138
140
  // If building a library, the target is actually another bundler rather
@@ -147,6 +149,13 @@ export class ScopeHoistingPackager {
147
149
  for (let b of this.bundleGraph.getReferencedBundles(this.bundle, {
148
150
  recursive: false,
149
151
  })) {
152
+ // If the referenced bundle is a native node bundle then don't require it as
153
+ // an external as we don't want to require native node bundles from other
154
+ // OS architectures
155
+ if (process.env.ATLASPACK_SUPER_BUILD === 'true' && b.type === 'node') {
156
+ continue;
157
+ }
158
+
150
159
  this.externals.set(relativeBundlePath(this.bundle, b), new Map());
151
160
  }
152
161
  }
@@ -166,18 +175,6 @@ export class ScopeHoistingPackager {
166
175
  lineCount += lines + 1;
167
176
  };
168
177
 
169
- if (
170
- getFeatureFlag('inlineConstOptimisationFix') ||
171
- getFeatureFlag('applyScopeHoistingImprovement')
172
- ) {
173
- // Write out all constant modules used by this bundle
174
- for (let asset of constantAssets) {
175
- if (!this.seenAssets.has(asset.id)) {
176
- processAsset(asset);
177
- }
178
- }
179
- }
180
-
181
178
  // Hoist wrapped asset to the top of the bundle to ensure that they are registered
182
179
  // before they are used.
183
180
  for (let asset of wrappedAssets) {
@@ -364,20 +361,15 @@ export class ScopeHoistingPackager {
364
361
  return `$parcel$global.rwr(${params.join(', ')});`;
365
362
  }
366
363
 
367
- async loadAssets(): Promise<{|
368
- wrapped: Array<Asset>,
369
- constant: Array<Asset>,
370
- |}> {
364
+ async loadAssets(): Promise<Array<Asset>> {
371
365
  let queue = new PromiseQueue({maxConcurrent: 32});
372
366
  let wrapped = [];
373
- let constant = [];
374
367
  this.bundle.traverseAssets((asset) => {
375
368
  queue.add(async () => {
376
369
  let [code, map] = await Promise.all([
377
370
  asset.getCode(),
378
371
  this.bundle.env.sourceMap ? asset.getMapBuffer() : null,
379
372
  ]);
380
-
381
373
  return [asset.id, {code, map}];
382
374
  });
383
375
 
@@ -398,87 +390,50 @@ export class ScopeHoistingPackager {
398
390
  ) {
399
391
  this.wrappedAssets.add(asset.id);
400
392
  wrapped.push(asset);
401
- } else if (
402
- (getFeatureFlag('inlineConstOptimisationFix') ||
403
- getFeatureFlag('applyScopeHoistingImprovement')) &&
404
- asset.meta.isConstantModule
405
- ) {
406
- constant.push(asset);
407
393
  }
408
394
  }
409
395
  });
410
396
 
411
- if (getFeatureFlag('applyScopeHoistingImprovement')) {
412
- // Tracks which assets have been assigned to a wrap group
413
- let assignedAssets = new Set<Asset>();
414
-
415
- for (let wrappedAsset of wrapped) {
416
- this.bundle.traverseAssets((asset, _, actions) => {
417
- if (asset === wrappedAsset) {
418
- return;
419
- }
420
-
421
- if (this.wrappedAssets.has(asset.id)) {
422
- actions.skipChildren();
423
- return;
424
- }
425
-
426
- if (
427
- !asset.meta.isConstantModule &&
428
- (assignedAssets.has(asset) || this.isReExported(asset))
429
- ) {
430
- wrapped.push(asset);
431
- this.wrappedAssets.add(asset.id);
432
-
433
- actions.skipChildren();
434
- return;
435
- }
436
-
437
- assignedAssets.add(asset);
438
- }, wrappedAsset);
439
- }
440
- } else {
441
- for (let wrappedAssetRoot of [...wrapped]) {
442
- this.bundle.traverseAssets((asset, _, actions) => {
443
- if (asset === wrappedAssetRoot) {
444
- return;
445
- }
446
-
447
- if (this.wrappedAssets.has(asset.id)) {
448
- actions.skipChildren();
449
- return;
450
- }
397
+ for (let wrappedAssetRoot of [...wrapped]) {
398
+ this.bundle.traverseAssets((asset, _, actions) => {
399
+ if (asset === wrappedAssetRoot) {
400
+ return;
401
+ }
451
402
 
452
- if (!asset.meta.isConstantModule) {
453
- this.wrappedAssets.add(asset.id);
454
- wrapped.push(asset);
455
- }
456
- }, wrappedAssetRoot);
457
- }
403
+ if (this.wrappedAssets.has(asset.id)) {
404
+ actions.skipChildren();
405
+ return;
406
+ }
407
+ // This prevents children of a wrapped asset also being wrapped - it's an "unsafe" optimisation
408
+ // that should only be used when you know (or think you know) what you're doing.
409
+ //
410
+ // In particular this can force an async bundle to be scope hoisted where it previously would not be
411
+ // due to the entry asset being wrapped.
412
+ if (
413
+ this.forceSkipWrapAssets.length > 0 &&
414
+ this.forceSkipWrapAssets.some(
415
+ (p) =>
416
+ p === path.relative(this.options.projectRoot, asset.filePath),
417
+ )
418
+ ) {
419
+ this.logger.verbose({
420
+ message: `Force skipping wrapping of ${path.relative(
421
+ this.options.projectRoot,
422
+ asset.filePath,
423
+ )}`,
424
+ });
425
+ actions.skipChildren();
426
+ return;
427
+ }
428
+ if (!asset.meta.isConstantModule) {
429
+ this.wrappedAssets.add(asset.id);
430
+ wrapped.push(asset);
431
+ }
432
+ }, wrappedAssetRoot);
458
433
  }
459
434
 
460
435
  this.assetOutputs = new Map(await queue.run());
461
- return {wrapped, constant};
462
- }
463
-
464
- isReExported(asset: Asset): boolean {
465
- let parentSymbols = this.bundleGraph
466
- .getIncomingDependencies(asset)
467
- .map((dep) => this.bundleGraph.getAssetWithDependency(dep))
468
- .flatMap((parent) => {
469
- if (parent == null) {
470
- return [];
471
- }
472
- return this.bundleGraph.getExportedSymbols(parent, this.bundle);
473
- });
474
-
475
- let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
476
-
477
- return assetSymbols.some((assetSymbol) =>
478
- parentSymbols.some(
479
- (parentSymbol) => parentSymbol.symbol === assetSymbol.symbol,
480
- ),
481
- );
436
+ return wrapped;
482
437
  }
483
438
 
484
439
  buildExportedSymbols() {
@@ -713,27 +668,13 @@ export class ScopeHoistingPackager {
713
668
  // outside our parcelRequire.register wrapper. This is safe because all
714
669
  // assets referenced by this asset will also be wrapped. Otherwise, inline the
715
670
  // asset content where the import statement was.
716
- if (getFeatureFlag('applyScopeHoistingImprovement')) {
717
- if (
718
- !resolved.meta.isConstantModule &&
719
- !this.wrappedAssets.has(resolved.id)
720
- ) {
721
- let [depCode, depMap, depLines] =
722
- this.visitAsset(resolved);
723
- res = depCode + '\n' + res;
724
- lines += 1 + depLines;
725
- map = depMap;
726
- }
671
+ if (shouldWrap) {
672
+ depContent.push(this.visitAsset(resolved));
727
673
  } else {
728
- if (shouldWrap) {
729
- depContent.push(this.visitAsset(resolved));
730
- } else {
731
- let [depCode, depMap, depLines] =
732
- this.visitAsset(resolved);
733
- res = depCode + '\n' + res;
734
- lines += 1 + depLines;
735
- map = depMap;
736
- }
674
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
675
+ res = depCode + '\n' + res;
676
+ lines += 1 + depLines;
677
+ map = depMap;
737
678
  }
738
679
  }
739
680
 
@@ -875,6 +816,21 @@ ${code}
875
816
  this.externalAssets.add(resolved);
876
817
  continue;
877
818
  }
819
+
820
+ // If the referencedBundle is a native node import then require it
821
+ // directly
822
+ // Only enabled for internal builds for now
823
+ if (
824
+ process.env.ATLASPACK_SUPER_BUILD === 'true' &&
825
+ referencedBundle &&
826
+ referencedBundle.type === 'node'
827
+ ) {
828
+ replacements.set(
829
+ nullthrows(dep.symbols.get('*')).local,
830
+ `require('${relativeBundlePath(this.bundle, referencedBundle)}')`,
831
+ );
832
+ continue;
833
+ }
878
834
  }
879
835
 
880
836
  for (let [imported, {local}] of dep.symbols) {
@@ -1286,49 +1242,34 @@ ${code}
1286
1242
  usedSymbols.has('default') &&
1287
1243
  !asset.symbols.hasExportSymbol('__esModule');
1288
1244
 
1289
- let usedNamespace;
1290
- if (
1291
- getFeatureFlag('inlineConstOptimisationFix') &&
1292
- asset.meta.isConstantModule
1293
- ) {
1294
- // Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
1295
- usedNamespace = this.bundleGraph
1296
- .getIncomingDependencies(asset)
1297
- .some(
1298
- (dep) =>
1299
- this.bundle.hasDependency(dep) &&
1300
- nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
1301
- );
1302
- } else {
1303
- usedNamespace =
1304
- // If the asset has * in its used symbols, we might need the exports namespace.
1305
- // The one case where this isn't true is in ESM library entries, where the only
1306
- // dependency on * is the entry dependency. In this case, we will use ESM exports
1307
- // instead of the namespace object.
1308
- (usedSymbols.has('*') &&
1309
- (this.bundle.env.outputFormat !== 'esmodule' ||
1310
- !this.bundle.env.isLibrary ||
1311
- asset !== this.bundle.getMainEntry() ||
1312
- this.bundleGraph
1313
- .getIncomingDependencies(asset)
1314
- .some(
1315
- (dep) =>
1316
- !dep.isEntry &&
1317
- this.bundle.hasDependency(dep) &&
1318
- nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
1319
- ))) ||
1320
- // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
1321
- // we fallback on the namespace object.
1322
- (asset.symbols.hasExportSymbol('*') &&
1323
- [...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
1324
- // If the exports has this asset's namespace (e.g. ESM output from CJS input),
1325
- // include the namespace object for the default export.
1326
- this.exportedSymbols.has(`$${assetId}$exports`) ||
1327
- // CommonJS library bundle entries always need a namespace.
1328
- (this.bundle.env.isLibrary &&
1329
- this.bundle.env.outputFormat === 'commonjs' &&
1330
- asset === this.bundle.getMainEntry());
1331
- }
1245
+ let usedNamespace =
1246
+ // If the asset has * in its used symbols, we might need the exports namespace.
1247
+ // The one case where this isn't true is in ESM library entries, where the only
1248
+ // dependency on * is the entry dependency. In this case, we will use ESM exports
1249
+ // instead of the namespace object.
1250
+ (usedSymbols.has('*') &&
1251
+ (this.bundle.env.outputFormat !== 'esmodule' ||
1252
+ !this.bundle.env.isLibrary ||
1253
+ asset !== this.bundle.getMainEntry() ||
1254
+ this.bundleGraph
1255
+ .getIncomingDependencies(asset)
1256
+ .some(
1257
+ (dep) =>
1258
+ !dep.isEntry &&
1259
+ this.bundle.hasDependency(dep) &&
1260
+ nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
1261
+ ))) ||
1262
+ // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
1263
+ // we fallback on the namespace object.
1264
+ (asset.symbols.hasExportSymbol('*') &&
1265
+ [...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
1266
+ // If the exports has this asset's namespace (e.g. ESM output from CJS input),
1267
+ // include the namespace object for the default export.
1268
+ this.exportedSymbols.has(`$${assetId}$exports`) ||
1269
+ // CommonJS library bundle entries always need a namespace.
1270
+ (this.bundle.env.isLibrary &&
1271
+ this.bundle.env.outputFormat === 'commonjs' &&
1272
+ asset === this.bundle.getMainEntry());
1332
1273
 
1333
1274
  // If the asset doesn't have static exports, should wrap, the namespace is used,
1334
1275
  // or we need default interop, then we need to synthesize a namespace object for
package/src/index.js CHANGED
@@ -17,6 +17,7 @@ import {ScopeHoistingPackager} from './ScopeHoistingPackager';
17
17
  type JSPackagerConfig = {|
18
18
  parcelRequireName: string,
19
19
  unstable_asyncBundleRuntime: boolean,
20
+ unstable_forceSkipWrapAssets: Array<string>,
20
21
  |};
21
22
 
22
23
  const CONFIG_SCHEMA: SchemaEntity = {
@@ -25,6 +26,12 @@ const CONFIG_SCHEMA: SchemaEntity = {
25
26
  unstable_asyncBundleRuntime: {
26
27
  type: 'boolean',
27
28
  },
29
+ unstable_forceSkipWrapAssets: {
30
+ type: 'array',
31
+ items: {
32
+ type: 'string',
33
+ },
34
+ },
28
35
  },
29
36
  additionalProperties: false,
30
37
  };
@@ -66,6 +73,8 @@ export default (new Packager({
66
73
  unstable_asyncBundleRuntime: Boolean(
67
74
  conf?.contents?.unstable_asyncBundleRuntime,
68
75
  ),
76
+ unstable_forceSkipWrapAssets:
77
+ conf?.contents?.unstable_forceSkipWrapAssets ?? [],
69
78
  };
70
79
  },
71
80
  async package({
@@ -99,6 +108,7 @@ export default (new Packager({
99
108
  bundle,
100
109
  nullthrows(config).parcelRequireName,
101
110
  nullthrows(config).unstable_asyncBundleRuntime,
111
+ nullthrows(config).unstable_forceSkipWrapAssets,
102
112
  logger,
103
113
  )
104
114
  : new DevPackager(