@parcel/packager-js 2.0.0-beta.3.1 → 2.0.0-dev.1515

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.
@@ -1,11 +1,17 @@
1
1
  // @flow strict-local
2
2
  import type {BundleGraph, PluginOptions, NamedBundle} from '@parcel/types';
3
3
 
4
- import {PromiseQueue, relativeBundlePath, countLines} from '@parcel/utils';
4
+ import {
5
+ PromiseQueue,
6
+ relativeBundlePath,
7
+ countLines,
8
+ normalizeSeparators,
9
+ } from '@parcel/utils';
5
10
  import SourceMap from '@parcel/source-map';
6
11
  import invariant from 'assert';
7
12
  import path from 'path';
8
13
  import fs from 'fs';
14
+ import {replaceScriptDependencies, getSpecifier} from './utils';
9
15
 
10
16
  const PRELUDE = fs
11
17
  .readFileSync(path.join(__dirname, 'dev-prelude.js'), 'utf8')
@@ -33,16 +39,14 @@ export class DevPackager {
33
39
  async package(): Promise<{|contents: string, map: ?SourceMap|}> {
34
40
  // Load assets
35
41
  let queue = new PromiseQueue({maxConcurrent: 32});
36
- this.bundle.traverse(node => {
37
- if (node.type === 'asset') {
38
- queue.add(async () => {
39
- let [code, mapBuffer] = await Promise.all([
40
- node.value.getCode(),
41
- this.bundle.env.sourceMap && node.value.getMapBuffer(),
42
- ]);
43
- return {code, mapBuffer};
44
- });
45
- }
42
+ this.bundle.traverseAssets(asset => {
43
+ queue.add(async () => {
44
+ let [code, mapBuffer] = await Promise.all([
45
+ asset.getCode(),
46
+ this.bundle.env.sourceMap && asset.getMapBuffer(),
47
+ ]);
48
+ return {code, mapBuffer};
49
+ });
46
50
  });
47
51
 
48
52
  let results = await queue.run();
@@ -54,12 +58,13 @@ export class DevPackager {
54
58
 
55
59
  let prefix = this.getPrefix();
56
60
  let lineOffset = countLines(prefix);
61
+ let script: ?{|code: string, mapBuffer: ?Buffer|} = null;
57
62
 
58
63
  this.bundle.traverse(node => {
59
64
  let wrapped = first ? '' : ',';
60
65
 
61
66
  if (node.type === 'dependency') {
62
- let resolved = this.bundleGraph.getDependencyResolution(
67
+ let resolved = this.bundleGraph.getResolvedAsset(
63
68
  node.value,
64
69
  this.bundle,
65
70
  );
@@ -82,17 +87,28 @@ export class DevPackager {
82
87
  'all assets in a js bundle must be js assets',
83
88
  );
84
89
 
90
+ // If this is the main entry of a script rather than a module, we need to hoist it
91
+ // outside the bundle wrapper function so that its variables are exposed as globals.
92
+ if (
93
+ this.bundle.env.sourceType === 'script' &&
94
+ asset === this.bundle.getMainEntry()
95
+ ) {
96
+ script = results[i++];
97
+ return;
98
+ }
99
+
85
100
  let deps = {};
86
101
  let dependencies = this.bundleGraph.getDependencies(asset);
87
102
  for (let dep of dependencies) {
88
- let resolved = this.bundleGraph.getDependencyResolution(
89
- dep,
90
- this.bundle,
91
- );
92
- if (resolved) {
93
- deps[dep.moduleSpecifier] = this.bundleGraph.getAssetPublicId(
94
- resolved,
95
- );
103
+ let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
104
+ if (this.bundleGraph.isDependencySkipped(dep)) {
105
+ deps[getSpecifier(dep)] = false;
106
+ } else if (resolved) {
107
+ deps[getSpecifier(dep)] =
108
+ this.bundleGraph.getAssetPublicId(resolved);
109
+ } else {
110
+ // An external module - map placeholder to original specifier.
111
+ deps[getSpecifier(dep)] = dep.specifier;
96
112
  }
97
113
  }
98
114
 
@@ -106,6 +122,20 @@ export class DevPackager {
106
122
  wrapped += JSON.stringify(deps);
107
123
  wrapped += ']';
108
124
 
125
+ if (
126
+ this.bundle.env.isNode() &&
127
+ asset.meta.has_node_replacements === true
128
+ ) {
129
+ const relPath = normalizeSeparators(
130
+ path.relative(
131
+ this.bundle.target.distDir,
132
+ path.dirname(asset.filePath),
133
+ ),
134
+ );
135
+ wrapped = wrapped.replace('$parcel$dirnameReplace', relPath);
136
+ wrapped = wrapped.replace('$parcel$filenameReplace', relPath);
137
+ }
138
+
109
139
  if (this.bundle.env.sourceMap) {
110
140
  if (mapBuffer) {
111
141
  map.addBuffer(mapBuffer, lineOffset);
@@ -130,7 +160,10 @@ export class DevPackager {
130
160
 
131
161
  let entries = this.bundle.getEntryAssets();
132
162
  let mainEntry = this.bundle.getMainEntry();
133
- if (!this.isEntry() && this.bundle.env.outputFormat === 'global') {
163
+ if (
164
+ (!this.isEntry() && this.bundle.env.outputFormat === 'global') ||
165
+ this.bundle.env.sourceType === 'script'
166
+ ) {
134
167
  // In async bundles we don't want the main entry to execute until we require it
135
168
  // as there might be dependencies in a sibling bundle that hasn't loaded yet.
136
169
  entries = entries.filter(a => a.id !== mainEntry?.id);
@@ -154,6 +187,27 @@ export class DevPackager {
154
187
  ')' +
155
188
  '\n';
156
189
 
190
+ // The entry asset of a script bundle gets hoisted outside the bundle wrapper function
191
+ // so that its variables become globals. We need to replace any require calls for
192
+ // runtimes with a parcelRequire call.
193
+ if (this.bundle.env.sourceType === 'script' && script) {
194
+ let entryMap;
195
+ let mapBuffer = script.mapBuffer;
196
+ if (mapBuffer) {
197
+ entryMap = new SourceMap(this.options.projectRoot, mapBuffer);
198
+ }
199
+ contents += replaceScriptDependencies(
200
+ this.bundleGraph,
201
+ this.bundle,
202
+ script.code,
203
+ entryMap,
204
+ this.parcelRequireName,
205
+ );
206
+ if (this.bundle.env.sourceMap && entryMap) {
207
+ map.addSourceMap(entryMap, lineOffset);
208
+ }
209
+ }
210
+
157
211
  return {
158
212
  contents,
159
213
  map,
@@ -192,7 +246,7 @@ export class DevPackager {
192
246
  return (
193
247
  !this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') ||
194
248
  this.bundle.env.isIsolated() ||
195
- !!this.bundle.getMainEntry()?.isIsolated
249
+ this.bundle.bundleBehavior === 'isolated'
196
250
  );
197
251
  }
198
252
  }
@@ -70,14 +70,31 @@ export class ESMOutputFormat implements OutputFormat {
70
70
  return [res, lines];
71
71
  }
72
72
 
73
- buildBundlePostlude(): string {
73
+ buildBundlePostlude(): [string, number] {
74
74
  let res = '';
75
+ let lines = 0;
75
76
  let exportSpecifiers = [];
76
- for (let exported of this.packager.exportedSymbols.values()) {
77
- for (let {exportAs, local} of exported) {
77
+ for (let {
78
+ asset,
79
+ exportSymbol,
80
+ local,
81
+ exportAs,
82
+ } of this.packager.exportedSymbols.values()) {
83
+ if (this.packager.wrappedAssets.has(asset.id)) {
84
+ let obj = `parcelRequire("${this.packager.bundleGraph.getAssetPublicId(
85
+ asset,
86
+ )}")`;
87
+ res += `\nvar ${local} = ${this.packager.getPropertyAccess(
88
+ obj,
89
+ exportSymbol,
90
+ )};`;
91
+ lines++;
92
+ }
93
+
94
+ for (let as of exportAs) {
78
95
  let specifier = local;
79
96
  if (exportAs !== local) {
80
- specifier += ` as ${exportAs}`;
97
+ specifier += ` as ${as}`;
81
98
  }
82
99
 
83
100
  exportSpecifiers.push(specifier);
@@ -86,8 +103,20 @@ export class ESMOutputFormat implements OutputFormat {
86
103
 
87
104
  if (exportSpecifiers.length > 0) {
88
105
  res += `\nexport {${exportSpecifiers.join(', ')}};`;
106
+ lines++;
89
107
  }
90
108
 
91
- return res;
109
+ if (
110
+ this.packager.needsPrelude &&
111
+ this.packager.shouldBundleQueue(this.packager.bundle)
112
+ ) {
113
+ // Should be last thing the bundle executes on intial eval
114
+ res += `\n$parcel$global.rlb(${JSON.stringify(
115
+ this.packager.bundle.publicId,
116
+ )})`;
117
+ lines++;
118
+ }
119
+
120
+ return [res, lines];
92
121
  }
93
122
  }
@@ -12,10 +12,13 @@ export class GlobalOutputFormat implements OutputFormat {
12
12
  }
13
13
 
14
14
  buildBundlePrelude(): [string, number] {
15
- return ['(function () {\n', 1];
15
+ let prelude = this.packager.bundle.env.supports('arrow-functions', true)
16
+ ? '(() => {\n'
17
+ : '(function () {\n';
18
+ return [prelude, 1];
16
19
  }
17
20
 
18
- buildBundlePostlude(): string {
19
- return '})();';
21
+ buildBundlePostlude(): [string, number] {
22
+ return ['})();', 0];
20
23
  }
21
24
  }