Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update default Closure option :output-wrapper true #201

Closed
lynaghk opened this issue May 10, 2013 · 9 comments
Closed

Update default Closure option :output-wrapper true #201

lynaghk opened this issue May 10, 2013 · 9 comments
Milestone

Comments

@lynaghk
Copy link

lynaghk commented May 10, 2013

Take it from a man who just lost an hour discovering one global minified function intermittently clobbering another, depending on JS load order: the Closure compiler should use :output-wrapper true by default.
That is, the emitted JS should be wrapped in a function so that it doesn't define vars in the global scope.
It costs a few bytes (enough to write an extra function(){}()) but may save a lot of people their sanity.

You can always override the default back to :output-wrapper false if you control the page.

@emezeske
Copy link
Owner

Is this an existing option to the ClojureScript compiler somewhere? I poked around a little bit but was unable to find it. I can definitely feel your pain...

@lynaghk
Copy link
Author

lynaghk commented May 11, 2013

Oh, my mistake; the ClojureScript compiler option is :output-wrapper true: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L927

@emezeske
Copy link
Owner

Ah, cool, thanks.

Thinking about this: is changing the default valued to true a backwards-compatibility problem? Couldn't this break existing code that relies on calling unmangled (e.g. simple output) function names? Or am I wrong about that?

@emezeske
Copy link
Owner

I added a note about this option's existence and its default value of false to the sample.project.clj file for now. I am totally onboard with making it the default, but that would probably need to be in a major release, with some accompanying documentation, and maybe a warning or something (unless I'm wrong about backwards compat issues).

@lynaghk
Copy link
Author

lynaghk commented May 12, 2013

Hmm, that's a good point about the simple optimizations crowd.

For adv optimizations, it'd only break existing code if people are relying on the arbitrary, minified function names emitted by Closure from another JS file, which is highly highly unlilkely (because it's crazy).
If people are using Closure advanced optimizations, they're already marking the fns they care about with ^:export true metadata, which will not be affected by this by this change.

We could flip the default depending on the optimizations flag, but it'd probably be simpler to wait until the next major version number since it is potentially breaking.
After all, I already got burned so we're putting it in all of our projects explicitly =)

@emezeske
Copy link
Owner

Sounds good. I think the simple approach of just enabling it by default for everyone is fine, but I think I'll put in a temporary (a release or two) warning message that will only be printed when simple optimizations are in use.

@cemerick
Copy link
Collaborator

@lynaghk Just to clarify, the problem only manifests if a page loads two advanced-compiled JavaScript files whose contents are not so wrapped?

Is this change one that should be effected in ClojureScript, rather than here?

@lynaghk
Copy link
Author

lynaghk commented Aug 29, 2013

@cemerick Not just adv-compiled, but could be any unwrapped JavaScript.
This is a longstanding problem with JS promoting vars to the global scope unless explicitly prevented from doing so via wrapping; most JS devs and libraries are familiar with it and wrap appropriately.
I think the only reason Closure doesn't do it by default is because they assume all JS on the page goes through it and leaving stuff unwrapped saves you 10 bytes or whatever (which you care about if you're The Google).

@cemerick
Copy link
Collaborator

Sure, sure.

I'm down with defaulting :output-wrapper true for advanced-mode compilation for a 1.0.0 release, and then always to true regardless of compilation level for a currently-theoretical breaking-OK 2.0.0 release. Pull req for the former welcome.

rm-hull added a commit to rm-hull/lein-cljsbuild that referenced this issue Oct 21, 2013
Merge branch 'master' of https://github.com/emezeske/lein-cljsbuild

* 'master' of https://github.com/emezeske/lein-cljsbuild: (45 commits)
  0.3.4
  final 0.3.4 release notes
  auto-discover version of lein-cljsbuild being used, fixes emezeskegh-242
  fail test subtask if any :test-command vector contains non-string values, fixes emezeskegh-243
  0.3.4 release notes draft
  Let hard compilation failures (i.e. failures loading Clojure files) fail the broader build (emezeskegh-234)
  Default :output-wrapper to true when :optimizations = :advanced, fixes emezeskegh-201
  bump cljsbuild-version in subproject => 0.3.4-SNAPSHOT (ref emezeskegh-242)
  orphaned release notes?
  Handle case-sensitivity, fixes emezeske#240
  Add new "sample" task
  update release notes
  0.3.4-SNAPSHOT
  0.3.3
  separate deploy script
  add README admonition re: explicit cljs deps, add explicit dep to example projects, fixes emezeskegh-228
  don't include paths in :output-dir or the :output-to path when watching for changes
  Reimplement `find-files` w/o using the "fs" library (too slow), fixes emezeskegh-219
  emit warning when user's project does not contain an explicit ClojureScript dependency, fixes emezeskegh-224
  0.3.3-SNAPSHOT
  ...

Conflicts:
	doc/RELEASE-NOTES.md
	plugin/project.clj
	plugin/src/leiningen/cljsbuild.clj
	support/project.clj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants