From d9ad7740ecf176c0c82943898b4abb5d3c6df81b Mon Sep 17 00:00:00 2001 From: Dan Holmsand Date: Sat, 10 Oct 2015 12:37:58 +0200 Subject: [PATCH] Make it easier to use with webpack and node Demo and tests now can run with webpack-generated React Use js/require, to make Reagent work better with node --- .gitignore | 6 +++++- Makefile | 18 ++++++++++++++++++ bin/gen-site.js | 3 ++- lib/modules.js | 15 +++++++++++++++ package.json | 13 +++++++++++++ project.clj | 9 +++++++++ src/reagent/dom.cljs | 5 ++++- src/reagent/dom/server.cljs | 6 +++++- src/reagent/impl/component.cljs | 1 + src/reagent/impl/util.cljs | 5 ++++- webpack.config.js | 23 +++++++++++++++++++++++ 11 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 lib/modules.js create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index e25f1f0..d29efbc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,8 @@ figwheel_server.log reagent.iml .idea -.lein-failures \ No newline at end of file +.lein-failures + +outsite/bundle.js +outsite/bundle.min.js +node_modules diff --git a/Makefile b/Makefile index e8503e0..61e8ce1 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,10 @@ run: figwheel runsite: @$(MAKE) run PROF=+site,$(PROF) +# development build with auto-reloading and webpacked source +runpack: target/webpack/bundle.js + @$(MAKE) run PROF=+webpack,$(PROF) + # development build with figwheel, but no tests runnotest: @$(MAKE) run PROF=+dev-notest,$(PROF) @@ -25,6 +29,10 @@ runnotest: runprod: clean @$(MAKE) serve-site PROF=prod,$(PROF) +# production build with auto-rebuild and webpacked source +runprodpack: clean target/webpack/bundle.js + @$(MAKE) serve-site PROF=prod,webpack,$(PROF) + # production build with auto-rebuild and testing runprodtest: clean @$(MAKE) serve-site PROF=prod-test,$(PROF) @@ -90,6 +98,16 @@ gh-pages-add: git push && rm -rf .git tmp +## Webpack +########## + +target/webpack/bundle.js: node_modules lib/modules.js package.json Makefile + npm run bundle + +node_modules: + npm install + + ## Misc utilities ################# diff --git a/bin/gen-site.js b/bin/gen-site.js index 2518c3d..e9c440d 100755 --- a/bin/gen-site.js +++ b/bin/gen-site.js @@ -12,7 +12,6 @@ if (typeof location === "undefined") { // for some reason global.location = {}; } - var gensite = function () { console.log("Loading " + srcFile); var optNone = cljsLoad.load(srcFile, outputDirectory, devFile); @@ -27,6 +26,8 @@ var compileFail = function () { } }; +process.env.NODE_ENV = "production"; + if (!compileFail()) { try { gensite(); diff --git a/lib/modules.js b/lib/modules.js new file mode 100644 index 0000000..09f4398 --- /dev/null +++ b/lib/modules.js @@ -0,0 +1,15 @@ + + +function exported_require (name) { + switch (name) { + case "react": return require("react"); + case "react-dom": return require("react-dom"); + case "react-dom/server": return require("react-dom/server"); + default: + console.error("Unknown module: ", name); + } +} + +if (!global.require) { + global.require = exported_require; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8a353cf --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "dependencies": { + "react": "^0.14.0", + "react-dom": "^0.14.0" + }, + "scripts": { + "bundle": "webpack && NODE_ENV=production webpack -p" + }, + "devDependencies": { + "babel-core": "^5.8.25", + "webpack": "^1.12.2" + } +} diff --git a/project.clj b/project.clj index a99bd19..3bbc64a 100644 --- a/project.clj +++ b/project.clj @@ -50,6 +50,15 @@ ;; :pseudo-names true :output-dir "target/client"}}}}}] + :webpack {:cljsbuild + {:builds {:client + {:compiler + {:foreign-libs + [{:file "target/webpack/bundle.js" + :file-min "target/webpack/bundle.min.js" + :provides ["cljsjs.react.dom" + "cljsjs.react"]}]}}}}} + :prod-test [:test :prod] :dev-notest [:dev diff --git a/src/reagent/dom.cljs b/src/reagent/dom.cljs index bb9d1c3..7e731ce 100644 --- a/src/reagent/dom.cljs +++ b/src/reagent/dom.cljs @@ -5,7 +5,10 @@ [reagent.debug :refer-macros [dbg]] [reagent.interop :refer-macros [.' .!]])) -(def react-dom js/ReactDOM) +(defonce react-dom (or (and (exists? js/ReactDOM) + js/ReactDOM) + (and (exists? js/require) + (js/require "react-dom")))) (assert react-dom) (defonce ^:private roots (atom {})) diff --git a/src/reagent/dom/server.cljs b/src/reagent/dom/server.cljs index f631e7f..35f63c2 100644 --- a/src/reagent/dom/server.cljs +++ b/src/reagent/dom/server.cljs @@ -5,7 +5,11 @@ [reagent.interop :refer-macros [.' .!]])) ;; TODO: Where the hell is ReactDOMServer? -(def react-dom-server js/React) +(defonce react-dom-server (or (and (exists? js/ReactDOMServer) + js/ReactDOMServer) + (and (exists? js/require) + (js/require "react-dom/server")) + js/React)) (assert react-dom-server) (defn render-to-string diff --git a/src/reagent/impl/component.cljs b/src/reagent/impl/component.cljs index bb4097f..4e17f3a 100644 --- a/src/reagent/impl/component.cljs +++ b/src/reagent/impl/component.cljs @@ -250,6 +250,7 @@ name) fmap (assoc fmap :displayName name + :autobind false :cljsLegacyRender legacy-render :reagentRender render-fun :render (:render static-fns))] diff --git a/src/reagent/impl/util.cljs b/src/reagent/impl/util.cljs index d2da3e9..f04647a 100644 --- a/src/reagent/impl/util.cljs +++ b/src/reagent/impl/util.cljs @@ -4,7 +4,10 @@ [reagent.interop :refer-macros [.' .!]] [clojure.string :as string])) -(def react js/React) +(defonce react (or (and (exists? js/React) + js/React) + (and (exists? js/require) + (js/require "react")))) (assert react) (def is-client (and (exists? js/window) diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..547c35b --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,23 @@ +var path = require('path'); +var webpack = require('webpack'); + +var prod = process.env.NODE_ENV === "production"; + + + +module.exports = { + entry: './lib/modules.js', + output: { + path: "./target/webpack/", + filename: prod ? 'bundle.min.js' : 'bundle.js' + }, + module: { + loaders: [ + { test: /.jsx?$/, loader: 'babel-loader', include: "./lib" } + ] + }, + plugins: [ + new webpack.DefinePlugin( + {'process.env': { 'NODE_ENV': prod ? '"production"' : '"development"'}}) + ] +}