bhauman / figwheel-main Goto Github PK
View Code? Open in Web Editor NEWFigwheel Main provides tooling for developing ClojureScript applications
Home Page: https://figwheel.org
License: Eclipse Public License 1.0
Figwheel Main provides tooling for developing ClojureScript applications
Home Page: https://figwheel.org
License: Eclipse Public License 1.0
This means that people have to start a file watching process, for their final compile if they have an environment that cljs doesn't support.
Just a continuation of nrepl/piggieback#92
Looking at the code it seems you'll only have to make one change here
figwheel-main/src/figwheel/main.cljc
Line 1230 in cc141a3
I'm following this tutorial to set up a figwheel environment.
But once I add the --compile
flag the compilation just finishes without leaving me inside the repl. E.g.
~/Development/cljs-starter > clj -m figwheel.main --compile cljs-starter.core --repl
[Figwheel] Compiling build unknown to "target/public/cljs-out/main.js"
[Figwheel] Successfully compiled build unknown to "target/public/cljs-out/main.js" in 0.413 seconds.
~/Development/cljs-starter >
deps.edn:
{:deps {org.clojure/clojurescript {:mvn/version "1.10.339"}
com.bhauman/figwheel-main {:mvn/version "0.1.8"}
com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}}
:paths ["src" "target"]}
cljs_starter/core.cljs:
(ns cljs-starter.core)
(defn what-kind? []
"Cruel")
(js/console.log (what-kind?))
What am I missing?
With the setup I have here using rebel-readline + clojure cli + deps.edn (no Leiningen) figwheel isn't able to compile .clj
files.
Steps to reproduce:
$ clojure -A:rebel
user=> (fig/start {:mode :serve} "dev")
user=> (fig/cljs-repl "dev"))
Modify src/user.clj
and save.
Note the error:
cljs.user=> [Figwheel] Could not Analyze /.../fullstack/src/user.clj line:1 column:1
Don't know how to create ISeq from: clojure.lang.Keyword
1 (ns user
^---
2 (:require [figwheel.main :as fig]
3 [fullstack.helpers :refer :all]))
4
5 (def x {:a 1})
6
[Figwheel:SEVERE] java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
I'm getting this error after the cljs compilation succeds and the REPL starts. Any ideas?
...
[Rebel readline] Type :repl/help for online help info
Exception in thread "main" clojure.lang.ExceptionInfo: Figwheel: Unable to dynamicly load figwheel.server.jetty-websocket/run-server {:not-loaded figwheel.server.jetty-websocket/run-server}
at clojure.core$ex_info.invokeStatic(core.clj:4739)
at clojure.core$ex_info.invoke(core.clj:4739)
at figwheel.repl$dynload.invokeStatic(repl.cljc:1070)
at figwheel.repl$dynload.invoke(repl.cljc:1066)
at figwheel.repl$run_default_server_STAR_.invokeStatic(repl.cljc:1089)
at figwheel.repl$run_default_server_STAR_.invoke(repl.cljc:1086)
at figwheel.repl$run_default_server.invokeStatic(repl.cljc:1123)
at figwheel.repl$run_default_server.invoke(repl.cljc:1122)
at figwheel.repl$setup.invokeStatic(repl.cljc:1152)
at figwheel.repl$setup.invoke(repl.cljc:1147)
at figwheel.repl.FigwheelReplEnv._setup(repl.cljc:1214)
at cljs.repl$repl_STAR_$fn__6607.invoke(repl.cljc:942)
at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1289)
at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1278)
at cljs.repl$repl_STAR_.invokeStatic(repl.cljc:940)
at cljs.repl$repl_STAR_.invoke(repl.cljc:855)
at rebel_readline.cljs.repl$eval8558$repl_STAR___8559.invoke(repl.clj:77)
at clojure.lang.Var.invoke(Var.java:385)
at figwheel.main$repl.invokeStatic(main.cljc:1406)
at figwheel.main$repl.invoke(main.cljc:1359)
at figwheel.main$default_compile.invokeStatic(main.cljc:1614)
at figwheel.main$default_compile.invoke(main.cljc:1579)
at figwheel.main$build_main_opt.invokeStatic(main.cljc:495)
at figwheel.main$build_main_opt.invoke(main.cljc:490)
at cljs.cli$main.invokeStatic(cli.clj:636)
at cljs.cli$main.doInvoke(cli.clj:625)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at cljs.main$_main.invokeStatic(main.clj:61)
at cljs.main$_main.doInvoke(main.clj:52)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:657)
at clojure.core$apply.invoke(core.clj:652)
at figwheel.main$_main$fn__7255.invoke(main.cljc:1908)
at clojure.core$with_redefs_fn.invokeStatic(core.clj:7434)
at clojure.core$with_redefs_fn.invoke(core.clj:7418)
at figwheel.main$_main.invokeStatic(main.cljc:1906)
at figwheel.main$_main.doInvoke(main.cljc:1885)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.core$apply.invokeStatic(core.clj:657)
at clojure.main$main_opt.invokeStatic(main.clj:317)
at clojure.main$main_opt.invoke(main.clj:313)
at clojure.main$main.invokeStatic(main.clj:424)
at clojure.main$main.doInvoke(main.clj:387)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.main.main(main.java:37)
This is my deps.edn file:
{:paths ["src" "resources"]
:deps
{org.clojure/clojure {:mvn/version "1.9.0"}
org.clojure/clojurescript {:mvn/version "1.10.339"}
org.clojure/core.async {:mvn/version "0.4.474"}
com.datomic/client-cloud {:mvn/version "0.8.56"}
com.cognitect/transit-clj {:mvn/version "0.8.309"}
com.cognitect/transit-cljs {:mvn/version "0.8.256"}
org.omcljs/om {:mvn/version "1.0.0-beta4"}
io.pedestal/pedestal.service {:mvn/version "0.5.4"}
io.pedestal/pedestal.immutant {:mvn/version "0.5.4"}
com.stuartsierra/component {:mvn/version "0.3.2"}}
ch.qos.logback/logback-classic {:mvn/version "1.2.3"
:exclusions
[org.slf4j/slf4j-api]}
org.slf4j/slf4j-api {:mvn/version "1.7.14"}
org.slf4j/jul-to-slf4j {:mvn/version "1.7.14"}
org.slf4j/jcl-over-slf4j {:mvn/version "1.7.14"}
org.slf4j/log4j-over-slf4j {:mvn/version "1.7.14"}}
:aliases
{:cljs.dev
{:extra-paths ["target"]
:extra-deps
{com.bhauman/figwheel-main {:mvn/version "0.1.5"}
com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}}}
:cljs.admin.dev
{:main-opts ["-m" "figwheel.main" "-b" "admin" "-r"]}
:cljs.reserve.dev
{:main-opts ["-m" "figwheel.main" "-b" "reserve" "-r"]}}}
Hi!
One thing which I've always wanted (but to be fair, have never checked if it was possible in the prior version of Figwheel) is how to println
from plain cljs code located in a source file, to the repl that is running within Emacs.
To summarize:
I recently tried to hack a solution with *print-fn*
and set!
, to no avail.
To know when Figwheel has reloaded its code (i.e. (println-to-repl "Reloaded!")
), without having to peek at the browser devtools. Most times I want to stay focused within Emacs, full-screen. Also, even if I switch to Chrome, when I see the evidence of the FW reload, I don't know if that one is for the latest change (10 seconds ago), or the prior change (e.g. 1 minute ago).
My prior approach was using Chrome notifications, but lately they only work over https, which can be a pain to setup for every project.
Whenever I say Emacs I probably could say "nrepl at my IDE" but I don't want to make assumptions about impl details.
Thanks - Victor
Figwheel main does it's best to make a decision as to what should be passed to the compiler as build inputs. It is reasonable to assume that there will be situations where a user will want to control the build-inputs that are passed to the compiler.
I'm proposing a :build-inputs
Figwheel configuration option that takes a vector of values.
The values in the provided vector can be
:main
which will cause the provided main namespace to be a build input.:watch-dirs
which will cause all the configured :watch-dirs
to be provided as inputsThis is a bug in figwheel-core that happens on reload when you change the dependency tree.
This is do to the hacky way that I was obtaining the dependency tree updates.
Something of note is that the CLJS compiler change that precipitated this problem was made on my birthday :)
clojure/clojurescript@adeaa9b#diff-37f2c970502705d61a0ab1f75ce8fe12
Hi,
I really like the idea of this but I've got a couple of issues:
how to repl in to a particular main? The scripting-api repl fn takes just build-id as an arg, but all these are in the same build.
I'm trying to use :after-load metadata to replace on-jsload. This would reload the react app in the app build and re-run the tests in the test build, but it seems like only one of the after-load fns gets used. I see a message in the other app that it has been unable to find the other reload fn (and I'd expect it not to be there).
I've tried to work around these problems by using multiple builds, started via scripting api, but am actually hitting issue 2 there as well.
If you need any more info please let me know.
Thanks,
Henry
Hello,
Given this deps.edn file (complete, not truncated):
{:deps {org.clojure/clojure {:mvn/version "1.9.0"}
org.clojure/clojurescript {:mvn/version "1.10.339"}
com.cerner/clara-rules {:mvn/version "0.18.0"}
com.rpl/specter {:mvn/version "1.1.0"}
tracking-spec {:mvn/version "0.1.4-SNAPSHOT"}}
:paths ["src"]
:aliases {:fig {:extra-deps {com.bhauman/figwheel-main {:mvn/version "0.1.4"}}
:extra-paths ["target"]
:main-opts ["--main" "figwheel.main" "--build" "dev" "--repl"]}}}
When I launch clojure -A:fig
I noticed that the only dev.cljs.edn
that will launch a REPL after the build is an almost empty one, with just the :main namespace, like {:main "trackers.core"}
. Same if I instead use cli option --compile trackers.core
. If I add any other CLJS compiler option the REPL supposed to launch after the build with the --repl
option doesn't launch, with no error in the browser console or in the terminal output:
#... [truncated, all the normal Figwheel output]
In the cljs.user ns, controls can be called without ns ie. (conns) instead of (figwheel.repl/conns)
Docs: (doc function-name-here)
Exit: :cljs/quit
Results: Stored in vars *1, *2, *3, *e holds last exception object
2018-07-12 16:06:30.763:INFO::main: Logging initialized @19570ms
Opening URL http://localhost:9500
# No ClojureScript version
# No REPL prompt
I tried waiting for several minutes, nothing happened.
If I put a complete dev.cljs.edn
file, all the build settings are honored, notably the :modules
and :libs
that I really need, but no REPL is launched. I narrowed it down to the :main
option being the only one that launches a REPL after removing all other options one by one.
To be sure, I've just re-read again the complete README and Tutorial to make sure I understood things clearly. CLJS compiler options go into .cljs.edn files and Figwheel options in figwheel-main.edn, right ?
End of the (bug?) report !
This will create and store state about the system so that you can launch a watching building process and then attach a REPL
There is a race condition here where we should add the default source paths before we add the ring-handler, so that it can be found.
Errors that originate in JavaScript should be have formatted and source mapped stacktraces
for instance warn if someone is trying to start a REPL with an optimizations other than :none
i.e "/cljs-out/dev" instead of "cljs-out/dev"
This will help folks who are using html pushstate navigation
then add a add-message-watch
function to the client
Could we make the browser launch step fail gracefully or be skippable via a cli parameter? This is especially an issue on windows (via WSL) or on a headless VM it will always crash at "Opening URL" unless you have a proper x-windows set up.
If an option exists and I missed it, forgive me.
clojure -Sdeps "{:deps {com.bhauman/figwheel-main {:mvn/version "0.1.5"} com.bhauman/rebel-readline-cljs {:mvn/version "0.1.4"}}}}" -m figwheel.main
"Opening URL http://localhost:9500
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)"
Making it work well on WSL might make more sense than creating a slightly forked "Windows version" (I'm using the CLI on WSL also, which works fine even though they have not released "native" windows CLI versions....).
OS: Windows 10.
I'm completely new to Clojure. I run
lein new figwheel-main hello-world.app -- --reagent
cd .\hello-world.app\
lein fig:build
The project compiles successfully and opens the browser, but I get a blank page. I inspect HTML body and get
<body>
<div id="app">
</div>
<!-- end of app div -->
<script src="cljs-out/dev-main.js" type="text/javascript"></script>
<script src="cljs-outdev/goog/base.js"></script>
<script src="cljs-outdev/goog/deps.js"></script>
<script src="cljs-outdev/cljs_deps.js"></script>
...
</body>
However there is no folder called cljs-outdev/
, I'm guessing those paths should be cljs-out/dev/
?
Thanks
I've started a project using Leiningen. Added ClojureScript and Figwheel-main to it. Here's my project.clj:
(defproject cljsplay "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.10.339"]
[com.bhauman/figwheel-main "0.1.4"]
[com.bhauman/rebel-readline-cljs "0.1.4"]
]
:main ^:skip-aot cljsplay.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}}
)
And my dev.cljs.edn:
{:main cljsplay.core
:watch-dirs ["cljs-src"]}
When I'm trying to run lein trampoline run -m figwheel.main -- -b dev -r
, I get this error:
Exception in thread "main" java.lang.ClassNotFoundException: expound.ansi, compiling:(figwheel/main.cljc:174:5)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6875)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyze(Compiler.java:6625)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyze(Compiler.java:6625)
at clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2797)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyze(Compiler.java:6625)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6319)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyze(Compiler.java:6625)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6001)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5380)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3972)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6866)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.access$300(Compiler.java:38)
at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:589)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868)
at clojure.lang.Compiler.analyze(Compiler.java:6669)
at clojure.lang.Compiler.analyze(Compiler.java:6625)
at clojure.lang.Compiler.eval(Compiler.java:6931)
at clojure.lang.Compiler.eval(Compiler.java:6916)
at clojure.lang.Compiler.load(Compiler.java:7379)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.loadResourceScript(RT.java:363)
at clojure.lang.RT.load(RT.java:453)
at clojure.lang.RT.load(RT.java:419)
at clojure.core$load$fn__5677.invoke(core.clj:5893)
at clojure.core$load.invokeStatic(core.clj:5892)
at clojure.core$load.doInvoke(core.clj:5876)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5697)
at clojure.core$load_one.invoke(core.clj:5692)
at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
at clojure.core$load_lib.invokeStatic(core.clj:5736)
at clojure.core$load_lib.doInvoke(core.clj:5717)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$load_libs.invokeStatic(core.clj:5774)
at clojure.core$load_libs.doInvoke(core.clj:5758)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$require.invokeStatic(core.clj:5796)
at clojure.core$require.doInvoke(core.clj:5796)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval5$fn__7.invoke(form-init4073996252145622837.clj:1)
at user$eval5.invokeStatic(form-init4073996252145622837.clj:1)
at user$eval5.invoke(form-init4073996252145622837.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6917)
at clojure.lang.Compiler.load(Compiler.java:7379)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$init_opt.invokeStatic(main.clj:277)
at clojure.main$init_opt.invoke(main.clj:277)
at clojure.main$initialize.invokeStatic(main.clj:308)
at clojure.main$null_opt.invokeStatic(main.clj:342)
at clojure.main$null_opt.invoke(main.clj:339)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: expound.ansi
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at clojure.lang.RT.classForName(RT.java:2168)
at clojure.lang.RT.classForName(RT.java:2177)
at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:1030)
at clojure.lang.Compiler.macroexpand1(Compiler.java:6807)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6854)
... 76 more
lein --version
outputs this:
Leiningen 2.8.1 on Java 1.8.0_172 OpenJDK 64-Bit Server VM
and perhaps have a configuration flag to turn the feature off entirely
Hi,
I love the new Figwheel, but I'm occasionally receiving the following error warning:
[Figwheel] Compiling build dev to "resources/public/js/app/dev/app.js"
internal/modules/cjs/loader.js:583
throw err;
^
Error: Cannot find module '@cljs-oss/module-deps'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:20:18)
at [eval]:8:13
at Script.runInThisContext (vm.js:91:20)
at Object.runInThisContext (vm.js:298:38)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at evalScript (internal/bootstrap/node.js:527:27)
[Figwheel] Failed to compile build dev in 2.779 seconds.
[Figwheel] Compile Exception:
This (somewhat randomly) seems to occurs after several successful change/reload cycles. Doing a (figwheel.main/reset) does not help, it seems necessary to kill the process and restart it.
I'm using Leiningen, on Mac, Clojurescript 1.10.339.
Any idea?
It would be great to have a chapter which explains nREPL.
And how to start figwheel-main in ClojureScript nREPL (using Leiningen and CLI Tools)
don't supply the watch-dirs as this will include all the files, not just the ones that are used.
In particular it would be powerful detect when someone is attempting to make a general watch-dir that is an parent directory of a classpath
think about the design of :figwheel.main/initializers
they are really processes that start when a build starts and end when a build ends
This could be expanded to more of a plugin architecture, where it adds hooks (ie pre-build-hook
) via multimethods,
The problem of state soon comes in for starting and stopping and we get back to component. I really don't want to bring component into this.
So how about we return a stop fn from the initializer. Will this pattern hold up or will we need to return to something more like component?
better to add an exception class and stack trace when not in concise mode
๐ Hello!
Trying to get back into Clojurescript land after being away for awhile. To be fair, it's possible I've skipped a step somewhere but I think I might have found an issue with how Figwheel is compiling things.
lein
and starting from a completely blank project using the template found herelein fig:build
Looking further into it, I see in the generated javascript that some of the paths are incorrectly formatted, for example this line .
document.write('<script src="cljs-out\dev/goog/deps.js"></script>');
Is there a reason the output is like this? If I change cljs-out\dev
to cljs-out/dev
and correct the other incorrect paths that get generated, then things load correctly and I'm left with just warnings and I see the connected status on localhost:9500
Any help is appreciated!
Folks will want to advanced compile once and see their app running.
Minimal repro:
(println "Hello from Node.js") ;; ->> Works just fine and prints the string to the REPL in Emacs
(defn POST []
(letfn [(random-boolean []
(if (= (.round js/Math (rand 1)) 1) true false))]
(js/Promise.
(fn [resolve reject]
(if (random-boolean)
(resolve "Wow some value!")
(reject (js/Error. "BOOOM!")))))))
(-> (POST)
(.then #(println %))
(.catch #(println %))) ;; String is printed in the browser instead of the REPL
Make it so that :modules cljs_base is loaded on the default repl pages.
Make it so that we print out the correct artifacts that are being compiled.
Remove :main
and :ouput-to
when using modules as they do not apply.
a clojure.lang.Var$Unbound cannot be cast to clojure.lang.Associative
has been reported when this is used over an nREPL connection
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.