NOTE: This proposal is dead. A simpler solution was arrived at via the new `:bundle` target.
The current Webpack solution works reasonable well for application oriented development, but does not address the wider issue of developing ClojureScript libraries that depend on the wider JavaScript ecosystem where the artifacts do not reside in Java-centric distrubtion like Maven (i.e. NPM). Currently a ClojureScript library cannot express these kinds of foreign library dependencies at all. Thus users must constantly redefine basic dependencies from NPM such as React, boilerplate Webpack configuration, boilerplate import/export files, and thus cannot create and share reusable ClojureScript components that depend on this vast ecosystem.
ClojureScript actually has nearly all of the pieces to solve this problem today due to prior work around :npm-deps
, as well as :foreign-libs
changes to support community distribution efforts like CLJSJS.
Allow users to create deps.cljs
file in their artifact that expresses which Node dependencies they need. Previously :npm-deps
was only for describing which NPM artifacts to install and which libraries to index ultimately for Closure compiler. We can extend this to allow :npm-deps
to be combined with :foreign-libs
. This can be done simply by extending the way we handle the :foreign-libs
:file
key. Instead of supplying a file, users can specify a special keyword - :bundle
. This can communicate that this file doesn't yet exist and will be constructed by some other tool.
We will also extend :global-exports
to support a more expressive syntax.
{cljs-react "react"}
{cljs-foo {* "foo"}}
{cljs-bar {[Foo Baz] "bar"}}
This extension allows us to generate the required index.js
files for Webpack and provides enough flexiblity for users to reshape existing libraries into a more idiomatic shape for ClojureScript consumption.
Finally we will supply a new compiler option :bundle-fn
a symbol that will take the the deep merged :file :bundle
foreign lib entries. This deep merged foreign lib entry is exactly what users are doing manually by hand today.
We will supply a default :bundle-fn
, cljs.webpack/bundle
which will take this foreign lib entry and automatically generate the index.js
files as well as the webpack.config.js
file and then invoke webpack
. We could supply :bundle-args
to supply other useful flags (i.e. development, production).
Note this design isn't actually tied in anyway to webpack. If some other popular tool comes along, users can easily accomodate that by supplying their own :bundle-fn
. At the same this proposal makes it easy to handle other kinds of assets like image and stylesheets via Webpack in a reusable way.
No, this problem was solved in a simpler way with the
:bundle
target.