With the following code:
if (process.env.NODE_ENV === 'production') {
console.log('Running in production');
} else {
console.log('Running in development');
}
When running parcel build [input], the code console.log('Running in development') is not included in the bundle, and the code console.log('Running in production') is included. This is the expected behavior.
But with the following code:
if (process.env.NODE_ENV === 'production') {
require('./production.js')
} else {
require('./development.js')
}
When running parcel build [input], both the content of ./production.js and ./development.js is included in the bundle.
It seems that excluding the unused code is done during minification, which work for static code, but doesn't work with require as the bundler handled the require before minification.
The code within if (process.env.NODE_ENV === 'production') {...} else {...} should be included in the bundle based on the process.env.NODE_ENV variable.
That would allow to use development tools like react-hot-loader that require different modules in production or development. See /src/index.js.
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.6.2 |
| Node | 9.5.0 |
| npm/Yarn | yarn 1.3.2 |
| Operating System | OSX |
Does the issue also occur when you set the require to a variable, so that the imported stuff actually goes somewhere?
For example, if you change your code to:
if (process.env.NODE_ENV === 'production') {
var app = require(â./production.jsâ)
} else {
var app = require(â./development.jsâ)
}
I also wonder if you get different results using the ES6 import statement
Same problem when I assign the require to a variable.
With ES6 import I don't think I can do a conditional import as the import statement must be at the file top level?
This is an expected result as parcel just walks through all the requires, this might get removed if treeshaking lands as that would recognise itâs unused and remove it
Sent with GitHawk
@DeMoorJasper Oh ya true
@pvdlg Were you asking this specifically for react-hot-loader, or in general? Because Parcel already supports react-hot-loader out of the box. See: React Hot Loader Docs #parcel
Are there other use cases, besides react-hot-loader, where we would want to programmatically evaluate conditionals surrounding require calls? Because implementing it would be _very_ expensive performance-wise, and wouldnât even be needed 99% of the time since most people donât use require in this way.
In my opinion we should keep things the way they are, and simply walk through imports/requires, and then rely on tree shaking to try to remove them like @DeMoorJasper suggested.
If tree shaking doesnât solve this in the future, we can try looking into traversing the AST and trying to extract the nearest conditional statement, or maybe supporting ternary operator expressions within the require (that would be pretty cool actually).
@davidnagli I was asking in general as it's useful to require some libs only in dev.
In the case of react-hot-loader they example in their repo present the same issue: the dev module is included in the production bundle. So I guess "Parcel already supports react-hot-loader out of the box" is a definition somewhat up to interpretation, or at least comes with some caveats. Yes it does work as expected in dev and the modules are hot reloaded preserving the state. But the dev modules are included in the production module.
Are there other use cases, besides react-hot-loader, where we would want to programmatically evaluate conditionals surrounding require calls? Because implementing it would be very expensive performance-wise, and wouldnât even be needed 99% of the time since most people donât use require in this way.
In the react ecosystem it seems there is a lot of libraries that have a dev and a prod mode that relies on process.env.NODE_ENV.
It's the case for react itself or for prop-types and pretty much any react related library.
I don't know about other client side rendering libraries (Angular, Vue etc...) but I wouldn't be surprised if it was the case.
In my opinion we should keep things the way they are, and simply walk through imports/requires, and then rely on tree shaking to try to remove them like @DeMoorJasper suggested.
If tree shaking doesnât solve this in the future, we can try looking into traversing the AST and trying to extract the nearest conditional statement, or maybe supporting ternary operator expressions within the require (that would be pretty cool actually).
If treeshaking does the jobs that's great! Being able to remove the development code of React in production is pretty important. Not doing so would make it really difficult to use Parcel for a React app.
I'm not sure how webpack handles that, but when using create-react-app the dev code is not included in the prod package.
Same problem here.
// in parcel
if (!process.env.BUILD_DEPLOY) {
require('./mock')
}
but the content of './mock' was also inlined into the bundle.js though it was not required.
After some thinking it might actually be a good idea to do this before any minifying or treeshaking as it would improve performance, as all the unused code doesnât need any processing if it never gets imported in the first place. It shouldnât be hard to implement, I might look into it if i find the time
Sent with GitHawk
Fixed by #1166.
Most helpful comment
@davidnagli I was asking in general as it's useful to
requiresome libs only in dev.In the case of
react-hot-loaderthey example in their repo present the same issue: the dev module is included in the production bundle. So I guess "Parcel already supports react-hot-loader out of the box" is a definition somewhat up to interpretation, or at least comes with some caveats. Yes it does work as expected in dev and the modules are hot reloaded preserving the state. But the dev modules are included in the production module.In the react ecosystem it seems there is a lot of libraries that have a dev and a prod mode that relies on
process.env.NODE_ENV.It's the case for react itself or for prop-types and pretty much any react related library.
I don't know about other client side rendering libraries (Angular, Vue etc...) but I wouldn't be surprised if it was the case.
If treeshaking does the jobs that's great! Being able to remove the development code of React in production is pretty important. Not doing so would make it really difficult to use Parcel for a React app.
I'm not sure how
webpackhandles that, but when usingcreate-react-appthe dev code is not included in the prod package.