Parcel: Allow presets to override built-in plugins

Created on 27 Dec 2018  ยท  4Comments  ยท  Source: parcel-bundler/parcel

๐Ÿ› bug report

I was attempting to use parcel with a react project using Emotion v10, a CSS-in-JS library. Emotion recommends using a preset which configures several plugins to enable a custom jsx pragma, per https://emotion.sh/docs/css-prop#babel-preset. However, when using this with parcel, parcel's default configuration for compiling jsx files doesn't seem to respect the configuration inside the preset. I ended up copy/pasting the plugin configuration from the preset into my plugins configuration in .babelrc:

  "plugins": [
    // Copy/pasta the config in @emotion/babel-preset-css-prop to override parcel's default.
    // Without this, parcel will default to using the one in transforms/babel/jsx
    ["@babel/plugin-transform-react-jsx", {
      "pragma": pragmaName, // default pragma is React.createElement
      "pragmaFrag": "React.Fragment", // default is React.Fragment
    }]
  ]

which did work.

๐ŸŽ› Configuration (.babelrc, package.json, cli command)

full config:

// copy/pasta from @emotion/babel-preset-css-prop
var pragmaName = '___EmotionJSX';
module.exports = {
  "presets": ["@emotion/babel-preset-css-prop"],
  "plugins": [
    "transform-inline-environment-variables",
    // Copy/pasta the config in @emotion/babel-preset-css-prop to override parcel's default.
    // Without this, parcel will default to using the one in transforms/babel/jsx
    ["@babel/plugin-transform-react-jsx", {
      "pragma": pragmaName, // default pragma is React.createElement
      "pragmaFrag": "React.Fragment", // default is React.Fragment
    }]
  ]
}

๐Ÿค” Expected Behavior

I shouldn't need to override the plugin; it should be able to be overridden from the preset.

๐Ÿ˜ฏ Current Behavior

I do need to override it.

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.11.0
| Node | 10.14.2
| npm | 6.4.1
| Operating System | osx

Bug babel โœจ Parcel 2

Most helpful comment

I've made a PR for fixing the JSX pragma overwriting (only tests are missing). Due to emotion's unusual process.env.NODE_ENV injection (why don't they already respect the value when the plugin runs?), this should work for you if the PR gets merged:

{
  "presets": ["@emotion/babel-preset-css-prop"],
  "plugins": ["transform-node-env-inline"]
}

EDIT:
transform-node-env-inline is needed because of https://github.com/parcel-bundler/parcel/issues/2237

All 4 comments

Each time I try Parcel I am able to use it longer and longer before I need to switch to Webpack. Previous attempts had me abandoning the effort within an hour or a day. This time it took a full month before I reached a dead end. That's some great progress, and the takeaway is that Parcel's a great tool that is usable for many real-world projects.

This issue, however, is that dead end that will force me to switch.

I can't bring myself to use that ugly Babel config. At this point a custom Webpack config is simpler and looks a lot better in a pull request. Shame, because I don't like Webpack much. Hah.

The corresponding Emotion issue, https://github.com/emotion-js/emotion/issues/1132, is pretty black and white that the blame for the error lies with Parcel's non-standard application of babel plugins. To be fair, Emotion's build complexity doesn't help.

Thanks for the hard work, and I'll be back on the next project.

Previous attempts had me abandoning the effort within an hour or a day. This time it took a full month before I reached a dead end.

Exponential growth, promising ๐Ÿ˜„

~@alflennik Could you please share a minimal reproduction and the exact error/bug you're getting/experiencing?~ I think I've got it

is pretty black and white that the blame for the error lies with Parcel's non-standard application of babel plugins

I can say one thing about their babel plugin as well: it seems to be the first plugin so far that actually injects process.env.NODE_ENV into the generated code (currently resulting in Uncaught ReferenceError: process is not defined at runtime). We would have noticed this already if other plugins did that.

I've made a PR for fixing the JSX pragma overwriting (only tests are missing). Due to emotion's unusual process.env.NODE_ENV injection (why don't they already respect the value when the plugin runs?), this should work for you if the PR gets merged:

{
  "presets": ["@emotion/babel-preset-css-prop"],
  "plugins": ["transform-node-env-inline"]
}

EDIT:
transform-node-env-inline is needed because of https://github.com/parcel-bundler/parcel/issues/2237

Thanks so much for the speedy work and I really hope that PR lands!

It will also resolve this issue: https://github.com/parcel-bundler/parcel/issues/2237
And the issue from Emotion: https://github.com/emotion-js/emotion/issues/1132

Was this page helpful?
0 / 5 - 0 ratings