parcel 2.16.4 → 3.0.0-alpha.1

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
@@ -5,33 +5,34 @@
5
5
  </p>
6
6
 
7
7
  [![Backers on Open Collective](https://opencollective.com/parcel/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/parcel/sponsors/badge.svg)](#sponsors)
8
- [![Build Status](https://dev.azure.com/devongovett/devongovett/_apis/build/status/parcel-bundler.parcel?branchName=v2)](https://dev.azure.com/devongovett/devongovett/_build/latest?definitionId=1)
9
8
  [![npm package](https://img.shields.io/npm/v/parcel.svg)](https://www.npmjs.com/package/parcel)
10
9
  [![npm package](https://img.shields.io/npm/dm/parcel.svg)](https://www.npmjs.com/package/parcel)
11
10
  [![Discord](https://img.shields.io/discord/894288336095690753)](https://discord.gg/XSCzqGRuvr)
12
11
  [![Twitter Follow](https://img.shields.io/twitter/follow/parceljs.svg?style=social)](https://twitter.com/parceljs)
13
12
 
14
- Parcel is a zero configuration build tool for the web. It combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production application.
13
+ **NOTE: This is Parcel v3 (currently in alpha).**
14
+
15
+ Parcel is a batteries-included build tool for the web. It combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production application.
15
16
 
16
17
  ## Features
17
18
 
18
- - 😍 **Zero config** – Parcel supports many languages and file types out of the box, from web technologies like HTML, CSS, and JavaScript, to assets like images, fonts, videos, and more. It has a built-in dev server with hot reloading, beautiful error diagnostics, and much more. No configuration needed!
19
- - ⚡️ **Lightning fast** – Parcel's JavaScript compiler is written in Rust for native performance. Your code is built in parallel using worker threads, utilizing all of the cores on your machine. Everything is cached, so you never build the same code twice. It's like using watch mode, but even when you restart Parcel!
19
+ - 😍 **Batteries included** – Parcel supports many languages and file types out of the box, from web technologies like HTML, CSS, and JavaScript, to assets like images, fonts, videos, and more. It has a built-in dev server with hot reloading, beautiful error diagnostics, and much more. No configuration needed!
20
+ - ⚡️ **Lightning fast** – Parcel is written in Rust for native performance, taking advantage of all of the cores on your machine. Extend it with native plugins written in Rust, Go, Swift, or any language that supports the C ABI.
20
21
  - 🚀 **Automatic production optimization** – Parcel optimizes your whole app for production automatically. This includes tree-shaking and minifying your JavaScript, CSS, and HTML, resizing and optimizing images, content hashing, automatic code splitting, and much more.
21
22
  - 🎯 **Ship for any target** – Parcel automatically transforms your code for your target environments. From modern and legacy browser support, to zero config JSX and TypeScript compilation, Parcel makes it easy to build for any target – or many!
22
- - 🌍 **Scalable** – Parcel requires zero configuration to get started. But as your application grows and your build requirements become more complex, it's possible to extend Parcel in just about every way. A simple configuration format and powerful plugin system that's designed from the ground up for performance means Parcel can support projects of any size.
23
+ - 🌍 **Scalable** – Parcel requires zero configuration to get started. But as your application grows and your build requirements become more complex, it's possible to extend Parcel in just about every way. A simple configuration format and powerful native and JavaScript plugin system means Parcel can support projects of any size or complexity.
23
24
 
24
25
  ## Getting Started
25
26
 
26
27
  See the following guides in our documentation on how to get started with Parcel.
27
28
 
28
- * [Building a webapp with Parcel](https://parceljs.org/getting-started/webapp/)
29
- * [Building a library with Parcel](https://parceljs.org/getting-started/library/)
30
- * [Migrating from Parcel v1](https://parceljs.org/getting-started/migration/)
29
+ * [Building a webapp with Parcel](https://v3.parceljs.org/getting-started/webapp/)
30
+ * [Building a library with Parcel](https://v3.parceljs.org/getting-started/library/)
31
+ * [Migrating from Parcel v2](https://v3.parceljs.org/getting-started/migration/)
31
32
 
32
33
  ## Documentation
33
34
 
34
- Read the docs at https://parceljs.org/docs/.
35
+ Read the docs at https://v3.parceljs.org/docs/.
35
36
 
36
37
  ## Community
37
38
 
package/bin/parcel ADDED
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Shipped as `bin/parcel` in the `parcel` package, and as `bin/parcel3` in
6
+ * `@parcel/parcel3`, which exists so Parcel 3 can be installed beside Parcel 2.
7
+ * Parcel itself is a native executable, published one
8
+ * platform package per target and pulled in through optionalDependencies, so all
9
+ * this file does is hand off to whichever one npm installed for this host.
10
+ *
11
+ * It also tries to take itself out of the loop. Starting Node costs ~30ms on
12
+ * every single invocation, which is a large tax on a tool whose whole
13
+ * point is being fast, so on the first run it rewrites the `node_modules/.bin`
14
+ * entry that launched it into a launcher that execs the binary without Node.
15
+ * See `launcher` for why that launcher looks the way it does.
16
+ *
17
+ * Install scripts would be the natural place for this, but npm and pnpm both
18
+ * block them by default now, so first run is the earliest moment available.
19
+ */
20
+
21
+ const fs = require('fs');
22
+ const path = require('path');
23
+
24
+ /**
25
+ * The command, which is also the `node_modules/.bin` entry `optimize` rewrites.
26
+ * Taken from this file's own name, so both packages can ship it unchanged.
27
+ */
28
+ const NAME = path.basename(__filename);
29
+
30
+ /** Prefix of the platform packages, which both packages depend on. */
31
+ const PLATFORM_PACKAGE = '@parcel/parcel3';
32
+
33
+ const EXECUTABLE = process.platform === 'win32' ? 'parcel.exe' : 'parcel';
34
+
35
+ /**
36
+ * The platform packages that could serve this host, best first.
37
+ *
38
+ * The names are derived rather than listed, matching what `matrix.mjs` builds
39
+ * from the target table: `process.platform` and `process.arch` are already the
40
+ * values npm's `os` and `cpu` fields use, so a new target needs no change here.
41
+ *
42
+ * On Linux the name also depends on the C library, and rather than detect it and
43
+ * trust the answer we try both: npm, pnpm and Bun all honour the `libc` field,
44
+ * so only the right one is installed and the wrong one simply fails to resolve.
45
+ * The musl check just decides which to try first, for the package managers that
46
+ * ignore `libc` and install both.
47
+ */
48
+ function candidates() {
49
+ const base = `${PLATFORM_PACKAGE}-${process.platform}-${process.arch}`;
50
+ if (process.platform !== 'linux') return [base];
51
+ return isMusl() ? [`${base}-musl`, base] : [base, `${base}-musl`];
52
+ }
53
+
54
+ /**
55
+ * Whether this is a musl system. Biome and friends shell out to `ldd --version`
56
+ * for this; a directory listing costs a fraction of a process.
57
+ */
58
+ function isMusl() {
59
+ try {
60
+ return fs.readdirSync('/lib').some(entry => entry.startsWith('ld-musl-'));
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+
66
+ function resolveBinary() {
67
+ for (const pkg of candidates()) {
68
+ try {
69
+ return require.resolve(`${pkg}/${EXECUTABLE}`);
70
+ } catch {}
71
+ }
72
+ return null;
73
+ }
74
+
75
+ const binPath = resolveBinary();
76
+ if (binPath == null) {
77
+ // Both cases land here, and the message covers both: the package is missing
78
+ // either because this platform has no prebuilt binary, or because it was
79
+ // skipped at install time.
80
+ process.stderr.write(
81
+ `Parcel could not find the "${
82
+ candidates()[0]
83
+ }" package, which would hold the Parcel ` +
84
+ `binary for ${process.platform} ${process.arch}.\n\n` +
85
+ `Either Parcel publishes no binary for this platform, or the one it does publish was not ` +
86
+ `installed: it comes in through optionalDependencies, so --no-optional and --omit=optional ` +
87
+ `both skip it, as does copying node_modules here from a machine of a different platform. ` +
88
+ `Reinstalling on this machine fixes the second case.\n`,
89
+ );
90
+ process.exit(1);
91
+ }
92
+
93
+ optimize();
94
+ run();
95
+
96
+ /**
97
+ * Rewrite the `.bin` entry that launched us so it runs the binary directly.
98
+ *
99
+ * Only an entry that can be proven to refer to this file is ever touched, the
100
+ * write goes through a temp file and an atomic rename, and every failure leaves
101
+ * the entry alone - a slow Parcel is fine, a broken one is not.
102
+ */
103
+ function optimize() {
104
+ // Windows generates .cmd and .ps1 shims with `node` baked in at install time,
105
+ // so replacing what they point at would only break them.
106
+ if (process.platform === 'win32' || process.env.PARCEL_NO_OPTIMIZE) return;
107
+
108
+ for (const entry of binEntries()) {
109
+ try {
110
+ const stat = fs.lstatSync(entry);
111
+ if (stat.isSymbolicLink()) {
112
+ // npm and Yarn: the .bin entry is a symlink to this file.
113
+ if (fs.realpathSync(entry) !== __filename) continue;
114
+ } else if (stat.isFile()) {
115
+ // pnpm: the .bin entry is a generated sh wrapper that runs `node <this>`.
116
+ if (!wrapsThisFile(fs.readFileSync(entry, 'utf8'))) continue;
117
+ } else {
118
+ continue;
119
+ }
120
+
121
+ replace(entry);
122
+ } catch {}
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Whether a generated wrapper points at this file. Package managers write the
128
+ * path relative to their own layout, so the tail below the last `node_modules`
129
+ * is the longest part that is guaranteed to appear verbatim.
130
+ */
131
+ function wrapsThisFile(contents) {
132
+ const tail = __filename.split(/node_modules[\\/]/).pop();
133
+ return contents.includes(tail) && contents.includes('node');
134
+ }
135
+
136
+ /** Every `.bin` entry that could have launched this file. */
137
+ function* binEntries() {
138
+ // What the kernel was handed, before symlinks were resolved: npm and Yarn
139
+ // launch us through the .bin symlink itself.
140
+ const argv1 = process.argv[1];
141
+ if (argv1 && path.basename(path.dirname(argv1)) === '.bin') {
142
+ yield argv1;
143
+ }
144
+
145
+ // Otherwise walk up. `node_modules/.bin` covers a hoisted layout; pnpm keeps
146
+ // the package under `node_modules/.pnpm/...` and the bin beside the store
147
+ // rather than next to the package, so that one is checked separately.
148
+ let dir = path.dirname(__filename);
149
+ for (
150
+ let parent = path.dirname(dir);
151
+ parent !== dir;
152
+ parent = path.dirname(dir)
153
+ ) {
154
+ const base = path.basename(dir);
155
+ if (base === 'node_modules') yield path.join(dir, '.bin', NAME);
156
+ if (base === '.pnpm') yield path.join(parent, '.bin', NAME);
157
+ dir = parent;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * The launcher gets read two different ways and has to work as both.
163
+ *
164
+ * Normally the kernel reads `#!/bin/sh` and sh execs the binary, which is the
165
+ * whole point: no Node anywhere. But an invocation that started just before the
166
+ * rename has already told Node to load this path as its entry module, and Node
167
+ * opens it ~30ms later - after the swap. Writing anything Node cannot parse, a
168
+ * symlink to the binary included, makes those invocations die trying to read a
169
+ * Mach-O or ELF file as JavaScript.
170
+ *
171
+ * So the rest of the file is also valid JavaScript. `":"` is the sh no-op and a
172
+ * bare string in JS; everything after `//` is an sh argument and a JS comment.
173
+ * A straggler falls through to the last line and runs the binary anyway, paying
174
+ * for Node one final time.
175
+ */
176
+ function launcher(entry) {
177
+ // Relative to the launcher, so the tree stays movable: renaming the project or
178
+ // copying node_modules into an image keeps it working.
179
+ const rel = path.relative(path.dirname(entry), binPath);
180
+ if (/["$`\\\n]/.test(rel)) return null; // not safely quotable for sh
181
+
182
+ return (
183
+ '#!/bin/sh\n' +
184
+ `":" //# ; exec "\${0%/*}/${rel}" "$@"\n` +
185
+ `require("child_process").spawnSync(require("path").join(__dirname, ${JSON.stringify(
186
+ rel,
187
+ )}), ` +
188
+ `process.argv.slice(2), {stdio: "inherit"});\n`
189
+ );
190
+ }
191
+
192
+ /**
193
+ * Write beside the entry, then rename over it. A concurrent invocation sees
194
+ * either the old entry or the new one, never a half-written file.
195
+ */
196
+ function replace(entry) {
197
+ const contents = launcher(entry);
198
+ if (contents == null) return;
199
+
200
+ const tmp = `${entry}.${process.pid}.tmp`;
201
+ try {
202
+ fs.writeFileSync(tmp, contents, {mode: 0o755});
203
+ fs.renameSync(tmp, entry);
204
+ } catch (err) {
205
+ try {
206
+ fs.unlinkSync(tmp);
207
+ } catch {}
208
+ throw err;
209
+ }
210
+ }
211
+
212
+ function run() {
213
+ const args = process.argv.slice(2);
214
+
215
+ // Replacing this process rather than forking one keeps signals, the exit code
216
+ // and terminal handling native. Node gained execve in 23.11 and never has it
217
+ // on Windows, hence the fallback.
218
+ if (typeof process.execve === 'function') {
219
+ process.execve(binPath, [binPath, ...args], process.env);
220
+ }
221
+
222
+ const result = require('child_process').spawnSync(binPath, args, {
223
+ stdio: 'inherit',
224
+ });
225
+ if (result.error) throw result.error;
226
+ // Signal death has no exit code of its own; 128 + signal is what a shell reports.
227
+ process.exit(
228
+ result.signal
229
+ ? 128 + require('os').constants.signals[result.signal]
230
+ : result.status,
231
+ );
232
+ }
package/package.json CHANGED
@@ -1,45 +1,31 @@
1
1
  {
2
2
  "name": "parcel",
3
- "version": "2.16.4",
3
+ "version": "3.0.0-alpha.1",
4
4
  "description": "Blazing fast, zero configuration web application bundler",
5
5
  "license": "MIT",
6
- "publishConfig": {
7
- "access": "public"
8
- },
9
- "funding": {
10
- "type": "opencollective",
11
- "url": "https://opencollective.com/parcel"
12
- },
13
6
  "repository": {
14
7
  "type": "git",
15
8
  "url": "https://github.com/parcel-bundler/parcel.git"
16
9
  },
17
- "bin": "lib/bin.js",
18
- "main": "lib/bin.js",
19
- "source": "src/bin.js",
20
- "engines": {
21
- "node": ">= 16.0.0"
10
+ "bin": {
11
+ "parcel": "bin/parcel"
22
12
  },
23
- "dependencies": {
24
- "@parcel/config-default": "2.16.4",
25
- "@parcel/core": "2.16.4",
26
- "@parcel/diagnostic": "2.16.4",
27
- "@parcel/events": "2.16.4",
28
- "@parcel/feature-flags": "2.16.4",
29
- "@parcel/fs": "2.16.4",
30
- "@parcel/logger": "2.16.4",
31
- "@parcel/package-manager": "2.16.4",
32
- "@parcel/reporter-cli": "2.16.4",
33
- "@parcel/reporter-dev-server": "2.16.4",
34
- "@parcel/reporter-tracer": "2.16.4",
35
- "@parcel/utils": "2.16.4",
36
- "chalk": "^4.1.2",
37
- "commander": "^12.1.0",
38
- "get-port": "^4.2.0"
39
- },
40
- "devDependencies": {
41
- "@babel/core": "^7.22.11",
42
- "@parcel/babel-register": "2.16.4"
13
+ "files": [
14
+ "bin",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "engines": {
19
+ "node": ">= 18"
43
20
  },
44
- "gitHead": "59484858a1a0bcbb71f74088956bb437a2db6505"
45
- }
21
+ "optionalDependencies": {
22
+ "@parcel/parcel3-darwin-arm64": "3.0.0-alpha.1",
23
+ "@parcel/parcel3-win32-arm64": "3.0.0-alpha.1",
24
+ "@parcel/parcel3-linux-arm64": "3.0.0-alpha.1",
25
+ "@parcel/parcel3-linux-arm64-musl": "3.0.0-alpha.1",
26
+ "@parcel/parcel3-darwin-x64": "3.0.0-alpha.1",
27
+ "@parcel/parcel3-win32-x64": "3.0.0-alpha.1",
28
+ "@parcel/parcel3-linux-x64": "3.0.0-alpha.1",
29
+ "@parcel/parcel3-linux-x64-musl": "3.0.0-alpha.1"
30
+ }
31
+ }
package/lib/bin.js DELETED
@@ -1,4 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- require('./cli');