malaporte / nashorn-commonjs-modules Goto Github PK
View Code? Open in Web Editor NEWCommonJS modules support for Nashorn
License: MIT License
CommonJS modules support for Nashorn
License: MIT License
Pretty much all class fields and methods are private which makes it impossible to extend.
Can these be changed to protected instead?
So this is more of a question than a bug per se, I guess.
At the moment it doesn't appear that the framework is usable in OSGi-based server environments because of the dependency on the jdk.nashorn.api.scripting package, because of the reference to the NashornScriptEngine class.
Typically the classloaders for OSGi bundles (and really the framework's parent loader) have filtered/restricted access to the classes in the bootloader/JDK. So attempts to reference jdk.* packages are not likely to work without some orchestration, perhaps even having to fiddle with the OSGi framework initialization configuration itself (which would be a non-starter for many clients)
So the larger question is why the dependency on the NashornEngine itself exists vs just a conventional reference to javax.script.ScriptEngine...and also, how hard (impossible?) would it be to undo said dependency in lieu of the standard ScriptEngine class...??
This is really a question--what is the best/right way to use this Require module in a multi-threaded servlet environment??
So believing based on what I've read that the Nashorn engine itself is threadsafe, I create a single one of those in my servlet init().
Then on each request/thread i create new bindings, map in Java objects to be exposed to the script(s), and then do engine.eval(mainscript,newbindings).
The challenge/question is where in that sequence do I put the Require.enable(engine)? once at init? It doesn't seem like Require class exposes a flavor of enable where i could pass in the bindings (global) i want it to use?
I have the following script:
var module1= require('./module1);
var instance1= new module1.myclass1();
...
var module2= require('./module2);
var instance2= new module2.myclass2();
I pass the script to the engine (eval
) and then I map each instance to a java class with the method getInterface(object, class).
The two modules and the two instances are created in the engineScope
.
In the Module.class
there is this part:
private Module compileJavaScriptModule(Folder parent, String fullPath, String code)
throws ScriptException {
Bindings engineScope = engine.getBindings(ScriptContext.ENGINE_SCOPE);
Bindings module = createSafeBindings();
module.putAll(engineScope);
and then this other part:
public Object require(String module) throws ScriptException {
...
try {
// If not cached, we try to resolve the module from the current folder, ignoring node_modules
if (isPrefixedModuleName(module)) {
found = attemptToLoadFromThisFolder(resolvedFolder, filename); // this calls the method compileJavaScriptModule
}
...
children.add(found.module);
So at the end I have module1 and instance1 among the children of module2. Obviously I have also all other things present in the engineScope (e.g. require, exports, and module <main>
). The more I load module the more the structure becomes redundant.
Considering that I am new to Nashorn and node.js and there is no many information about module.children I'm questioning if it is correct to put the full content of the engineScope as child of a module.
Thanks for your attention.
aris
P.S. I've tried to comment module.putAll(engineScope)
: it works even so and the content of children seems more correct to me because I see only the module objects required by the one I'm inspecting.
There appears to be a bug that triggers an NPE when the module.exports is a function (and not an object with members). To recreate define a module (math.js) with syntax like:
module.exports = function(a,b) {
return a+b;
}
and then use it as follows in a client module:
var sum = require('./math.js');
var x = sum(2,4);
The problem goes away (and code works) if I change the definition to module.exports.somefunc = .... and the invocation to var x.somefunc = sum(2,4);
I ran into a problem running highlight.js that took me all day to debug and work around. It can be reproduced by fully initializing the highlight.js NPM module and then trying to highlight a string containing double quotes with the Scala highlighter:
val engine = ... // NashornScriptEngine
val mainModule = Require.enable(engine, ...)
val hl = mainModule.require("highlight.js")
engine.invokeMethod(hl, "highlight", "scala", "\"foo\"")
This triggers the initialization of the Scala highlighter where Object.create(proto, ...)
gets called at some point. It is called from within lib/highlight.js
using a prototype object that was originally created in the module lib/languages/scala.js
. For some reason this object appears as a ScriptObjectMirror
within Nashorn and not as a ScriptObject
. This makes Object.create
fail with:
javax.script.ScriptException: TypeError: [object Object] is not an Object in <eval> at line number 540 at column number 8
This problem does not occur when intializing highlight.js manually without nashorn-commonjs-modules by loading all required files and running them through engine.eval
calls with the default context.
I was able to work around the problem by inserting the following patch in the constructor of Module
to replace Object.create
with a version that can unwrap a ScriptObjectMirror
to the underlying ScriptObject
:
engine.eval( // Patch Object.create to unwrap ScriptObjectMirror to ScriptObject
"""(function() {
var realCreate = Object.create;
var su = Java.type('jdk.nashorn.api.scripting.ScriptUtils');
Object.create = function(p, v) { return realCreate(su.unwrap(p), v); };
})();""", global)
I am still not sure if there's something wrong in Module
that could be done differently to avoid the problem, or if it's simply a bug in Nashorn. Googling for the symptoms didn't yield any useful results.
I realize this is a long shot ("help me debug my server!") but I'm kind of at wit's ends.
I'm using handlebars
as a dependency in an Atomist rug
project, which behind the scene relies on nashorn-commonjs-modules 1.0.8
. Everything works fine locally (tested on Debian and MacOS) but one require
fails for a library when the same code is run on a CI server. I've also tried running the build locally using the same Docker image used by CI and can't reproduce the issue. At this point, I'm thinking the only difference would be in the environment passed to the Docker container (NPM config, networking...) because otherwise everything else is the same (same Java version, same libraries...).
Anyhow, enough ado, here is the stack I am getting:
Caused by: .atomist/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:16 Error: Module not found: ./code-gen
at com.coveo.nashorn_modules.Module.throwModuleNotFoundException(Module.java:365)
at com.coveo.nashorn_modules.Module.require(Module.java:126)
at jdk.nashorn.internal.scripts.Script$Recompilation$260$60AAAAA$javascript_compiler$cu1$restOf.L:1(.atomist/node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js:16)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:647)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
at com.coveo.nashorn_modules.Module.compileJavaScriptModule(Module.java:334)
at com.coveo.nashorn_modules.Module.compileModuleAndPutInCache(Module.java:288)
at com.coveo.nashorn_modules.Module.loadModuleAsFile(Module.java:202)
at com.coveo.nashorn_modules.Module.attemptToLoadFromThisFolder(Module.java:177)
at com.coveo.nashorn_modules.Module.require(Module.java:116)
at jdk.nashorn.internal.scripts.Script$Recompilation$252$60AAAAA$handlebars$cu1$restOf.L:1(.atomist/node_modules/handlebars/dist/cjs/handlebars.js:22)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:667)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
at com.coveo.nashorn_modules.Module.compileJavaScriptModule(Module.java:334)
at com.coveo.nashorn_modules.Module.compileModuleAndPutInCache(Module.java:288)
at com.coveo.nashorn_modules.Module.loadModuleAsFile(Module.java:202)
at com.coveo.nashorn_modules.Module.attemptToLoadFromThisFolder(Module.java:177)
at com.coveo.nashorn_modules.Module.require(Module.java:116)
at jdk.nashorn.internal.scripts.Script$Recompilation$30$60AAAAA$index.:scopeCall(.atomist/node_modules/handlebars/lib/index.js)
at jdk.nashorn.internal.scripts.Script$Recompilation$30$60AAAAA$index.L:1(.atomist/node_modules/handlebars/lib/index.js:7)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:667)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
at com.coveo.nashorn_modules.Module.compileJavaScriptModule(Module.java:334)
at com.coveo.nashorn_modules.Module.compileModuleAndPutInCache(Module.java:288)
at com.coveo.nashorn_modules.Module.loadModuleAsFile(Module.java:202)
at com.coveo.nashorn_modules.Module.loadModuleThroughPackageJson(Module.java:247)
at com.coveo.nashorn_modules.Module.loadModuleAsFolder(Module.java:215)
at com.coveo.nashorn_modules.Module.attemptToLoadFromThisFolder(Module.java:181)
at com.coveo.nashorn_modules.Module.searchForModuleInNodeModules(Module.java:150)
at com.coveo.nashorn_modules.Module.require(Module.java:122)
at jdk.nashorn.internal.scripts.Script$Recompilation$25$Common$cu1$restOf.L:1(.atomist/editors/Common.js:5)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:628)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
at com.coveo.nashorn_modules.Module.compileJavaScriptModule(Module.java:334)
at com.coveo.nashorn_modules.Module.compileModuleAndPutInCache(Module.java:288)
at com.coveo.nashorn_modules.Module.loadModuleAsFile(Module.java:202)
at com.coveo.nashorn_modules.Module.attemptToLoadFromThisFolder(Module.java:177)
at com.coveo.nashorn_modules.Module.require(Module.java:116)
at jdk.nashorn.internal.scripts.Script$Recompilation$7$Common.:program(.atomist/editors/Common.js:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:449)
And here is the beginning of javascript-compiler.js
where the failing require('./code-gen')
is located. Note that require
s above it work fine. And yes, code-gen.js
is in the same dir as javascript-compiler.js
.
'use strict';
exports.__esModule = true;
// istanbul ignore next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _base = require('../base');
var _exception = require('../exception');
var _exception2 = _interopRequireDefault(_exception);
var _utils = require('../utils');
var _codeGen = require('./code-gen');
var _codeGen2 = _interopRequireDefault(_codeGen);
Is this familiar by any chance? What type of environment change could influence this? How could I debug this, knowing that I can't attach a remote debugger to the JVM.
Any pointer/advice/hope would be very appreciated ๐
I have a couple of simple modules that I'm trying to wrangle into Nashorn. One example is LoDash.
If I include it as a Maven dependency via webjars:
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>lodash</artifactId>
<version>4.17.4</version>
</dependency>
I technically have it in my classpath via the jar lodash-4.17.4.jar
with an example path inside it of /META-INF/resources/webjars/lodash/4.17.4/index.js
.
Is there any chance this is enough to be able to require the module? I'm figuring the version is one problem, and the other problem is not being sure how to reference the path in the ResourceFolder.
Currently, the require method enforces (line 115 of Module.class) that all modules loaded from the filesystem must be prefixed with '/', '../' or './'.
This makes it difficult to import existing modules that in turn require other modules that do not include a prefix.
Can you just remove this check and leave it up to the module loader (i.e. Folder implementation) to determine whether to load from filesystem or not?
In particular, a script may set exports
to a string. This fails because RequireFunction.require
expects exports
to be of type Bindings
, which is enforced when reassigning a new exports
which was created by a script.
So, when trying to resolve module 'fbjs/lib/invariant', from React, I'm getting a no module found exception.
When debugging the module, seems like it could be related with this method.
private Module searchForModuleInNodeModules(Folder from, String filename) throws ScriptException {
Folder current = from;
while (current != null) {
Folder nodeModules = current.getFolder("node_modules");
if (nodeModules != null) {
Module found = attemptToLoadFromThisFolder(nodeModules, filename);
if (found != null) {
return found;
}
}
current = current.getParent();
}
return null;
}
It does not seem to mimic the NodeJS behaviour, at least according to this
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
a. if PARTS[I] = "node_modules" CONTINUE
c. DIR = path join(PARTS[0 .. I] + "node_modules")
b. DIRS = DIRS + DIR
c. let I = I - 1
5. return DIRS
I include this in my pom.xml, and get this at runtime:
java.lang.NoClassDefFoundError: com/coveo/nashorn_modules/Folder
I'm loading it into a Bukkit plugin in Minecraft.
I cannot use "get" function in the exports of a module. A different name e.g. "get1" works just fine. Probably somehow the exports interferes with the SimpleBindings class methods?
Exception in thread "main" javax.script.ScriptException: TypeError: Can not invoke method [jdk.internal.dynalink.beans.SimpleDynamicMethod Object javax.script.SimpleBindings.get(Object)] with the passed arguments; they do not match any of its method signatures. in at line number 6
at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:467)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:451)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at sample1.RequireTest.main(RequireTest.java:27)
Caused by: :6 TypeError: Can not invoke method [jdk.internal.dynalink.beans.SimpleDynamicMethod Object javax.script.SimpleBindings.get(Object)] with the passed arguments; they do not match any of its method signatures.
at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:213)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:185)
at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:172)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(NashornBottomLinker.java:103)
at jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(NashornBottomLinker.java:73)
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:154)
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:253)
at jdk.nashorn.internal.scripts.Script$Recompilation$3$58AA$^eval_.get1(:6)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:641)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
at jdk.nashorn.internal.scripts.Script$^eval_.:program(:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
... 5 more
Hi,
I'm having trouble using the library ... I was getting NPEs when using it, so checked out and triedto build the source locally, using this environment:
Java version: 1.8.0_25, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Contents/Home/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.6", arch: "x86_64", family: "mac"
As far as I can tell, standard Mac with standard Oracle J8 JDK...
Anyway, I get the following error running Maven:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.239 s
[INFO] Finished at: 2018-01-27T09:26:23-07:00
[INFO] Final Memory: 20M/325M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project nashorn-commonjs-modules: Compilation failure: Compilation failure:
[ERROR] /Users/sjerman/Git/nashorn-commonjs-modules/src/test/java/com/coveo/nashorn_modules/ModuleTest.java:[420,34] cannot find symbol
[ERROR] symbol: method identical(jdk.nashorn.api.scripting.ScriptObjectMirror,jdk.nashorn.api.scripting.ScriptObjectMirror)
[ERROR] location: class jdk.nashorn.api.scripting.ScriptObjectMirror
[ERROR] /Users/sjerman/Git/nashorn-commonjs-modules/src/test/java/com/coveo/nashorn_modules/ModuleTest.java:[428,34] cannot find symbol
[ERROR] symbol: method identical(jdk.nashorn.api.scripting.ScriptObjectMirror,jdk.nashorn.api.scripting.ScriptObjectMirror)
[ERROR] location: class jdk.nashorn.api.scripting.ScriptObjectMirror
[ERROR] /Users/sjerman/Git/nashorn-commonjs-modules/src/test/java/com/coveo/nashorn_modules/ModuleTest.java:[437,34] cannot find symbol
[ERROR] symbol: method identical(jdk.nashorn.api.scripting.ScriptObjectMirror,jdk.nashorn.api.scripting.ScriptObjectMirror)
[ERROR] location: class jdk.nashorn.api.scripting.ScriptObjectMirror
[ERROR] -> [Help 1]
[ERROR]
I loaded in Eclipse and get same compile errors, looking at ScriptObjectMirror object in Eclipse browser it doesn't have identical method.
I'm not sure what the issue is but starting to wonder if the Nashorn API has changed... which is weird.
Any suggestions?
I have succeeded in loading some modules through the file system. However, I'm having trouble loading built-in node modules such as http
or url
and any modules that require these. The reason is probably because the root folder I specified does not have these modules under it.
How should I get around this?
I recently downloaded version 1.0.9
and attempted to build the project, but was met with unit test failures.
I tried to compile by running mvn package
, and was met with the following test failures:
Failed tests:
rootFolderHasTheExpectedProperties(com.coveo.nashorn_modules.FilesystemFolderTest)
getFolderReturnsAnObjectWithTheExpectedProperties(com.coveo.nashorn_modules.FilesystemFolderTest)
Tests run: 68, Failures: 2, Errors: 0, Skipped: 0
OS info:
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)
Maven home: C:\apache-maven\bin..
Java version: 1.8.0_102, vendor: Oracle Corporation
Java home: C:\Progra~1\Java\jdk1.8.0_102\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"
Any insight into what might be going wrong would be appreciated!
Hello,
Not sure if this is an issue or bad use on my part. I'm trying to into Nashorn a Node.js package, json-rules-enign, located here.
public static void main( String[] args ) { App app = new App(); String moduleFolder = "node_modules/json-rules-engine/dist/"; String filePath = moduleFolder + "index.js"; //String filePath = "index.js"; try { ScriptEngineManager engineManager = new ScriptEngineManager(); ScriptEngine engine = engineManager.getEngineByName(ID_SCRIPT_ENGINE); Folder nodeJsModFolder = ResourceFolder.create(app.getClass().getClassLoader(), moduleFolder, "UTF-8"); Require.enable((NashornScriptEngine) engine, nodeJsModFolder); logDebug("Folder is " + nodeJsModFolder.getPath()); engine.eval(new FileReader(app.loadFile(filePath))); } catch (FileNotFoundException e) { logError(e); } catch (ScriptException e) { logError(e); } }
But when I run it, getting this error on the line "engine.eval(new FileReader(app.loadFile(filePath)));", which is trying to load file "node_modules/json-rules-engine/dist/index.js" from the JSON rules engine Node.js package:
ERROR: An error ocurred: javax.script.ScriptException: TypeError: [object global] is not an Object in at line number 4
In the JavaScript, the error seems to be coming from this line in file "node_modules/json-rules-engine/dist/json-rules-engine.js":
Object.defineProperty(exports, "__esModule", { value: true });
I'm using Java 1.8.0_121, and version 1.0.6 of nashorn-commonjs-modules. Any idea what I might be doing wrong? Thanks.
I am trying to call a small library build with webpack2. It is configured to result in a es5, commonjs bundle. I am using nashorn-commonjs-module to import it by evaluating module = require('importModule');
.
importModule
contains a default export to a function served as the API, which I want to call.
However, module
is evaluate to an empty object. There are no exports, nothing... any idea? Did I get something wrong?
This is a bit speculative because I haven't actually verified it with nashorn-commonjs-modules. I have since ported the project to Scala, adapted it better to my use case, and fixed the bugs I ran into. It is not a single file with ~150 LOC. I discovered this issue with my version but looking at the source code tells me that I've reproduced the logic faithfully and therefore the original implementation should also fail.
I am trying to load the mermaid
NPM module. It contains a file src/d3.js
:
//log.debug('Setting up d3');
var d3;
if (require) {
try {
d3 = require('d3');
} catch (e) {
//log.debug('Exception ... but ok');
//log.debug(e);
}
}
...
Due to the order in which resources are searched, the call require('d3')
gets resolved back to the current file. I haven't done any research of how this supposed to work on NPM but it seems that an "obvious" node_module reference should first be searched in the global modules, not moving upwards from the current directory which may contain a .js file with the same name. After changing the search order to check the root folder first and only work back up from the current folder if it's not found at the root, I can load these modules correctly.
It appears that the POM for the library still includes SLF4J as a dependency even though I cannot see an actual import that refers to it in any of the Java source files.
This causes some wonkiness when trying to use the library in an OSGi environment as it automatically generates an import for the SLF4J packages--unnecessarily.
In the pom.xml there is no scope set for mockito-core.
I think it should definitely test.
This line seems to be the culprit:
engine.eval("(function (exports, require, module, __filename, __dirname) {" + code + "})");
When code
contains a JS file string where the last line ends in a comment, it comments out the end brackets, })
, and parsing fails. Adding a newline would most likely fix this:
engine.eval("(function (exports, require, module, __filename, __dirname) {" + code + "\n})");
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.