miracle2k / webassets Goto Github PK
View Code? Open in Web Editor NEWAsset management for Python web development.
License: BSD 2-Clause "Simplified" License
Asset management for Python web development.
License: BSD 2-Clause "Simplified" License
Recently I've been looking to add compass files to some reusable apps (well, reusable by me and my team.)
Ideally these files would be compiled with the compass files for the project, so that variables could be overwritten, etc. I think this should work in theory on production using collect static because it'll move all the sass files into the same directory before webassets renders things (I haven't tried it yet).
I have tried this locally and right now the compass files do not see each other when using runserver.
I keep getting this error:
"Error: No asset bundles were found. If you are defining assets directly within your templates, you want to use the --parse-templates option."
Here are the steps i followed:
my assets.py looks like:
from django_assets import Bundle, register
js = Bundle('static/js/jquery/ui.slider.js',
'static/js/jquery/ui.core.js',
filters='jsmin', output='static/js/jquery/packed.js')
register('js_all', js)
I was trying to debug, by putting in print statements inside django_assets, here and there. The autoload() seems to find my home/assets.py fine, and register() inside that module works as well. I checked by printing out _REGISTRY at the end of register() with its id(_REGISTRY).
Now when when i run the management command, and it reaches registry.iter(), i added another print command inside iter() printing out the ID of that _REGISTRY var. It seems both IDs are different. So even though my the proper registry variable is getting set the first time, the next time it's actually a different instance.
Any clues what could be happening, or why i'm an idiot for missing something obvious :-)
Cheers,
Sid
When I'm trying to create filter via function, I'm recieving next:
File "\lib\site-packages\webassets\filter\__init__.py", line 62, in set_environment
if not self.env or self.env != env:
AttributeError: 'CallableFilter' object has no attribute 'env'
It seems like you reload Filter's constructor with CallableFilter's own, but do not set self.env
This will fix problem:
class CallableFilter(Filter):
"""Helper class that create a simple filter wrapping around
callable.
"""
def __init__(self, callable):
self.env = None
self.callable = callable
Thanks for your attention.
It would be nice to be able to have the filehash as query-string-cache-busting value instead of the mtime of the file which could change each time the site is redeployed where the hash will only change when the actual content is modified.
It would be also useful to cache that hash somewhere so that each request does not trigger a file read which is catastrophic. Note: this is also applicable to mtime testing since each request will make a stat on that file.
This can help to reuse sass variables across the merge, thus developer can collect all his vars for colours and basic layout in one place and don't @import this to every file.
For integration with build scripts that are supposed to push generated assets to a server, the rebuild command should allow specifying an explicit output target:
$ ./manage.py assets rebuild BUNDLE_NAME --output /tmp/%(version)s.css
This is just a feature request/help for implementing a function to automagically bundle all files of a certain type in a directory. I tried writing my own function:
def make_css_bundle(media_root, dir):
files = os.listdir(os.path.join(media_root, dir))
files.sort()
files = [os.path.join(dir, f) for f in files]
return files
and calling it like this:
css_all = Bundle(
make_css_bundle(STATIC_ROOT, 'verbena/css'),
make_css_bundle(STATIC_ROOT, 'verbena/diversifist/css'),
filters='cssmin', output='gen/all.css')
but I'm running into errors because the Bundle._build function doesn't support lists (I'm not that great of a programmer, so I gave up). I think this feature is important as it will allow a user to use Pinax css folders without hand-coding each file.
debug_info=None (default value) actually turning on the --debug-info:
if not self.debug_info is False: args.append('--debug-info')
Am I missing something? For me it's more correct to check if it's True (i.e it's set explicitly)
Hi,
I have similar to the following:
env.register('css', 'css/layout.css', 'css/day.css',
filters=['cssprefixer', 'cssmin', 'gzip'],
output='css/wa/site_min.css.gz')
The problem is that only the gzip file shows up. I need the css file as well to be in the folder so the webserver can find it (for browsers that don't accept gzip). I'll try making two rules, but seems like it should be an option somehow.
Hey Michael,
Webassets looks awesome. I'm trying to get it set up on my django->coffin->jinja2 project.
However, as soon as I added django_assets
to my INSTALLED_APPS
, I get a TypeError
accessing the site:
tag() got an unexpected keyword argument 'environment'
I see this in django_assets/templatetags/assets.py:113
:
register.tag(AssetsExtension, environment={'assets_environment': get_env()})
However, coffin's Library.tag doesn't expect the environment argument.
Am I missing something? I'm using the latest coffin (0.3.3) and the latest webassets (ebf81fd)
Any help will be appreciated.
Thanks!
-Adam
I'm getting the following error when adding my compass file:
Syntax error: Undefined mixin 'global-reset'.
on line 4 of /var/folders/-P/-PK-JXZbH-8aPX1RMuoHME+++TI/-Tmp-/tmp6b9zyo/in.sass, in `global-reset'
from line 4 of /var/folders/-P/-PK-JXZbH-8aPX1RMuoHME+++TI/-Tmp-/tmp6b9zyo/in.sass
1: /var/folders/-P/-PK-JXZbH-8aPX1RMuoHME+++TI/-Tmp-/tmp6b9zyo/in.sass
my file is currently very simple:
@import global
+global-reset
where global includes:
@import compass
I'm a bit confused about where I should be putting my compass config.rb file. Is it even possible to use a config file?
gzip filters import itself instead of standart gzip module and then raises attribute error on line 22:
zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=out)
It could be fixed with
from future import absolute_import
Hello,
in django_assets/management/commands/assets.py you are missing an import - BuildError class is not imported and ImportError exception is thrown.
Importing the missing module in assets.py fixed the problem:
from django_assets.bundle import BuildError
Hi all,
webassets is now using MEDIA_URL and MEDIA_ROOT settings. The meaning of these settings was changed in django 1.3 and webassets should use STATIC_URL and STATIC_ROOT for django 1.3 (or django < 1.3 + django-staticfiles).
There is a fork by lyschoening (https://github.com/lyschoening/webassets/) with django.contrib.staticfiles-related changes. As I can understand, it uses the following approach: replace MEDIA_* settings with STATIC_* settings and load files using staticfiles loader (source files are compressed, not the collected). This seems backwards-incompatible though.
I think the issue can be resolved this way:
a) Production. Files are collected to STATIC_ROOT and combined by webassets. Staticfiles loader is useless (?) because files are collected and webassets can load them from STATIC_ROOT.
b) Development. Files are served uncombined by staticfiles development view. Staticfiles loader is useless because files are not compressed and webassets doesn't have to load files.
c) Development. Files are served by staticfiles development view and we want them to be combined. Webassets can't just put combined files to STATIC_ROOT because it is ignored(?) when development staticfiles serving is enabled.
So I think it is easier to always work with collected static files. If (c) support is important it may be added later.
Michael, what was the reason for caching being disabled in non-debug mode? Could there be an option to override this?
We currently have 150+ JavaScript and SASS/CSS bundles and it takes over two minutes to generate all of the assets. Any ideas?
Example: http://webassets.readthedocs.org/en/latest/django/settings.html
I believe the guys at rtfd.org use whitelisting for enabling sphinx extensions. There is also suport for custom requirements necessary to build docs which is not enabled for non-trusted users as I can remember.
This page has a pretty good comparison of the Django asset managers, but webassets is missing:
http://djangoplugables.com/grids/g/asset-managers/
(I haven't kept up to date with webassets enough to fill in the columns myself.)
I'm using Django 1.3 and the latest Git version of webassets.
assets.py:
from django_assets import Bundle, register
js = Bundle('static/js/ajaxHandler.js',
'static/js/hashListener.js',
'static/js/autocomplete.js',
#filter='jsmin',
output='static/js/packed.js')
register('scripts', js);
base.html:
{% load assets %}
...
{% assets 'scripts' %}
<script src="{{ ASSET_URL }}"></script>
{% endassets %}
I can build the assets:
$ ./manage.py assets rebuild
Building asset: static/js/packed.js
But when including the assets part in my template, I get a TemplateSyntaxError:
Django Version: 1.3
Exception Type: TemplateSyntaxError
Exception Value:
Caught TypeError while rendering: 'NoneType' object is not subscriptable
Exception Location: /usr/lib/python2.7/site-packages/webassets-0.5.dev-
py2.7.egg/webassets/env.py in absurl, line 272
Python Executable: /usr/bin/python2
Python Version: 2.7.1
Traceback:
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, _callback_args, *_callback_kwargs)
File "/var/www/databot_front/databot/apps/shab/views.py" in home
20. return render_to_response('base_home.html', context)
File "/usr/lib/python2.7/site-packages/django/shortcuts/init.py" in render_to_response
20. return HttpResponse(loader.render_to_string(_args, *_kwargs), *_httpresponse_kwargs)
File "/usr/lib/python2.7/site-packages/django/template/loader.py" in render_to_string
183. return t.render(Context(dictionary))
File "/usr/lib/python2.7/site-packages/django/template/base.py" in render
123. return self._render(context)
File "/usr/lib/python2.7/site-packages/django/template/base.py" in _render
117. return self.nodelist.render(context)
File "/usr/lib/python2.7/site-packages/django/template/base.py" in render
744. bits.append(self.render_node(node, context))
File "/usr/lib/python2.7/site-packages/django/template/debug.py" in render_node
73. result = node.render(context)
File "/usr/lib/python2.7/site-packages/django/template/loader_tags.py" in render
127. return compiled_parent._render(context)
File "/usr/lib/python2.7/site-packages/django/template/base.py" in _render
117. return self.nodelist.render(context)
File "/usr/lib/python2.7/site-packages/django/template/base.py" in render
744. bits.append(self.render_node(node, context))
File "/usr/lib/python2.7/site-packages/django/template/debug.py" in render_node
73. result = node.render(context)
File "/usr/lib/python2.7/site-packages/webassets-0.5.dev-py2.7.egg/django_assets/templatetags/assets.py" in render
54. for url in bundle.urls(env=get_env()):
File "/usr/lib/python2.7/site-packages/webassets-0.5.dev-py2.7.egg/webassets/bundle.py" in urls
310. urls.extend(bundle._urls(env, *args, *_kwargs))
File "/usr/lib/python2.7/site-packages/webassets-0.5.dev-py2.7.egg/webassets/bundle.py" in _urls
285. return [make_url(env, self.output)]
File "/usr/lib/python2.7/site-packages/webassets-0.5.dev-py2.7.egg/webassets/merge.py" in make_url
163. return env.absurl(result)
File "/usr/lib/python2.7/site-packages/webassets-0.5.dev-py2.7.egg/webassets/env.py" in absurl
272. root += root[-1:] != '/' and '/' or ''
The SASS filter adds calls the SASS compiler with --debug-info
, which creates a lot of extraneous CSS output. There doesn't seem to be a way of disabling this other than subclassing the filter. It'd be cool if the filter recognized a SASS_DEBUG
setting or something that would toggle it.
I think that the expected behaviour when a file specified on a Bundle is not found is to just move on and append the next file, not to raise IOError or OSError. Especially in Django: one have defined their bundles and load them in the template and suddenly a (OS|IO)Error appears?
I would suggest to silent these errors or at least raise a more explanatory error.
the documentation http://readthedocs.org/docs/webassets/en/latest/builtin_filters.html refers to the 'closure' filter.
the source file src/django-assets/src/webassets/filter/closure.py has the name property set to 'closure_js'
Also, it'd be really nice to be able to get errors passed through the compiler, as well as pass it more configuration options for things like --language_in and which errors to suppress
Michael,
webassets is fantastic. I'd love to replace django-compress with it, but your release notes suggest that its API is still changing. How close are you to a 1.0 release?
(django-compressor would be our choice because of its stability, but it doesn't have a command to precompute all of the bundles. I've considered porting your management command, but the django-compressor author appears to have been inactive since September 2010.)
Something I wanted to have for a long time, and something I am reminded of every time I work with webassets, is the ability to define a single Bundle that contains both Javascript and CSS files. This would allow one to define, for example, a jQueryUI bundle that contains all the files necessary, both scripts and stylesheets, in a single place.
Or, a form widget could provide a bundle with again, both the necessary JS and CSS files (this would potentially allow things like collecting all assets from all form widgets used to built the final bundle).
However, I'm unsure how to best implement this; obviously, backwards-compatibility is also a concern, although I wouldn't be opposed to breaking it for a good design.
The fact that webassets doesn't presume anything about the type of files it works with (i.e. you don't explicitly define "Javascript" and "CSS" files as in some other libs) was a very conscious decision and I'd like to keep it that way on a core architectural level; however, it might be time to add something on top to make the day to day job of working with Javascript and CSS files easier. If you define, for example, multiple JS bundles, and use the same filters for each, it's tedious to explicitly define the list of filters for each bundle again and again.
I'm opening a ticket for this as a kind of RFC; anybody stumbling over this and wanting to share their thoughts, I'd be happy to hear them.
when using the following in a compass file (and django 1.3)
background-image: image-url("interface/arrow_back.png")
I get the following URL output in the css:
background-image: url('/images/interface/arrow_back.png');
i.e. its missing the STATIC_URL before /images
With DEBUG="merge", the cssrewrite filter is not applied. While this matches strictly speaking what DEBUG="merge" is supposed to do (not apply the filters), it's presumably not what one wants.
This just reveals a more basic weakness; The way one is currently encouraged to use nested bundles with debug="false" is also overly complicated. Maybe the filter itself should be able to declare when it needs to be applied. "cssrewrite" would say something to the effect of "always", as would CSS compilers like "sass".
Maybe there should be a semantic separation between different things filters "do". CSS compilation would be considered a sort of "pre-processing" step, "cssrewite" would be post-processing, and the actual compression would happen in between.
That some filters need to be the first ones to run (like sass), something that currently is not enforced (an outstanding TODO) could also play into this.
This would allow writing output files directly to S3, for example.
In “timestamp” mode updater can also watch for changes in assets definition file(s) and rebuild assets if bundle configuration has been changed.
Now you need to delete assets files or switch updater to “always” mode to update your assets after making changes in assets filters etc.
This has been suggested by dguaraglia:
A Javascript Template filter akin to what Jammit has: a filter that gets a bunch of files, converts their contents into into Javascript-safe strings, then wraps them with a function calling a renderer function you specify and puts everything in a namespace.
The question is how this should be implemented. A simple output filter would probably do the job.
The alternative would be a special bundle type:
Bundle(
'js1.js',
'js2.js',
JammitBundle(
'template1.jst',
'template2.jst',
'template3.jst',
template_language='resig'
),
'jquery.js',
filter='jsmin',
)
However this raises questions like: If I define my bundles in a YAML file, how do I specify a particular subclass like "JammitBundle" to be used?
Also have a look at: https://github.com/marlun/django-djammit
I defined a simple asset bundle in one of my Django templates and ran ./manage.py assets rebuild --parse-templates which produced the following error
File "/mypath/src/django-assets/src/django_assets/loaders.py", line 63, in _recurse_node
isinstance(node, (AssetsNodeMapped, AssetsNodeOriginal,)):
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
Looks like the import at the top of that file is failing and so AssetsNodeMapped is None and so the second argument to isinstance is a tuple of (None, AssetsNodeOriginal,)
Since webassets.Environment
already implements magic methods such as __getitem__
, it would be nice if the class provided __contains__
as well:
def __contains__(self, name):
return name in self._named_bundles
This small feature comes in handy when iron-proofing against typos; it's also much more elegant than try...except KeyError:
block.
Thanks!
Here's an idea I'm currently planning to add as soon as a find the time, to find a common solution to multiple related features that are currently lacking, like cache busting via filename, using hashes to cache-bust (#6), or auto-rebuilding via hash (a TODO in the code).
All this should be possible without complicating things too much for users who don't need any of it. Comments are welcome.
We'll make the following changes:
env.versioner
attribute defines what should be used as a version. This would be backed with classes like TimestampVersion
(the default) or HashVersion
, and you'd be free to create your own class, like MyGitRevVersion
.assets.expire
becomes a simple boolean, it controls whether a query string should be used for cache busting. Potentially it should also be renamed to make this clearer. What is added as a query string is determined by the versioner. By default nothing changes, but you can now expire using something else than the timestamp by defining a different versioner (see #6).%(version)s
placeholder, and this is as an alternative for env.expire
. Instead of a querystring for cache-busting, the filename itself would change. At least initially, those files would probably not be managed, so webassets would never delete old versions, although I suppose there's no reason this couldn't be done.When manually building a bundle, this is what happens:
The process for automatic (re)building:
env.updater
to env.auto_update
or env.auto_build
for clarification purposes and making it a boolean as well, and then letting the Version class provide the updater to use. There would probably be only a "TimestampUpdater" built in, but you could write your own. If a Version class does not provide an updater, like MyGitRevVersion likely wouldn't, then the env.auto_build
option can't be used with that versioner.expire=True
to do hash-based cache busting (again, see #6), while still having automatic rebuilds by timestamp checking.The existing cache system would be extended/used so that the current version of a bundle can be cached. The HashVersion would need this feature very much, and TimestampVersion would benefit as well (needing no stat calls). Of course, this can only provide a benefit if automatic rebuilding is not wanted.
Either the environment or bundles could probably be "pinned" to a specific version, which would make it possible in some scenarios to run with old version assets.
According to http://elsdoerfer.name/docs/webassets/django/settings.html ASSETS_UPDATER can be False. This used to work with webassets 0.5 but with latest master an exception is raised (Caught AttributeError while rendering: 'NoneType' object has no attribute 'needs_rebuild'). This is not mentioned in upgrading docs.
In order to work cssrewrite needs both relative paths but in some cases one of the path sent is absolute.
This patch fixes the problem for me.
diff --git a/src/webassets/bundle.py b/src/webassets/bundle.py index db03d6d..7d7bb8c 100644 --- a/src/webassets/bundle.py +++ b/src/webassets/bundle.py @@ -269,7 +269,8 @@ class Bundle(object): hunks.append(apply_filters( hunk, combined_filters, 'input', env.cache, disable_cache, - output_path=output_path)) + output_path=output_path, + source_path=c)) # Return all source hunks as one, with output filters applied final = merge(hunks)
Hello!
I am using Jinja2, Hamlish2 extension for Jinja and Coffin in Django project.
I defined a bundle in ./assets.py
:
from django_assets import Bundle, register
js = Bundle('coffee/sample.coffee', filters='coffeescript', output='gen/packed.js')
register('base', js)
Then I add django_assets app to INSTALLED_APPS in ./settings.py
When I first time run server the file compiles and successfuly shows in html code. But when I press F5 in browser or restart server an OSError appears that file coffee/sample.coffee
is not found. I inspected the code and found a solution:
just change line 241 in bundle.py (commit 0d380f7)
source_paths = [p for p in self.get_files(env)]
to next line:
source_paths = [env.abspath(p) for p in self.get_files(env)]
And timestamp updater will work correctly and the error will dissapear.
Please fix.
Hi Michael,
The setup for YUI compression can be easier. There is http://pypi.python.org/pypi/yuicompressor package with bundled yuicompressor.
It can be installed as
pip install yuicompressor
No more configuration would be necessary (no more worries about downloading YUI compressor, putting it somewhere, setting YUI_COMPRESSOR_PATH / JAVA_HOME / environment variables), the only requirement is Java Runtime Environment installed.
The old 'yui_js' and 'jui_css' filters should remain the same for backward compatibility.
Can we introduce e.g. 'yui_js_auto' and 'yui_css_auto' filters (any thoughts on better names?) that will use setup described above?
If so, I'll be happy to send a pull request.
Hi.
I noticed weird problem, when you are trying to use webassets with django project deployed via uwsgi, it calculates abspath in a wrong way in env.abspath routine.
It's not directly related to webassets, but to python working under uwsgi, because os.getcwd returns '/' and, consequently, os.path.abspath works wrong ('foobar' => '/foobar').
Friend of mine found mention of similar issue in flask maillist:
http://flask.pocoo.org/mailinglist/archive/2010/11/27/path-of-application-wsgi-vs-local/#dfa0ec9483f46abd14146242aa1ada34
./manage.py assets rebuild
[skipped]
File "/usr/local/lib/python2.6/dist-packages/django_assets/management/commands/assets.py", line 27, in <module>
from django.templatetags.assets import AssetsNode as AssetsNodeMapped
ImportError: No module named assets
not even sure if this is possible, but for compass I'm only including say "main.sass" which imports "something.sass"
if a change is made to something, it won't get picked up automatically by webassets I think because the timestamp on main hasn't changed.
I don't see it in the docs.
It'd be nice if URLs could be used in bundles, for example when using Google's Libraries API.
Bundle('https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js')
I think one can fudge this for now by using debug=True
, but it'd be nice if it was fully supported.
In webassets
django_assets/templatetags/assets.py
There is an attempt to do this at line 117
register = CoffinLibrary()
from webassets.ext.jinja2 import AssetsExtension
from django_assets.env import get_env
register.tag(AssetsExtension, environment={'assets_environment': get_env()})
but register.tag doesn't take an environment paramater.
Please update it to a more reliable version.
Gzip is not working for me:
AttributeError: 'module' object has no attribute 'GzipFile'
This happens because of the filename in webassets/filter/gzip.py. A simple rename of the file in gzipfilter.py fixes the problem.
If webassets is in debug mode, and a subbundle uses debug=False because it relies on, for example, a CSS compiler, then "watch" would currently try to build the full bundle, when it should be building the subbundle.
I believe this used to work, but was apparently broken at some point.
String 56: obsoletes = ['django-assets'],
According to the docs obsoletes parameter should contain a list of packages (not distributions).
This issue prevents webassets installation on my machine:
Running setup.py egg_info for package webassets
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/ivan/sites/.envs/aka/src/webassets/setup.py", line 61, in <module>
cmdclass = cmdclass,
File "/usr/lib/python2.6/distutils/core.py", line 113, in setup
_setup_distribution = dist = klass(attrs)
File "/home/ivan/sites/.envs/aka/lib/python2.6/site-packages/setuptools/dist.py", line 264, in __init__
_Distribution.__init__(self,attrs)
File "/usr/lib/python2.6/distutils/dist.py", line 258, in __init__
getattr(self.metadata, "set_" + key)(val)
File "/usr/lib/python2.6/distutils/dist.py", line 1215, in set_obsoletes
distutils.versionpredicate.VersionPredicate(v)
File "/usr/lib/python2.6/distutils/versionpredicate.py", line 113, in __init__
raise ValueError("expected parenthesized list: %r" % paren)
ValueError: expected parenthesized list: '-assets'
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/home/ivan/sites/.envs/aka/src/webassets/setup.py", line 61, in <module>
cmdclass = cmdclass,
File "/usr/lib/python2.6/distutils/core.py", line 113, in setup
_setup_distribution = dist = klass(attrs)
File "/home/ivan/sites/.envs/aka/lib/python2.6/site-packages/setuptools/dist.py", line 264, in __init__
_Distribution.__init__(self,attrs)
File "/usr/lib/python2.6/distutils/dist.py", line 258, in __init__
getattr(self.metadata, "set_" + key)(val)
File "/usr/lib/python2.6/distutils/dist.py", line 1215, in set_obsoletes
distutils.versionpredicate.VersionPredicate(v)
File "/usr/lib/python2.6/distutils/versionpredicate.py", line 113, in __init__
raise ValueError("expected parenthesized list: %r" % paren)
ValueError: expected parenthesized list: '-assets'
This pattern comes up a lot:
{% assets "gargle_js" %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
It'd be nice to have additional shortcut tags for CSS and JS to automatically insert the <link>
and <script>
tags, respectively:
{% assets_js "gargle_js" %}
Thoughts? I'll try to create a patch if I have time.
I use compass to create inline data-urls for images on our site. These are currently causing a failure.
TemplateSyntaxError: Caught Exception while rendering: compass: subprocess had error: stderr=File not found or cannot be read: /private/var/folders/-P/-PK-JXZbH-8aPX1RMuoHME+++TI/-Tmp-/tmp9fZh2n/static/images/wood/cherry/background.png, stdout=, returncode=1
where background.png is the image in question.
Why would you delete the old project?
I can understand wanting to start this new one but why not leave the other one around for posterity? I probably have 40 pip requirements files with the old url in it that are all now broken.
It is required here: https://github.com/miracle2k/webassets/blob/master/setup.py
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.