webpacker: assets:compile doesn't respect NODE_ENV

It seems that NODE_ENV=development bundle exec rails assets:precompile ignores NODE_ENV environment variable.

In order to confirm the problem, I added simple debug code to config/webpack/production.js

+if (process.env.NODE_ENV === 'production') {
+  throw 'NODE_ENV: ' + process.env.NODE_ENV;
+}
 process.env.NODE_ENV = process.env.NODE_ENV || 'production'

And here is the result.

/Users/mito/work/webpacker-test% NODE_ENV=development bundle exec rails assets:precompile
yarn install v1.5.1
[1/4] šŸ”  Resolving packages...
success Already up-to-date.
āœØ  Done in 1.25s.
Webpacker is installed šŸŽ‰ šŸ°
Using /Users/mito/work/webpacker-test/config/webpacker.yml file for setting up webpack paths
Compilingā€¦
Compilation failed:


/Users/mito/work/webpacker-test/config/webpack/production.js:2
  throw 'NODE_ENV: ' + process.env.NODE_ENV;
  ^
NODE_ENV: production

In spite of NODE_ENV=development, process.env.NODE_ENV is production. Probably, itā€™s caused by this line https://github.com/rails/webpacker/blob/master/lib/tasks/webpacker/compile.rake#L24

This is a repository which includes the reproducing code. https://github.com/y310/webpacker-test

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 38 (21 by maintainers)

Most upvoted comments

Yeah, this is very misleading in the docs, if you run:

RAILS_ENV=staging bundle exec rails assets:precompile

This will load config/webpack/production.js

There is no way to assets:precompile against anything other than config/webpack/production.js because it is hard-coded to 'production' in https://github.com/rails/webpacker/blob/master/lib/tasks/webpacker/compile.rake#L22

I want to run NODE_ENV=staging and use that to point my bundle to a different API endpoint used in staging vs production. That is my use case, and it seems odd that assets:precompile does not honour NODE_ENV.

@gauravtiwari - We have spent hours debugging the above bug, since it directly contradicts the Custom Rails Environments instructions for this gem, which state that NODE_ENV can force assets:compile to compile in development mode:

# compiles in production mode by default unless NODE_ENV is specified
bundle exec rails assets:precompile
bundle exec rails webpacker:compile

If one has to use assets:precompile, is it possible to compile in development mode?

Hey @jakeNiemiec, whatā€™s the high-level rationale for restricting NODE_ENV to only production/development rather than respecting the NODE_ENV passed by the developer?

Iā€™m not even getting to the part of running the tests because of this behavior! bundle exec rails assets:precompile crashes because initializers that shouldnā€™t be invoked are crashing due the problems described above. Same with bundle exec rails webpacker:precompile.

The only thing that works to even get into the testing phase is running bin/webpacker which allows us to bypass this entire mess.

When our applications are running in production mode, they need to call specific endpoints to register themselves. Only in production mode, because for the other environments, we simply donā€™t care.

With this issue from webpacker, this causes our tests in CI to simply crash because either the endpoint they need to call is not available/reachable, or they donā€™t have the required environment variables available to make these calls.

Why? Because webpacker decides to load production.js and the production configuration because of this issue, something thatā€™s not wanted at all when running explicitly in a testing environment.

So right now we have the following choices:

  • Donā€™t use webpacker whatsoever ever
  • Put a lot of if statements in our production configuration files to detect whether weā€™re running under a CI environment and skip sections
  • Refactor the entire sections of our code that perform this to not be loaded by webpacker.

Right now weā€™re seriously going with option one if this is the behavior webpacker will be keeping.

@coding-bunny Iā€™ve adjusted my process to have NODE_ENV to only ever be equal to ā€œdevelopmentā€ or ā€œproductionā€, and to only be used for whether the bundle is in ā€œdevelopment modeā€, or for the case of prod or CI, the minified / bundled version

Iā€™m inlining a client side API key with webpack / node-config (option 1 here) when I build my Docker image. The key must be different in QA / Prod environments.

But since NODE_ENV=qa isnā€™t respected, I get the prod key in both environments. It would be nice if webpacker recognized more environments than prod/dev.

@jakeNiemiec Also from the docs:

And, this will compile in development mode and load configuration for cucumber environment if defined in webpacker.yml or fallback to production configuration

RAILS_ENV=cucumber NODE_ENV=development bundle exec rails assets:precompile

This isnā€™t true. Running bundle exec rails assets:precompile is going to ignore NODE_ENV and always use NODE_ENV=production.

The ā€œPlease note, NODE_ENV can either be set to production, development or testā€ and the example of specifying NODE_ENV=development and running the asset precompile lead you to believe specifying NODE_ENV does something. However, with the hardcoded production NODE_ENV in the webpacker:compile rake task, this isnā€™t the case.

@csalvato What happens if you run yarn install? I guess since yarn install is being run in production mode itā€™s stripping off all the dev dependencies. Btw, what environment is this - CI?

@gauravtiwari This is the output:

$ yarn install
yarn install v1.10.0
[1/5] šŸ”  Validating package.json...
[2/5] šŸ”  Resolving packages...
[3/5] šŸšš  Fetching packages...
[4/5] šŸ”—  Linking dependencies...
warning "@rails/webpacker > postcss-cssnext@3.1.0" has unmet peer dependency "caniuse-lite@^1.0.30000697".
warning " > at.js@1.5.3" has incorrect peer dependency "jquery@^1.7.0".
warning " > pdfjs-dist@2.0.428" has unmet peer dependency "webpack@^2.0.0 || ^3.0.0".
warning "pdfjs-dist > worker-loader@1.1.1" has unmet peer dependency "webpack@^2.0.0 || ^3.0.0 || ^4.0.0".
warning " > rails-erb-loader@5.2.1" has unmet peer dependency "webpack@^2.0.0 || >= 3.0.0-rc.0 || ^3.0.0".
warning " > vue-loader@13.7.3" has unmet peer dependency "css-loader@*".
warning " > karma-webpack@2.0.6" has unmet peer dependency "webpack@^1.0.0 || ^2.0.0 || ^3.0.0".
warning "karma-webpack > webpack-dev-middleware@1.12.2" has unmet peer dependency "webpack@^1.0.0 || ^2.0.0 || ^3.0.0".
warning " > webpack-dev-server@2.11.2" has unmet peer dependency "webpack@^2.2.0 || ^3.0.0".
[5/5] šŸ“ƒ  Building fresh packages...
āœØ  Done in 31.92s.

Btw, what environment is this - CI?

Local dev environment. Not CI.

@csalvato Can you double check that eslint-friendly-formatter is not under devDependancies in your package.json file? If so, try to move it to dependancies or make sure it is not include in production code (at require (internal/module.js:11:18)). More discussion of that in #1212

Moving it to dependencies enabled NODE_ENV=development ./bin/webpack to work, and compiled the dev version šŸ‘