rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.37k stars 195 forks source link

Please clarify the docs regarding when dev/prod modes are on (Node) #50

Open holyjak opened 9 years ago

holyjak commented 9 years ago

Hello,

perhaps it wasn't my brightest day :-) but I found it difficult to find out when the dev or prod modes are active under Node.js. It would be great clarify that in the docs.

I believe this is true (and exhaustive) but am not sure:

/*1.*/ var Immutable = require('seamless-immutable'); // => dev mode
/*2.*/ var Immutable = require('seamless-immutable/seamless-immutable.production.min'); // => prod mode
/*3.*/ var Immutable = require('seamless-immutable/seamless-immutable.production.min'); process.env.NODE_ENV = "development"; // => dev mode

Thank you!

rtfeldman commented 9 years ago

Not sure I follow the question - we just use process.env.NODE_ENV in the source to hook into envify when generating the production and development builds.

I can totally see explaining how that works in the source, because I can see how that would be unclear. Is that what you are referring to?

holyjak commented 9 years ago

Hello, my question is: In Node, what are the ways to switch on the dev or the prod mode?

I have seen the NODE_ENV in the code without really understand when it is effective so likely the line 3 isn't true.

rtfeldman commented 9 years ago

I still don't quite follow. This is how you do it for Node in general, but in the specific case of seamless-immutable, it's only used by envify when building the development and production builds.

You won't see NODE_ENV in the outputted development build or production build, because envify strips it out. Does that clarify?

oliverwoodings commented 9 years ago

I believe what @jakubholynet means is how do you switch between using the dev build and and production build. The package.json file for seamless-immutable points to the development build, which in my opinion is not ideal. Really it should point to the actual source. If users want to perform optimisations based on environment (i.e. using envify or webpack's define plugin), they should be able to do it themselves in their build step. This is how React does it and it works well; it gives the developer the power to choose.

To answer @jakubholynet 's question, if you are using webpack you can alias seamless-immutable to get different builds. Personally I have my webpack config set up like so:

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": '"' + (process.env.NODE_ENV || "development") + '"'
    })
  ],
  resolve: {
    alias: {
      "seamless-immutable$": path.resolve(__dirname, "node_modules/seamless-immutable/src/seamless-immutable.js")
    }
  }
};
rtfeldman commented 9 years ago

Thanks for clarifying! A few thoughts:

  1. The current source can't be used in development or production on a normal web page, as until envify has been done, references to process.env will still be around waiting to break. So I don't think that's the right default at the moment.
  2. Not everyone needs the performance optimizations provided by "prod mode," but this is a library built around strong guarantees of immutability, so I think the default should be that those strong guarantees are enforced. They are enforced in the development build, but not in the production build, so I think the development build is the better default.
  3. I haven't looked at that part of React's source, but I'm guessing they code defensively around process.env so that things won't break if envify hasn't been run. I'm open to that approach so long as the post-envify, post-uglify production build doesn't end up with any lingering unnecessary checks as a result. This isn't a priority for me, but a PR would certainly be welcome!
oliverwoodings commented 9 years ago

Yeah so what they do in React is something like this:

var __DEV__ = process && process.env && process.env.NODE_ENV === "development";
var __PROD__ = process && process.env && process.env.NODE_ENV === "production";

if (__DEV__) {
  //do dev-only stuff
}

The envify-uglify combo will cause all those conditional statements to be removed in production, so no lingering checks.

I'll see if i can get a PR in some time!

rtfeldman commented 9 years ago

Sounds good! :+1:

holyjak commented 9 years ago

Sorry for a late response. Thanks, @oliverwoodings, for the clarifying on my behalf and for the response. I was interested both in being able to switch between dev/prod manually (depending on what I require) and in a build step. I have the answers I need but perhaps they should be included in the docs [more visibly] as well? Thank you all!

mheiber commented 8 years ago

Thanks for the Webpack example. How can I specify which build to use using Browserify?

tleunen commented 7 years ago

If your webpack configuration uses the default mainFields, or use defaults values, with browser first before main, the development build from seamless-immutable will be used, even though you set NODE_ENV to prod.

See https://webpack.js.org/configuration/resolve/#resolve-mainfields

The default target of webpack is web, so therefore, every use will use the development version by default.