π Migration
Some tips for upgrading from Parcel 1 to Parcel 2
For the most part, you shouldn't have to change much when upgrading to Parcel 2:
ΒΆ Code Changes
ΒΆ Importing non-code assets from Javascript
If you want import the url to an image (or a soundfile, etc.) from Javascript, you need to prepend url: to the module specifier (read more about named pipelines in Plugin Configuration)
import logo from "./logo.svg";
document.body.innerHTML = `<img src="${logo}">`;import logo from "url:./logo.svg";
document.body.innerHTML = `<img src="${logo}">`;Alternatively, you can use a custom .parcelrc to opt into the old behaviour (add more asset extensions if you use them):
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{jpg,png,svg}": ["@parcel/transformer-raw"]
  }
}ΒΆ Typescript
Parcel 1 transpiled TypeScript using tsc (the official TypeScript compiler). Parcel 2 instead uses Babel (using @babel/preset-env) by default. This has two notable consequences:
(The TypeScript page contains more informations - and limitations - of Parcel's TypeScript handling.)
ΒΆ @babel/preset-typescript Isn't inserted Automatically into a Custom .babelrc.
For most use cases, transpiling using Babel is enough, so Parcel includes @babel/preset-typescript in its default Babel config for TypeScript assets. You need to specify it manually however if you are using a custom .babelrc:
{
  "presets": ["@babel/preset-env"],
  "plugins": ["babel-plugin-foo"]
}{
  "presets": ["@babel/preset-env", "@babel/preset-typescript"],
  "plugins": ["babel-plugin-foo"]
}ΒΆ Babel Doesn't Read tsconfig.json
In case Babel doesn't work for you (e.g. because of an advanced tsconfig.json), you can use tsc:
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
  }
}ΒΆ Importing GraphQL
When import GraphQL files (.gql), imports are still resolved/inlined (using graphql-import-macro), but you now get the processed GraphQL query as a string instead of an Apollo AST.
import fetchDataQuery from "./fetchData.gql"; // fetchDataQuery is the parsed AST
const DataComponent = () => {
  const { data } = useQuery(test, {
    fetchPolicy: "cache-and-network",
  });
  // ...
};import gql from "graphql-tag";
import fetchDataQuery from "./fetchData.gql"; // fetchDataQuery is a string
// Convert to the Apollo Specific Query AST
const parsedFetchDataQuery = gql(fetchDataQuery);
const DataComponent = () => {
  const { data } = useQuery(parsedFetchDataQuery, {
    fetchPolicy: "cache-and-network",
  });
  // ...
};ΒΆ Hooking into Bundle Events
Parcel 1 let you hook in and listen to events like buildEnd or buildError. The API has changed but you can still listen for events like so:
import Bundler from "parcel-bundler"
const bundler = new Bundler({ /* ... */ })
bundler.bundle()
bundler.on("buildEnd", () => { /* ... */ })
bundler.on("buildError", (error) => { /* ... */ })import Parcel from "@parcel/core"
const bundler = new Parcel({ /* ... */ })
bundler.watch((err, buildEvent) => {
  if(buildEvent.type === "buildSuccess") { /* ... */ }
  if(buildEvent.type === "buildFailure") { /* ... */ }
})ΒΆ Configuration/CLI
ΒΆ Transpilation
By default, Parcel 2 doesn't downlevel your source code anymore. If you want this to happen, you should specify a browserslist to only target the browsers you want to support.
ΒΆ package.json#main
Many package.jsons (e.g. the one generated by npm init) contain main: "index.js" which is ignored by most tools (for non-library projects). Parcel 2 will however use that value as the output path; for most web apps, this line should simply be removed. If you really do need it, you can add "targets": { "main": false } to your package.json. See Configuration#main
ΒΆ --target
This CLI flag is now inferred from your package.json, one of these three properties is enough (number denotes priority).
parcel build index.js --target node{
  "targets": {
    "default": {
      "context": "node", // <--- (1)
      "engines": {
        "node": "10", // <------ (2)
      },
    },
  },
  "engines": {
    "node": "10", // <---------- (3)
  },
}ΒΆ --experimental-scope-hoisting
Parcel 2 has scope hoisting enabled by default; to disable it, add --no-scope-hoist.
parcel build index.js --experimental-scope-hoisting
parcel build index.jsparcel build index.js
parcel build index.js --no-scope-hoistΒΆ --bundle-node-modules
To bundle packages from node_modules when targetting Node.js, you now should specify that in the target configuration:
parcel build index.js --target node --bundle-node-modules{
  "default": "dist/index.js"
  "targets": {
    "default": {
      "includeNodeModules": true
    }
  },
  "engines": {
    "node": "10"
  }
}This option is more versatile that the CLI parameter (you can also selectively include packages), see Configuration#includeNodeModules for all details.
ΒΆ --out-dir
To align --out-dir with the options in package.json#targets, that option was renamed to --dist-dir.
parcel build index.html --out-dir wwwparcel build index.html --dist-dir wwwΒΆ --out-file
This flag was removed and the path should instead be specified in package.json (see Configuration).
parcel build index.js --out-file lib.js{
  "default": "lib.js",
  // ...
}ΒΆ --log-level
The log levels now have names instead of numbers (none, error, warn, info, verbose)
parcel build index.js --log-level 1parcel build index.js --log-level errorΒΆ --global
This option has been removed without a replacement (for now).
parcel build index.js --global mylibΒΆ --no-minify
This option has been renamed to --no-optimize
parcel build index.js --no-minifyparcel build index.js --no-optimize