Parcel: postcss fails to read NODE_ENV correctly

Created on 30 Apr 2020  ยท  8Comments  ยท  Source: parcel-bundler/parcel

๐Ÿ› bug report

When running parcel watch / serve and even when I add NODE_ENV=development variable before running command it still reads process.env.NODE_ENV is production.

I have console log in my .postcss and it prints production no matter what I do.

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

    "build": "parcel build '.tmp/parcel/**/index.html' --cache-dir .tmp/.cache",
    "build:dev": "NODE_ENV=development parcel build '.tmp/parcel/**/*.html' --cache-dir .tmp/.cache",
    "watch": "parcel watch '.tmp/parcel/**/*.html' --cache-dir .tmp/.cache",
    "watch:dev": "NODE_ENV=development parcel watch '.tmp/parcel/**/*.html' --cache-dir .tmp/.cache",
    "serve": "parcel serve --port 3000 '.tmp/parcel/**/*.html' --cache-dir .tmp/.cache",
    "serve:dev": "NODE_ENV=development parcel serve --port 3000 '.tmp/parcel/**/*.html' --cache-dir .tmp/.cache",
{
    "presets": [
        "@babel/preset-env", {
            "include": ["@babel/plugin-transform-strict-mode" ]
      }]
}



md5-bd95d0666822cf5288b1c50071e7127c



console.log('.postcssrc', process.env.NODE_ENV)

const purgecss = require('@fullhuman/postcss-purgecss')({
  content: ['.tmp/parcel/**/*.html'],
  // Include any special characters you're using in this regular expression
  defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:\.\/]+/g) || [],
})

module.exports = {
  plugins: [
    require('postcss-easy-import'),
    require('tailwindcss')('./pages/assets/css/tailwind.config.js'),
    require('autoprefixer'),
    ...(process.env.NODE_ENV === 'production' ? [purgecss] : []),
  ],
}

check npm scripts
https://github.com/danielstaleiny/minimal-example-parcel2

๐Ÿค” Expected Behavior

parcel should have NODE_ENV 'development' when running watch / serve mode and when setting up in cli NODE_ENV environment.

๐Ÿ˜ฏ Current Behavior

parcel build -> nothing is printed from .postcss??
NODE_ENV=development -> nothing is printed .postcss??
parcel watch -> .postcss production
NODE_ENV=development parcel watch -> .postcss production
parcel serve -> .postcss production
NODE_ENV=development parcel serve -> .postcss production

๐Ÿ’ Possible Solution

Propagate NODE_ENV variable correctly to postcss

๐Ÿ”ฆ Context

runs purge when it is not needed.

๐Ÿ’ป Code Sample

https://github.com/danielstaleiny/minimal-example-parcel2

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | "parcel": "^2.0.0-nightly.240",
| Node | v10.17.0
| npm/Yarn | 6.11.3
| Operating System | NixOS unstable (20.03)

Bug Confirmed Bug โœจ Parcel 2

Most helpful comment

I'm experiencing this issue with Tailwind CSS, which also does a purge when NODE_ENV is production

All 8 comments

There is example of using env variable on bottom of the README.md
https://github.com/postcss/postcss-cli
They are parsing NODE_ENV with ctx variable but when I tried it. Parcel complain that it is not an object but function.

Do we have a possible starting point to fix this issue? I want to dig further in. I was using the latest alpha version, and upon switching to the recent beta I've started experiencing the same. I don't really know what may have changed that it's now causing initial NODE_ENV to not be passed properly through the whole pipeline.

The JS config is "executed" here: https://github.com/parcel-bundler/parcel/blob/d19bee10bef6b611c02ef8af8b40101bb0a238cf/packages/core/utils/src/config.js#L87

Problems I've discovered just now:

  1. (The file is required so when it is changed in watch mode, require() returns the same result. The cache needs to be cleared with something like delete require.cache[configFile])
  2. (Before calling this require(), the value in options.env.NODE_ENV should be loaded into process.env (and reverted?))
  3. This line causes the config to be reevaluated even if it's contents didn't change (e.g. env vars): https://github.com/parcel-bundler/parcel/blob/d19bee10bef6b611c02ef8af8b40101bb0a238cf/packages/transformers/postcss/src/loadConfig.js#L86
    The config is indeed reevaluated (and it is different), but the asset isn't transformed again (so somehow Parcel has decided that the config didn't change at all?):
    https://github.com/parcel-bundler/parcel/blob/d19bee10bef6b611c02ef8af8b40101bb0a238cf/packages/transformers/postcss/src/PostCSSTransformer.js#L50
  4. requires in the JS config to missing modules should throw an error, but these are swallowed here:
    https://github.com/parcel-bundler/parcel/blob/d19bee10bef6b611c02ef8af8b40101bb0a238cf/packages/core/utils/src/config.js#L110

cc @DeMoorJasper @padmaia

Any workarounds for this issue? I don't fancy turning purge on/off and deleting cache manually whenever I need to publish. ๐Ÿ˜ญ

I'm experiencing this issue with Tailwind CSS, which also does a purge when NODE_ENV is production

Came here for the same reason..
I was pulling my here to understand what was going on..
The valur that's read is not undefined though..
So from where production is coming?

Does anyone find a workaround for Tailwind?

Running into the same issue - I think it's caused by what's described in #5029.

I had issues with tailwind as well for the longest time. I decided to do a diff between process.env in build & dev mode. Turns out there's a variable called npm_lifecycle_event that seems to contain the name of the npm script that's running. You can essentially use this as your hook to know whether you are in dev mode or not.

For instance say you have the following scripts in your package.json :

{
    ...,
    "scripts": {
        "dev": "parcel src/index.html",
        "build": "parce build src/index.html"
    },
    ...
}

and the following in your tailwind.config.js

// This will be equal to the current running script "build" | "dev"
const isProd = process.env["npm_lifecycle_event"] === "build";

module.exports = {
  purge: {
    enabled: isProd,
    mode: "layers",
    layers: ["base", "components", "utilities"],
    content: ["src/**/*.html", "src/**/*.tsx"],
  },
};

This will build with purge mode when you execute the build command and leave as is with dev script.

More information can be found here: https://medium.com/@brianhan/use-this-npm-variable-as-a-flag-for-your-build-scripts-31069f5e2e57

Hope that helps!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

algebraic-brain picture algebraic-brain  ยท  3Comments

jzimmek picture jzimmek  ยท  3Comments

donaldallen picture donaldallen  ยท  3Comments

medhatdawoud picture medhatdawoud  ยท  3Comments

mnn picture mnn  ยท  3Comments