kubetail-org / loadjs Goto Github PK
View Code? Open in Web Editor NEWA tiny async loader / dependency manager for modern browsers (899 bytes)
License: MIT License
A tiny async loader / dependency manager for modern browsers (899 bytes)
License: MIT License
As more people discover page insights they will be coming here to resolve render-blocking js and css and this is the reason why I am trying out your software. I tried implementing load.js on my javascript which worked great, but then I added links to my css in 1st two lines of loadjs and my website is now unstylized. Here is how I am using your loadjs software in my section:
<-- <script> window.addEventListener('load', function() { loadjs(["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css", "styles/style.css", "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.4.min.js", "https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js", "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js", "scripts/djmarketing.js"], { success: function djMain() { /* loaded in series */ }, async: false }); }); </script> -->
Hi Everyone,
The newest version of LoadJS (2.0.0) includes a new API and support for fetching files in parallel and executing them in series via an async: false
option:
loadjs(['/path/to/foo.js', '/path/to/bar.js'], {
success: function() { /* foo.js and bar.js loaded in series */ },
async: false
});
Please try it out and let us know what you think!
Andres
First of I love this! I'm coming from headJS which is a fantastic loader (core only) almost as little as loadJS.
Second, Looks like when you load in parallel the order changes in reverse.
For example I would logically load my files like this in parallel:
loadjs(['//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js', '//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js'], 'thunk');
however in the dom the files are changed in reverse and the output is this:
loadjs(['//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js', '//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js'], 'thunk');
in this case seeing as bootsrtap needs jQuery first the changes that the scripts will conflict are very high.
is this a bug or is intended to load the scripts in reverse from the order originally assigned?
For example headJS does this very well and respects the original order, as it loads in sequence and parallel.
Let me know your thoughts.
Is this possible?
loadjs.ready(['moment/moment.js', 'moment/locale/es.js'], function() {
console.log(moment);
});
If both scripts are loaded in parallel there is no guarantee if moment
is loaded before locales?
I don't like nesting callbacks, you know, aka callback-hell.
This is something I use in $script.js
which seems to be missing in loadjs
. e.g. would be used like:
loadjs.path('/build/public');
loadjs('angular.js', 'angular');
loadjs('jquery.js', 'jquery');
Hi Everyone,
The newest version of LoadJS (3.2.0) includes support for retries after a load failure:
loadjs(['/path/to/foo.js', '/path/to/bar.js'], 'foobar', {
success: function() { /* foo.js & bar.js loaded */ },
error: function(pathsNotFound) { /* at least one path didn't load */ },
numRetries: 3
});
And for low-level access to script elements before they get added to the DOM (e.g. so you can add custom attributes):
loadjs(['/path/to/foo.js', '/path/to/bar.js'], {
success: function() {},
error: function(pathsNotFound) {},
before: function(path, scriptEl) {
/* called for each script node before being embedded */
if (path === '/path/to/foo.js') scriptEl.crossOrigin = true;
}
});
Special thanks to @rarkins and @toddw for their work on these features. Please try out the new version of LoadJS and let us know what you think!
Andres
https://github.com/muicss/loadjs
https://www.npmjs.com/package/loadjs
bower loadjs#* invalid-meta The "main" field cannot contain minified files
bower loadjs#* invalid-meta The "main" field has to contain only 1 file per filetype; found multiple .js files: ["dist/loadjs.js","dist/loadjs.min.js"]
When you use a package like https://www.npmjs.com/package/main-bower-files, both js files then get aded to the page
Hello. Forgive me if I am missing something obvious. I am a JS novice...
loadjs('BROKEN-URL-TO-CDN/lib.js', 'bundle', {
before: function(path, el) {
//add SRI and crossorigin
el.integrity = 'xxxx';
el.crossOrigin = 'anonymous';
},
error: function(pathsNotFound) {
//fallback to local copy
loadjs('js/lib.js', 'bundle');
}
});
I am trying to load a file from a CDN and fall back to a local copy on error. When testing the fallback, I purposefully corrupted the URL of the CDN, expecting loadJS to load the local file. However, what I got instead was this:
GET broken-url-to-cdn/lib.js::ERR_NAME_NOT_RESOLVED
t @ loadjs.min.js:1
r @ loadjs.min.js:1
i @ loadjs.min.js:1
(anonymous) @ (index):53
loadjs.min.js:1 Uncaught LoadJS
i @ loadjs.min.js:1
error @ (index):61
(anonymous) @ loadjs.min.js:1
i @ loadjs.min.js:1
s.onload.s.onerror.s.onbeforeload @ loadjs.min.js:1
Please help me understand what is going on (and how to fix it).
Thanks.
Hi Everyone,
The newest version of LoadJS (2.1.0) includes support for fetching CSS files:
loadjs(['/path/to/foo.css', '/path/to/bar.js'], {
success: function() { /* foo.css and bar.js loaded */ },
fail: function(depsNotFound) { /* foo.css or bar.js didn't load */ }
});
Please try it out and let us know what you think!
Andres
https://github.com/muicss/loadjs
https://www.npmjs.com/package/loadjs
We shaved off a few more bytes and bumped the version number (v0.1.3). The new version of LoadJS is 566 bytes (minified + gzipped). Enjoy!
https://github.com/muicss/loadjs
I've been thinking about simplifying the LoadJS API by combining the success/fail callback into one function that gets passed in a list of unmet dependencies:
loadjs(['foo.js', 'bar.js'], function(pathsNotFound) {
if (pathsNotFound.length) return; // at least one file failed
});
The advantage of merging the success/fail callbacks is that it simplifies the API and exposes script request failures in a more concise way.
Let me know if you have any thoughts or suggestions!
It doesnt seem like i can import this in node using commonjs such as import loadjs from 'loadjs'. Is this something that could be introduced?
Reason being i would like to load scripts from within my react app. I can use scriptjs which does indeed support this because it doesnt have an error callback :(
Thanks
Add to bower brah!
Hi Everyone,
The latest version of LoadJS (v3.5.0) includes the following new features:
Support for custom DOM insertion mechanisms via before
callback method
loadjs(['/path/to/foo.js'], {
success: function() {},
error: function(pathsNotFound) {},
before: function(path, scriptEl) {
document.body.appendChild(scriptEl);
/* return `false` to bypass default DOM insertion mechanism (<head>) */
return false;
}
});
Support for custom CSS filename suffixes via "css!" prefix
loadjs(['css!/path/to/cssfile.custom'], {
success: function() { /* cssfile.custom loaded as stylesheet */ }
});
An .isDefined()
method to detect previously defined bundle definitions
if (!loadjs.isDefined('foobar')) {
loadjs(['/path/to/foo.js', '/path/to/bar.js'], 'foobar', {
success: function() { /* foo.js & bar.js loaded */ }
});
}
Special thanks to @Boldewyn, @michelollivier, @sourcec0de, and @akrawchyk for their help with these features. Please try out the new version of LoadJS and let us know what you think!
Andres
https://github.com/muicss/loadjs
https://www.npmjs.com/package/loadjs
I have no problem with that. Just wondering. It's looking weird.
loadjs(['https://test.com/js/fuploader.js'], 'photouploader');
while trying to load java-script file, I am getting error on single page react application.
A few users have requested the ability to load files in parallel and execute them in order. By default, LoadJS requests are asynchronous but by setting the async attribute to false on <script> we can enable the desired behavior.
To accommodate async=false behavior, I propose we add support for an optional argument to loadjs
:
// load files in parallel and execute them in order
loadjs(['foo.js', 'bar.js'], function() { }, {async: false});
Let me know what you think!
I'm using loadjs to async load the Select2 jQuery plugin (https://select2.github.io/) that I use for 2 different use cases: 1) search autocomplete 2) location suggestions. The location suggestions depends on another data adapter, but both cases need the same plugin files other than that:
loadjs([
'/js/select2.js',
'/css/select2-theme.css'
], 'select2', {
success: initKeywordAutocomplete
});
loadjs([
'/js/select2.js',
'/js/select2-places.js',
'/css/select2-theme.css'
], 'select2-places', {
async: false, // load in series to ensure select2 is available before the places data adapter
success: initLocationAutocomplete
});
If I use the above code on a page, select2.js
, select2-theme.css
will both be added to the DOM twice, and select2-places.js
will only be added once.
First, is it reasonable to add an enhancement to loadjs that dedupes the scripts added to the DOM? Currently only bundles are deduped by their id's, but I'm thinking of saving the script paths too so they aren't appended to the DOM more than once.
Second, I can see why it would be a bad idea to expose the bundle dependency tracker objects, and instead have the .reset()
function to let users clear them out. But, is there a way to inspect the requests loadjs has initiated? Or should I just query the DOM for a script tag for the src
I want to avoid downloading twice?
Thanks in advance!
Fail is a verb, not a noun like success, so failure or error should be used.
This is documented as item 7, but is not shown in examples.html.
It appears to fail for me, as it tries to load the bundle name via http.
So I check if my mistake by running examples. The examples run, but they don't show above documented use case.
so this modified example fails but is documented as working.
// compose more complex dependency lists
loadjs('assets/file1.js', 'example7a');
loadjs(['example7a', 'assets/file3.js'], 'example7b');
// wait for multiple depdendencies
loadjs.ready(['example7b'],
function() {
log('Load by bundle');
},
function(depsNotFound) {
throw "Load should succeed";
});
I only tested on chrome
['1.js', '2.js']
on chrome the loading order is 2.js --> 1.js
Is that a bug ?
I have 3 resources: A, B, and C.
loadjs(['A', 'B', 'C'], function() {
// never reached, Errors thrown
});
Both B and C depend on A being loaded to work, but C is loading first and causing an error.
The only way I can get it working is:
loadjs(['A'], function() {
loadjs(['B', 'C'], function() {
// everything is ready
});
});
It is my understanding that Loadjs is a module loader. Working with ES6, Babel will transform your code and use (in most cases) hook in a module loader like Require.js or Commonjs to handle your imports
and this is part of the reason I choose to opt out of using es6
modules, because imo, require / common while appropriate, are out-dated.
Enter Loadjs โ By far by one of my most favourite little components. My question is as follows, would it (or is it) possible to use loadjs to transform es6 modules? e.g: Instead of transforming with Require.js / Common.js? Take the below situation:
ES6
import jQuery from 'jquery'
Babel > ES2015
define(['jQuery'], function(jquery) {
});
Using Loadjs, transform would be as follows:
loadjs(['jQuery'], {
success: function(){
// here
}
});
I was hoping someone could clarify if this is possible to do? My schedule is brutal and I've never played with transpilers, but if this in theory iis possible to do and viable, would this not be a far better solution opposed to relying on monolithic, ancient modules loaded like Require.js / Common.js (well at least until es6 support becomes the standard) to transform modules from ES6 into es2015.
Further Reading
My most recent project I used E6 Babel and instead of including a transform plugin like requirejs / common.js I instead just built a simple wrapper around loadjs. The build included Turbolinks which is why I built the wrapper, but what I found is I was using loadjs as I would es6 Modules:
Firstly, here is the wrapper:
class Loadjs {
constructor(options) {
this.modules = options.modules;
this.bundle = options.bundle;
this.async = options.async;
this.eval = options.eval;
}
ready(callback) {
if(!loadjs.isDefined(this.bundle)) {
if (this.eval) {
loadjs(this.modules, this.bundle, {
async: this.async
});
} else {
loadjs(this.modules, this.bundle, {
async: this.async,
before: function(path, el) {
//document.body.appendChild(el);
for (let key of path) {
el.setAttribute('data-turbolinks-eval', 'false')
}
//return false;
}
});
}
}
loadjs.ready(this.bundle, {
success: callback
});
}
}
What this would allow to do is the following, firstly I would call in the component e.g:
const Carousel = new Loadjs({
bundle: 'swiper',
modules: ['/assets/js/component/swiper.min.js'],
async: false,
eval: false
});
And when I required the component, I would init (as I would using loadjs)
Carousel.ready(() =>{
new swiper();
});
Of course you don't need this wrapper, loadjs ships with this functionality, I needed to attach attributes to component script files to prevent evaluation by Turbolinks, hence why I required it. However, the fact remains, I am achieving virtually what I would if I was to opt in and use es6 modules. Which begs me to ask to question again, could loadjs be used as a transform plugin by babel to transform es6 modules into es2015 code.
@amorey as always you poet, I'd love to hear your thoughts regarding this.
Can you add it to the CDN js?
https://cdnjs.com/
Hey,
Most projects I build always do terrible on Google Page Speed because of async loading and whatnot. I found this library and I'm excited to finally use it because I think this is the approach Google wants me to take for the fastest page render time.
On my sites I use rails which minifies all css and js into single files, and then I also have jQuery (using google CDN so its probably cached). So I'm wondering the best way to use loadJS if I have only 3 files (and I'm not using it as a dependency manager).
application.css
//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js
application.js
Will this cause a FOUC while the CSS loads? Also can I use a absolute URL for a path instead of a local path?
Hey! I'm trying to figure out how to detect and handle if an external tracker script has been blocked by Ghostery/AdBlock - but my test code below only ever seems to trigger success
, even if I'm using Ghostery to explicitly block the Marketo script (and I don't see that script load in DevTools either). Am I doing it wrong?
loadjs(['https://munchkin.marketo.net/munchkin-beta.js'], 'marketo');
loadjs.ready('marketo', {
success: function() {
console.log('pass!');
},
error: function(depsNotFound) {
console.log('fail!');
}
});
</script>
Hi Everyone,
We shaved off a few more bytes and bumped the version number to v1.0.2. The new version of LoadJS is 506 bytes (minified + gzipped):
https://github.com/muicss/loadjs
Also, LoadJS is now available via NPM and bower:
$ npm install loadjs
$ bower install loadjs
Let us know if you run into any issues or if you have any feature requests.
Enjoy!
Andres
Hi! I'm using loadjs (great library btw) and I'm seeing some infrequent loading failures in the logs. I'm trying to establish if it's caused by something blocking the scripts or if they are failing to load for some other reason.
The loadFiles
function already has logic to detect blocked scripts but it does not expose this information, only which scripts were blocked, if any. I'd like to be able to add this to the logs to better diagnose the what causing the failed script loads.
What do you think?
Why script injection starts after timeout? It delays downloading of scripts, sometimes significantly. There is almost no delay in Chrome, but in FF and IE9 (that's what I've tested so far) timeout event fired after DOMContentLoaded and thus they have notable lag before starting to download scripts. I tried to delete setTimeut and it removes the lag while the code is still passed all tests.
So, the question is: what for do we use setTimeout
? Comment says that timeout "fires after window 'load' event", but it's neither the truth or explanation why.
If you need, I can do some deeper investigation on this.
I see on the docs you can do something like the following:
// define a dependency bundle
loadjs(['/path/to/foo.js', '/path/to/bar.js'], 'foobar');
// OR use more advanced syntax for more options
loadjs.ready('foobar', {
success: function() { /* foo.js & bar.js loaded */ },
error: function(depsNotFound) { /* foobar bundle load failed */ },
before: function(path, scriptEl) { /* execute code before fetch */ },
async: true, // load files synchronously or asynchronously (default: true)
numRetries: 3 // number of times to retry fetch (default: 0)
});
Also, the docs on async indicate that with async: false
, the scripts should be loaded in parallel but executed in series. However, I am doing exactly the above, and sometimes the second script is loaded first causing an error to be thrown:
if (!loadjs.isDefined('jquery-validation')) {
loadjs(['/assets/vendor/jquery-validation/jquery.validate.min.js', '/assets/vendor/jquery-validation/additional-methods.js'], 'jquery-validation');
}
loadjs.ready('jquery-validation', {
async: false,
success: function () {
startFormValidation();
}
});
...And the error I get is from the additional-methods.js file, since it depends on the jquery.validate.min.js file. This is completely random, so I would imagine its just to do with the order they are executed. Am I doing something wrong or is there a way to ensure the files are loaded in the order I list them in? Thanks!
Could you add the possibility of loading other common resources Asynch? Like CSS for example. would this be possible without adding too much code overhead to loadJS?
Or perhaps creating new repos and have few handy modules that can be imported to add extra optional functionality to loadJS?
Let me know your thoughts.
How can I unload?
One way: load to a div w/ id and then remove div. Is that good or is there a better way?
Require does this: http://stackoverflow.com/questions/11899967/require-js-remove-definition-to-force-reload/18521604#18521604
Hi,
Is it possible to retry the load after some time? The use-case is for a resillient application (not a web-site) that needs to wait until a file becomes available. In this case I set the number of retries very high and would like to try the load every few seconds instead of immediatly, which hammers the server.
Thanks
Hi Everyone,
I just wanted to let you know that the latest version of LoadJS (3.5.2) accepts a success function as a simple callback argument:
loadjs(['/path/to/foo.js', '/path/to/bar.js'], function() {
// foo.js & bar.js have loaded
});
For access to more advanced features you can still pass in an object as an argument:
loadjs(['/path/to/foo.js', '/path/to/bar.js'], {
success: function() { /* foo.js & bar.js have loaded */ },
error: function(pathsNotFound) { /* at least one path didn't load */ },
async: false
});
I hope that helps to simplify your LoadJS syntax! Please let me know if you have any questions or suggestions.
Andres
P.S. Special thanks to @W1zzardTPU for the suggestion and the PR!
Hi!
I guess, it would be handy to publish the loader on npmjs.com to make it friendly for, say, browserify users.
Hi Everyone,
I just wanted to let you know that the latest version of LoadJS (v3.5.4) includes support for images (.png|.jpg|.gif|.svg). Here are some things you can do with the new functionality:
Execute code after an image has finished downloading
loadjs(['/path/to/foo.png', '/path/to/bar.css', '/path/to/thunk.js'], function() {
/* foo.png, bar.css and thunk.js loaded */
var img = document.createElement('img');
img.src = '/path/to/foo.png';
document.body.appendChild(img);
});
Detect download errors
loadjs(['/path/to/foo.png', '/path/to/bar.css', '/path/to/thunk.js'], {
success: function() { /* foo.png, bar.css and thunk.js loaded */ },
error: function(pathsNotFound) { /* at least one path didn't load */ }
});
Include images in bundle definitions
loadjs(['/path/to/foo.png', '/path/to/bar.css', '/path/to/thunk.js'], 'foobarthunk');
loadjs.ready('foobarthunk', function() {
/* foo.png, bar.css and thunk.js loaded */
});
Force treat a file as an image using an "img!" prefix
loadjs(['img!/path/to/image.custom'], function() {
/* image.custom loaded */
});
I hope this helps to simplify your frontend loading issues! Please let me know if you have any questions or suggestions.
Andres
I have the issue that scripts are loaded multiple times. I would have expected that scripts that have been loaded or are in the middle of loading won't be loaded each time.
loadjs(['libraryA.js', 'usingA.js'], {
success: function() { /* done loading */ },
async: false
});
loadjs(['libraryA.js', 'libraryB_usingA.js', 'usingA_B.js'], {
success: function() { /* done loading */ },
async: false
});
In the above example libraryA.js
gets loaded twice. I've been trying to avoid this issue by using bundleIds
and loadjs.ready
but this gets complicated quite quickly.
Am I missing something here?
Bundle ids in dependency lists are not working (example number 7).
Bundle id in dependency list detects like a script. In the browser's console it shows as script not loaded (status 500). Loadjs calls error callback.
I would like to load a number of scripts in parallel but delay their insertion into dom (and thus parsing/execution) until another unrelated async event has happened (SSR rendered html loading).
it this possible somehow ? I had assumed I could use the before
handler to set the script type to something like 'dummy' until the time is right and then switch the elements type (in order) .. but that does not work it seems since success is never triggered.
Is this possible somehow ?
Hi,
nice library. But I'm missing a way to define the target document. I would like to use this library to load scripts into iFrames.
Does it make sense to follow the proposal of adding a media="none" attribute to the link and switch that with "all" once loaded ?
See http://keithclark.co.uk/articles/loading-css-without-blocking-render/
Idea being that whenever the css link element is added some other things might still be going on on the page and those might block once the link element is detected.
I'm using LoadJS with ReactJS.
This code is inside ComponentWillReceiveProps:
https://jsfiddle.net/6n2khubb/
It works perfectly, even the setState executes correctly but the Uncaught LoadJS jumps in anyway.
If I comment the line
this.setState({ reducers: reducers })
then, no exception is shown.
I'm using scriptjs with the same code and works like a charm.
Hi, I'm using your great loader a few places, ex: https://cekvenich.site44.com/post/IDE/.
If you view console - notice the warning that chrome will follow spec and stop loading if type='text/javascript' and such is missing. I hope you can view the console and help decipher the warning, I think that is what they are saying.
( source is here but you won't need it
https://github.com/cekvenich/murder/tree/master/cekvenich.site44.com )
I have to deploy new code before. Can you please add types to all loads based on extension?
ex: .js is text/javascript' .
Hi Everyone,
The newest version of LoadJS (v1.0.4) includes better support for scripts blocked by Ad Blockers (e.g. Ad Block Plus, Ghostery). LoadJS now detects script loads canceled via the preventDefault()
mechanism:
https://github.com/muicss/loadjs
Let us know if you run into any issues or have any feature requests.
Enjoy!
Andres
We shaved off a few more bytes and bumped the version number (v0.1.4). The new version of LoadJS is 545 bytes (minified + gzipped). Enjoy!
https://github.com/muicss/loadjs
Hello,
I'm trying to mix and match my synchronous and asynchronous calls. I have 3 css files that can be loaded in any order, and 2 JS files that need to be loaded in a particular order. I'm trying to do the following:
loadjs(['https://unpkg.com/[email protected]/dist/leaflet.css',
'https://unpkg.com/[email protected]/dist/MarkerCluster.css',
'https://unpkg.com/[email protected]/dist/MarkerCluster.Default.css'
], 'css');
loadjs(['https://unpkg.com/[email protected]/dist/leaflet.js',
'https://unpkg.com/[email protected]/dist/leaflet.markercluster.js'
], 'js', { async: false });
loadjs.ready(['css, js'], {
success: function() {
console.log('Woohoo! everything loaded!');
document.body.appendChild(main);
},
error: () => {
console.log('ruh-roh... something went wrong!');
}
});
The files all seem to load properly like this, but the loadjs.ready()
function never runs. Is there any way to properly do what I'm trying to do here?
see my PR for details #40
Hi,
Sometimes, like with Google Fonts, there's no extension at the end of the URL. Then we'll need to set the resource type to help toast to load the resource as expected :
load('[css]https://fonts.googleapis.com/css?family=Open+Sans');
it requires to modify code with something like
` if (/.css$/.test(path)) {
isCss = true;
// css
e = doc.createElement('link');
e.rel = 'stylesheet';
e.href = path;
} else if (/^[css].+/.test(path)) {
isCss = true;
// css
e = doc.createElement('link');
e.rel = 'stylesheet';
e.href = path.substring(5);
} else if (/^[js].+/.test(path)) {
// javascript
e = doc.createElement('script');
e.src = path.substring(4);;
e.async = async === undefined ? true : async;
} else {
// javascript
e = doc.createElement('script');
e.src = path;
e.async = async === undefined ? true : async;
}`
Regards
Michel
I've been logging error callbacks from loadjs
for the past 5 weeks. My observations are:
This leads me to believe that in some of these cases, retrying failed file loads might actually work. Although I could probably write a wrapper around this, would you support the concept of retries in the library itself?
What do you think about adding an internal dependency called "document", that's triggered by document.ready?
I faced random issues with jquery dependencies until I realized my jQuery code now got executed before the DOM was ready. Clearly a coding bug on my side, but it got me thinking.
My current workaround is
loadjs(["..."], 'jquery-pre');
loadjs.ready(['jquery-pre'], function() {
$(function() { loadjs.done('jquery'); });
});
Not sure if worth the feature bloat for loadjs
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.