Parcel: How can I throw an error from a plugin to prevent a build?

Created on 21 Nov 2019  ·  5Comments  ·  Source: parcel-bundler/parcel

❔ Question

How can I throw an error in a plugin that will prevent the build from continuing?

🔦 Context

I am developing a one-liner plugin whose only job is to run execSync('tsc --noEmit') before every build. It throws an error, and a warning is printed to the console, but the build continues on anyway. I can manually call process.exit(1) but that'll kill the whole parcel process watching my files. Is it possible for a plugin to indicate that the build has failed?

💻 Code Sample

const { execSync } = require('child_process')
const path = require('path')

const cwd = process.cwd()
const binPath = execSync('yarn bin', { cwd, encoding: 'utf8' }).trim()
const tscCommand = `${path.join(binPath, 'tsc')} --noEmit`

module.exports = () => {
  // Will throw if tsc reports any issues
  execSync(tscCommand, { cwd, encoding: 'utf8', stdio: 'inherit' })
}
Question

Most helpful comment

This makes it on every rebuild ("before"/"when"), but you can't abort a build.

module.exports = (bundler) => {
  bundler.on('buildStart', entryPoints => {
      execSync(tscCommand, { cwd, encoding: 'utf8', stdio: 'inherit' })
  });
}

All 5 comments

Which parcel version are you using?

In Parcel 2 this plugin already exists. Although it doesn't stop the build it runs after it, as a typechecker should probably not block a build.

In Parcel 1 you could just run the command before the build? Actually same in any build tool

(Apart from that, if this is your complete code, you should take another look at how Parcel 1 work, e.g. https://parceljs.org/plugins.html)

I'm running Parcel 1.12.4, which I just installed this morning from the registry, so I assume 2 is in beta?

I personally would prefer a type-checker blocking a build, which would be consistent with other static languages (I can't compile a Java application with the wrong types). I guess that's not a huge deal to me though.

I did see the Parcel 1 plugin docs, but I wasn't sure how to get more information about how to design a plugin from that. It only provides an example that calls two registration methods which aren't applicable to what I'm trying to do.

Also, changing the build command only lets me type-check before a build, but not before every build when I'm in dev mode, watch-and-reloading.

This makes it on every rebuild ("before"/"when"), but you can't abort a build.

module.exports = (bundler) => {
  bundler.on('buildStart', entryPoints => {
      execSync(tscCommand, { cwd, encoding: 'utf8', stdio: 'inherit' })
  });
}

buildStart worked perfectly, thanks!

If anyone happens to be looking for a full list of events, they’re all very neatly defined at https://github.com/parcel-bundler/parcel/blob/23ba2cc54f3286f60e2cab63eb358660c916139d/packages/core/types/index.js

Was this page helpful?
0 / 5 - 0 ratings