Remove cljsjs dependency for module processing build

This commit is contained in:
Juho Teperi 2020-04-13 13:45:13 +03:00
parent 1e14521112
commit f7620fd21b
6 changed files with 193 additions and 26 deletions

166
npm_react.ext.js Normal file
View File

@ -0,0 +1,166 @@
// Extern file for React with Node module processing
//
// Compared to Cljsjs extern, this doesn't contain the public API, which
// can be optimized here. This just fixes the React
// internal methods and properties that are created dynamically.
//
// TODO: Package separately and remove these from Cljsjs externs?
/**
* React event system creates plugins and event properties dynamically.
* These externs are needed when consuming React as a JavaScript module
* in light of new ClojureScript compiler additions (as of version 1.9.456).
* See the following link for an example.
* https://github.com/facebook/react/blob/c7129c/src/renderers/dom/shared/eventPlugins/SimpleEventPlugin.js#L43
*/
var ResponderEventPlugin;
var SimpleEventPlugin;
var TapEventPlugin;
var EnterLeaveEventPlugin;
var ChangeEventPlugin;
var SelectEventPlugin;
var BeforeInputEventPlugin;
var bubbled;
var captured;
var topAbort;
var topAnimationEnd;
var topAnimationIteration;
var topAnimationStart;
var topBlur;
var topCancel;
var topCanPlay;
var topCanPlayThrough;
var topClick;
var topClose;
var topContextMenu;
var topCopy;
var topCut;
var topDoubleClick;
var topDrag;
var topDragEnd;
var topDragEnter;
var topDragExit;
var topDragLeave;
var topDragOver;
var topDragStart;
var topDrop;
var topDurationChange;
var topEmptied;
var topEncrypted;
var topEnded;
var topError;
var topFocus;
var topInput;
var topInvalid;
var topKeyDown;
var topKeyPress;
var topKeyUp;
var topLoad;
var topLoadedData;
var topLoadedMetadata;
var topLoadStart;
var topMouseDown;
var topMouseMove;
var topMouseOut;
var topMouseOver;
var topMouseUp;
var topPaste;
var topPause;
var topPlay;
var topPlaying;
var topProgress;
var topRateChange;
var topReset;
var topScroll;
var topSeeked;
var topSeeking;
var topStalled;
var topSubmit;
var topSuspend;
var topTimeUpdate;
var topTouchCancel;
var topTouchEnd;
var topTouchMove;
var topTouchStart;
var topTransitionEnd;
var topVolumeChange;
var topWaiting;
var topWheel;
// https://github.com/facebook/react/blob/master/packages/shared/isTextInputElement.js#L13-L29
// Closure will rename these properties during optimization
// But these are used dynamically to check against element props so they must not be renamed.
var isTextInputElement = {};
isTextInputElement.supportedInputTypes = {
color: true,
date: true,
datetime: true,
"datetime-local": true,
email: true,
month: true,
number: true,
password: true,
range: true,
search: true,
tel: true,
text: true,
time: true,
url: true,
week: true
};
// Context methods are created dynamically.
React.Context = function() {};
React.Context.prototype.Provider = function() {};
React.Context.prototype.Consumer = function() {};
// Value returned from createRef has dynamically set `current` property.
// var ReactRef = {};
// ReactRef.current = {};
// Rest are required due to Reagent implementation.
// Lifecycle methods need to be declared, as Reagent creates these dynamically
var React = {};
React.Component = function() {};
React.Component.prototype.componentWillMount = function() {};
React.Component.prototype.UNSAFE_componentWillMount = function() {};
React.Component.prototype.componentDidMount = function(element) {};
React.Component.prototype.componentWillReceiveProps = function(nextProps) {};
React.Component.prototype.UNSAFE_componentWillReceiveProps = function(nextProps) {};
React.Component.prototype.shouldComponentUpdate = function(nextProps, nextState) {};
React.Component.prototype.componentWillUpdate = function(nextProps, nextState) {};
React.Component.prototype.UNSAFE_componentWillUpdate = function(nextProps, nextState) {};
React.Component.prototype.componentDidUpdate = function(prevProps, prevState, rootNode) {};
React.Component.prototype.componentWillUnmount = function() {};
React.Component.prototype.componentDidCatch = function(error, info) {};
React.Component.prototype.getDerivedStateFromProps = function() {};
React.Component.prototype.getDerivedStateFromError = function() {};
React.Component.prototype.getSnapshotBeforeUpdate = function() {};
React.Component.prototype.getInitialState = function() {};
React.Component.prototype.getDefaultProps = function() {};
React.Component.prototype.getChildContext = function() {};
// Reagent creates render method statically.
// React.Component.prototype.render = function() {};
// React.Component.prototype.props;
// React.Component.prototype.state;
// React.Component.prototype.refs;
// React.Component.prototype.propTypes;
React.Component.prototype.context;
React.Component.prototype.contextTypes;
React.Component.prototype.contextType;
React.Component.prototype.mixins;
React.Component.prototype.childContextTypes;
// Reagent also creates the attributes dynamically (from clj maps)
// but mostly the attributes match DOM built-in attributes anyway.
React.ReactAttribute = function() {};
React.ReactAttribute.ref = {};
React.ReactAttribute.dangerouslySetInnerHTML = {};
React.ReactAttribute.dangerouslySetInnerHTML.__html = {};

View File

@ -3,13 +3,7 @@
:license {:name "MIT"}
:description "A simple ClojureScript interface to React"
:dependencies [[org.clojure/clojure "1.10.1"]
;; If :npm-deps enabled, these are used only for externs.
;; Without direct react dependency, other packages,
;; like react-leaflet might have closer dependency to a other version.
[cljsjs/react "16.13.0-0"]
[cljsjs/react-dom "16.13.0-0"]
[cljsjs/react-dom-server "16.13.0-0"]]
:dependencies [[org.clojure/clojure "1.10.1" :scope "provided"]]
:plugins [[lein-cljsbuild "1.1.7"]
[lein-doo "0.1.11"]
@ -25,10 +19,13 @@
:profiles {:dev {:dependencies [[org.clojure/clojurescript "1.10.597"]
[figwheel "0.5.19"]
[doo "0.1.11"]
[cljsjs/prop-types "15.7.2-0"]]
[doo "0.1.11"]]
:source-paths ["demo" "test" "examples/todomvc/src" "examples/simple/src" "examples/geometry/src"]
:resource-paths ["site" "target/cljsbuild/client" "target/cljsbuild/client-npm"]}}
:resource-paths ["site" "target/cljsbuild/client" "target/cljsbuild/client-npm"]}
:cljsjs {:dependencies [[cljsjs/react "16.13.0-0"]
[cljsjs/react-dom "16.13.0-0"]
[cljsjs/prop-types "15.7.2-0"]]}}
:clean-targets ^{:protect false} [:target-path :compile-path "out"]
@ -131,7 +128,8 @@
:output-to "target/cljsbuild/node-test-npm/main.js"
:npm-deps true
:aot-cache true
:checked-arrays :warn}}
:checked-arrays :warn
:verbose true}}
;; With :advanched source-paths doesn't matter that much as
;; Cljs compiler will only read :main file.
@ -159,7 +157,9 @@
:output-dir "target/cljsbuild/prod-npm/out" ;; Outside of public, not published
:closure-warnings {:global-this :off}
:npm-deps true
:aot-cache true}}
:aot-cache true
:verbose true
:externs ["npm_react.ext.js"]}}
{:id "prod-test"
:source-paths ["test"]
@ -180,10 +180,12 @@
:optimizations :advanced
:elide-asserts true
:pretty-print false
;; :pseudo-names true
:output-to "target/cljsbuild/prod-test-npm/main.js"
:output-dir "target/cljsbuild/prod-test-npm/out"
:closure-warnings {:global-this :off}
:npm-deps true
:aot-cache true
:checked-arrays :warn}}]})
:checked-arrays :warn
:verbose true
:pseudo-names true
:externs ["npm_react.ext.js"]}}]})

View File

@ -1,6 +1,6 @@
#!/bin/bash
set -ex
rm -rf target/cljsbuild/prod-test/
lein doo chrome-headless prod-test once
lein with-profile +cljsjs doo chrome-headless prod-test once
test -f target/cljsbuild/prod-test/main.js
node_modules/.bin/gzip-size target/cljsbuild/prod-test/main.js

View File

@ -1,5 +1,5 @@
#!/bin/bash
set -ex
rm -rf target/cljsbuild/test/
COVERAGE=1 lein doo chrome-headless test once
COVERAGE=1 lein with-profile +cljsjs doo chrome-headless test once
test -f target/cljsbuild/test/out/cljsjs/react/development/react.inc.js

View File

@ -1,5 +1,5 @@
#!/bin/bash
set -ex
rm -rf target/cljsbuild/node-test/
lein doo node node-test once
lein with-profile +cljsjs doo node node-test once
test -f target/cljsbuild/node-test/out/cljsjs/react/development/react.inc.js

View File

@ -457,15 +457,14 @@
(rstr (ae [:div [:div "foo"]]))))))
(def ndiv (let [cmp (fn [])]
(gobj/extend
(.-prototype cmp)
(.-prototype react/Component)
#js {:render (fn []
(this-as
this
(r/create-element
"div" #js {:className (.. this -props -className)}
(.. this -props -children))))})
(gobj/extend (.-prototype cmp) (.-prototype react/Component))
(set! (.-render (.-prototype cmp))
(fn []
(this-as
this
(r/create-element
"div" #js {:className (.. this -props -className)}
(.. this -props -children)))))
(gobj/extend cmp react/Component)
cmp))