overzealous / lazypipe Goto Github PK
View Code? Open in Web Editor NEWLazily create a pipeline out of reusable components. Useful for gulp.
License: MIT License
Lazily create a pipeline out of reusable components. Useful for gulp.
License: MIT License
Im trying to minificate execution time by predefining babel presets and plugins, determinate by extension, but i got a infinite loop in stream:
file ./tasks/babel.js
module.exports = function() {
const path = require('path');
var self = this;
return self.files.source('', '.{babel.{js,jsx},es,es5,es6,esx,esx5,esx6}')
.pipe(this.transformers.sourcemap(function(lazypipe) {
return lazypipe
/* here code gone to loop */
.pipe(require('gulp-tap'), function(file, t) {
var ext = path.extname(file.path),
cfg = {presets:[],plugins:[]};
if ('es6,esx6'.split(',').indexOf(ext)) {
cfg.presets.push('es2016');
} else {
cfg.presets.push('es2015');
}
if ('.esx6,esx5,esx,jsx'.split(',').indexOf(ext)) {
cfg.plugins.push('transform-react-jsx');
}
t.through(require('gulp-babel'), [cfg]);
})
}))
.pipe(self.files.dest('/assets/scripts'));
};
file: ./fns.js
const lazypipe = require('lazypipe');
gulp.transformers = gulp.transformers || {};
gulp.transformers.sourcemap = function(lazyCallback) {
const sourcemap = require('gulp-sourcemaps');
if (gulp.production) {
return lazyCallback(lazypipe())();
} else {
return lazypipe()
.pipe(sourcemap.init)
.pipe(lazyCallback(lazypipe()))
.pipe(sourcemap.write, '.')();
}
};
file: ./gulpfile.babel.js
import { each, extend } from "lodash";
var gulp = extend(require('gulp'), {
temp: '../.tmp',
source: '../source',
ignoreChar: '_',
EOL: require('os').EOL,
sep: require('path').sep,
production: !!~process.argv.indexOf('--ENV=PROD')
});
require('./fns.js')(gulp);
if (~process.argv.indexOf('--stats')) {
require('gulp-stats')(gulp);
}
each(require('require-dir')('./tasks'), (fn, name)=> {
if (fn.constructor == Function) {
var arg = [];
arg.push(name);
if (fn.dependencies) {
arg.push(fn.dependencies);
}
arg.push(fn.bind(gulp));
gulp.task.apply(gulp, [name, fn.dependencies, fn.bind(gulp, require('lodash'))])
}
});
Modification gulp-babel plugin for logging:
file ./node_modules/gulp-babel/index.js
...
module.exports = function (opts) {
opts = opts || {};
console.log(opts);
return through.obj(function (file, enc, cb) {
if (file.isNull()) {
cb(null, file);
return;
}
console.log(file.path);
if (file.isStream()) {
cb(new gutil.PluginError('gulp-babel', 'Streaming not supported'));
return;
}
...
$ ver
Microsoft Windows [Version 10.0.14379]
$ gulp -v
[17:52:45] CLI version 3.9.1
[17:52:45] Local version 3.9.1
$ gulp babel
[17:53:46] Requiring external module babel-register
(node:25388) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.
[17:53:47] Starting 'babel'...
{ presets: [ 'es2016' ], plugins: [ 'transform-react-jsx' ] }
...\source\scripts\app.babel.jsx
...\source\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
... 5 minutes later
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
...\scripts\app.babel.js
I saw #4 but it didn't help me to find a solution. I'm using lazypipe to create reusable pieces of functionality that can be packaged up and reused. Is this the proper way to use lazy pipe with .on()?
function babelPipe(config) {
var jsFilter = gulpFilter(['**/*.js'], {restore: true});
var pipe = lazypipe()
.pipe(function() {
return jsFilter;
})
.pipe(babel)
.pipe(function() {
return jsFilter.restore;
});
return pipe()
.on('error', function(e) {
console.log('>>> ERROR', e);
// emit here
this.emit('end');
});
}
Would make things more javascripty for passing args into stream fns
var jsHintTasks = lazypipe()
// adding a pipeline step, notice the stream function has not been called!
.pipe(jshint)
// adding a step with an argument
.pipe(jshint.reporter, 'jshint-stylish');
could be rewritten as
var jsHintTasks = lazypipe()
// adding a pipeline step, notice the stream function has not been called!
.pipe(jshint)
// adding a step with an argument
.pipe(jshint.reporter.bind(null, 'jshint-stylish'));
i'm kind of a novice to gulp and indeed node, and i'm going thru what is probably a typical exercise of trying to 'dry' up a gulp-file.
i have come across lazypipe
and multipipe and they seem to have similar capabilities in terms of composition of streams, but i don't think i understand the nuance of their differences (particularly when used in conjunction with gulp).
perhaps something around immutability?
anyone familiar enough with both packages to shed some light for me?
regards,
tony.
Hey
I'm trying to refactor my gulp to use this tool
sass pipeline looks like:
gulp.task('sass', function () {
gulp.src('./sass/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css'));
});
And i couldn't figure i i can add the .on('error', sass.logError)
Thanks!
I stumbled on this project, and was wondering: how is this different as the combine method from gulp-util
?
In the example below, there are two ways I tried to do the same thing.
var gulp = require('gulp');
var lazypipe = require('lazypipe');
var newer = require('gulp-newer');
var less = require('gulp-less');
var rename = require('gulp-rename');
// start crashing lines
var lp = lazypipe();
lp.pipe(newer, {dest: 'build', ext: '.css'});
lp.pipe(less)
.pipe(rename, {extname: '.css'});
// end crashing lines
//start working lines
var lp = lazypipe()
.pipe(newer, {dest: 'build', ext: '.css'})
.pipe(less)
.pipe(rename, {extname: '.css'});
//end working lines
gulp.task('default', function () {
return gulp.src('src/*.less')
.pipe(lp())
.pipe(gulp.dest('build'));
});
When I chain the pipe()
calls, I get no errors. (I'm not saying that it "works". I'm actually trying to see why gulp-newer
doesn't do what it should at the moment.) When I store the result of lazypipe()
and use it, I get this error:
_\test>gulp
[23:05:31] Using gulpfile _\test\Gulpfile.js
[23:05:31] Starting 'default'...
[23:05:31] 'default' errored after 4.42 ms
[23:05:31] Error: Tried to build a pipeline with no pipes!
at validateSteps (_\node_modules\lazypipe\index.js:17:10)
at build (_\node_modules\lazypipe\index.js:25:5)
at Gulp.<anonymous> (_\test\Gulpfile.js:21:15)
at module.exports (_\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:34:7)
at Gulp.Orchestrator._runTask (_\node_modules\gulp\node_modules\orchestrator\index.js:273:3)
at Gulp.Orchestrator._runStep (_\node_modules\gulp\node_modules\orchestrator\index.js:214:10)
at Gulp.Orchestrator.start (_\node_modules\gulp\node_modules\orchestrator\index.js:134:8)
at &\node_modules\gulp\bin\gulp.js:129:20
at process._tickCallback (node.js:442:13)
at Function.Module.runMain (module.js:499:11)
Hello, first of all, thanks for the great project. I've been using it for some time now in order to take a stream and send all js
files to a pipe and css
file to another. Like this:
gulp.task("optimize-css-js", function(){
// Other unrelated code //
return gulp.src(cssjs)
.pipe(gulpif("*.css", cssPipe())) // Process CSS
.pipe(gulpif("*.js", jsPipe())); // Process JS
});
var jsPipe = lazypipe()
.pipe(concat, conf.minified.js)
.pipe(uglify)
.pipe(gulp.dest, path.join(conf.distFolder, conf.resourcesDir));
var cssPipe = lazypipe()
.pipe(cleanCSS, {
//...
.pipe(gulp.dest, path.join(conf.distFolder, conf.resourcesDir));
Since I included return
on the task I was expecting the task to only finish after both pipes finished their operations, however this doesn't seem to be the case. Due to some reason the task finishes before all files in both pipes are written to the disk... How can I fix this?
Thank you!
Hello @OverZealous I'm using lazypipe()
as template to DRY my gulp tasks.
Unfortunately, I get an error:
serge@serge:~/projects/haystak$ gulp deploy
[20:41:50] Starting 'deploy'...
Building APP bundle
[20:41:50] 'deploy' errored after 25 ms
[20:41:50] TypeError: dest.on is not a function
at Duplexer.Readable.pipe (/home/serge/projects/korob/node_modules/readable-stream/lib/_stream_readable.js:485:8)
at rebundle (/home/serge/projects/korob/Gulpfile.js:69:8)
at browserifyTask (/home/serge/projects/korob/Gulpfile.js:82:3)
at Gulp.<anonymous> (/home/serge/projects/korob/Gulpfile.js:229:3)
at module.exports (/home/serge/projects/korob/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask (/home/serge/projects/korob/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep (/home/serge/projects/korob/node_modules/orchestrator/index.js:214:10)
at /home/serge/projects/korob/node_modules/orchestrator/index.js:279:18
at finish (/home/serge/projects/korob/node_modules/orchestrator/lib/runTask.js:21:8)
at cb (/home/serge/projects/korob/node_modules/orchestrator/lib/runTask.js:29:3)
my gulpfile (I removed unnecessary lines out of scope + plus add references to lines):
var browserify = require('browserify');
var babelify = require('babelify');
var pathmodify = require('pathmodify');
var path = require('path');
var concat = require('gulp-concat');
var cssmin = require('gulp-cssmin');
var glob = require('glob');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var rev = require('gulp-rev');
var revReplace = require('gulp-rev-replace');
var buffer = require('gulp-buffer');
var insertLines = require('gulp-insert-lines');
var livereload = require('gulp-livereload');
var htmlmin = require('gulp-htmlmin');
var notify = require('gulp-notify');
var sass = require('gulp-ruby-sass');
var shell = require('gulp-shell');
var slim = require('gulp-slim');
var source = require('vinyl-source-stream');
var streamify = require('gulp-streamify');
var uglify = require('gulp-uglify');
var watchify = require('watchify');
var lazypipe = require('lazypipe');
// Add md5 hashsums to assets
function revFiles(dest) {
return lazypipe()
.pipe(gulp.dest, dest);
}
var browserifyTask = function (options) {
// Our app bundler
var appBundler = browserify({
entries: [options.src], // Only need initial file, browserify finds the rest
debug: options.development, // Gives us sourcemapping
cache: {}, packageCache: {}, fullPaths: options.development // Requirement of watchify
})
.plugin(pathmodify, {
mods: [
pathmodify.mod.dir('npm', path.join(__dirname, 'node_modules'))
]
})
.transform(babelify, { presets: ['react', 'es2015'] })
// The rebundle process
var rebundle = function () {
var start = Date.now();
console.log('Building APP bundle');
appBundler.bundle()
.on('error', gutil.log)
.pipe(source('application.js'))
.pipe(gulpif(!options.development, streamify(uglify())))
.pipe(revFiles(options.dest)) // line 69
.pipe(notify(function () {
console.log('APP bundle built in ' + (Date.now() - start) + 'ms');
}))
.on("finish", function() { refreshView(options) });
};
// Fire up Watchify when developing
if (options.development) {
appBundler = watchify(appBundler);
appBundler.on('update', rebundle);
}
rebundle(); // line 82
}
gulp.task('deploy', function () {
browserifyTask({ // line 229
development: false,
src: './app/coffee/application.js',
dest: './public/dist/'
});
});
I'll be appreciated by your help
I know that for something like replace('a', 'b')
you need to pass the function and parameters seprately like .pipe(replace, 'a', 'b')
but is it possible to have something like this re-used with lazypipe?
.pipe(coffeelint.reporter('fail').on('error', function(){
gutil.beep();
gulp.run('lint');
}));
I'm using gulp 4 (which require every task to report on async completion)
on tasks with regular pipes you can just return the stream and gulp will watch the stream to finish.
with lazypipes, even that they working, gulp say:
[16:06:45] The following tasks did not complete: lint-sass
[16:06:45] Did you forget to signal async completion?
My code:
using lazypipe:
const sassLint = lazypipe()
.pipe(gulpSassLint)
.pipe(gulpSassLint.format);
...
gulp.task('lint-sass', function () {
return gulp.src(paths.sass)
.pipe(sassLint());
});
Regular:
gulp.task('lint-sass2', function () {
return gulp.src(paths.sass)
.pipe(gulpSassLint())
.pipe(gulpSassLint.format());
});
Thanks!
I'm using the solution from this issue to build a static site with gulpsmith (and handlebars). Now I have to preface this by saying that I'm still learning, and that I might be doing something stupid.
But having said that: I've been looking at this for a week now and cannot find any obvious mistakes, and was wondering if maybe what I'm trying to do is maybe just not possible with lazypipe.
As I said, I'm using a lazypipe to build a static site, and have narrowed the error down to my metalsmith/gulpsmith lazypipe (repo here):
'use strict';
/**
* Dependencies
*/
var config = require('../config').metalsmith;
var filePathTask = require('../util/filePath');
var gulpsmith = require('gulpsmith');
var handlebars = require('handlebars');
var lazypipe = require('lazypipe');
var relativePathHelper = require('../util/relativePath');
var site = require('../../site');
var templates = require('metalsmith-templates');
/**
* Local config
*/
config.templates.engine = 'handlebars';
config.templates.partials = {
'header': 'partials/header',
'footer': 'partials/footer'
};
/**
* Register handlebars helpers
*/
handlebars.registerHelper('relative_path', relativePathHelper);
/**
* Lazypipe
*/
var wrapper = function () {
return gulpsmith()
.metadata(site)
.use(filePathTask)
.use(templates(config.templates));
};
module.exports = lazypipe().pipe(wrapper);
The weird thing is that when building once this lazypipe works just fine. But when serving and watching for changes the pipe breaks down (so effectively after building more than once with the same lazypipe). It gives the following error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: ENOENT, open '/home/ismay/Github/cape/templates/<h2>Header</h2>
.html'
Now <h2>Header</h2>.html
is actually the content of the old header partial, before the changes were made. Instead of <h2>Header</h2>.html
it should actually be partials/header.html
(as defined in the lazypipe here). So it is substituting the partials file path with its content.
Am I using lazypipe wrong when I'm using it like this? Or is this not a lazypipe issue? I have tried the exact same steps without lazypipe in between and everything worked as expected.
It feels to me like this is some sort of caching issue, since the pipe has been used once already (when building the site to ./.tmp/
, before watching for changes and rebuilding after changes), and only errors out after its second use.
Trying this again, the original issue was closed abruptly.
The assumption that my question is a "Gulp" issue is wrong @OverZealous , in fact, I posted code that clearly uses lazypipe.
I can merge streams using either the merge or event-stream libraries, thats not the issue. At the moment I am using a simple function as a re-usable unit for the several Gulp tasks. This has been in use for several months. I thought it would be nice to use Lazypipe which was developed to be used as reusable units/ channels.
My question is; How can I create a reusable lazypipe channel for a complex task that I would like to use in several projects.
I am trying to:
1. Concat and compress a set of CSS files
2. Inject both the compressed and non-compressed files in a HTML template
3. Make this a usable lazypipe channel for re-use over a set of projects
I have this so far
return lazypipe()
.pipe(gulp.dest, output.non_compressed_path)
.pipe(plugins.concat, optionsObj.filename)
.pipe(plugins.csso, true)
.pipe(gulp.dest, output.compressed_path)
To Inject the above in HTML templates however, the lazypipe source would have to start with the HTML template, so piping the result of the above would not work as in:
// This has to starte with "gulp.src(templateName)" then pipe to below
.pipe(plugins.inject, gulp.src(cssFiles, {read: false}), {name: 'test'})````
Can someone point me in the right direction? Thanks
If you use lazypipe
at the end of a Gulp stream, the task will be properly executed, but it never finishes. If you run this task standalone this is not problematic; you will just not get the message on the comand line that the task finished. However if the task is used in a series it will cause depending tasks to wait forever.
Example code:
var lazy = lazypipe()
.pipe(uglify)
.pipe(gulp.dest(destination));
function task() {
return gulp
.src(glob)
.pip(lazy());
}
At first sight it seems related to #7, but there's actually something different going on.
I tracked the problem down to stream-combiner
not firing a finish
event and it seems that Gulp relies on that event.
I opened an issue on the stream-combiner
GitHub page:
dominictarr/stream-combiner#13
I guess you shouldn't have to change anything to your code, but you might want to follow up on that issue, so that you can update your dependencies when the issue gets fixed.
Is there a simple way to wrap lazypipe in a function and pass an argument?
I have for example:
var CSS = lazypipe()
.pipe(size, { showFiles: true, title: 'css' })
.pipe(gulp.dest, './build/css');
.pipe(minifycss)
.pipe(rename, { suffix: '.min' })
.pipe(size, { showFiles: true, title: 'css' })
.pipe(gulp.dest, './build/css');
however, i'd like ./build/css
to be passed with an argument. Any suggestions are appreciated.
Is there a way to use lazypipe
with gulp-filter
?
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var paths = gulp.paths;
var lazypipe = require('lazypipe')
var cssFilter = $.filter('**/*.css', {restore: true});
var endStream = function() {
this.end();
}
cssFilter.on("error", endStream);
exports.duplicateApp = lazypipe()
.pipe(cssFilter)
.pipe($.replace, ['#0492ff', '#008787'])
.pipe(cssFilter.restore)
The problem is related to that line
var cssFilter = $.filter('**/*.css', {restore: true});
it needs to be
.pipe($.filter,['**/*.css', {restore: true}])
But is there a way to write this differently, to get it working with lazypipe and still having the listeners/ restore function?
I thought about something similiar to this:
exports.duplicateApp = lazypipe()
.pipe(function(){cssFilter = $.filter; cssFilter.on("error", endStream); return cssFilter;}, ['**/*.css', {restore: true}])
.pipe($.replace('#0492ff', '#008787'))
.pipe(function(){return cssFilter.restore;})
But I 1) run into the same error and 2) cssFilter would not be available in the other pipe.
I am trying to:
I have this so far
return lazypipe()
.pipe(gulp.dest, output.non_compressed_path)
.pipe(plugins.concat, optionsObj.filename)
.pipe(plugins.csso, true)
.pipe(gulp.dest, output.compressed_path)
To Inject the above in HTML templates however, the lazypipe source would have to start with the HTML template, so piping the result of the above would not work as in:
// This has to starte with "gulp.src(templateName)" then pipe to below
.pipe(plugins.inject, gulp.src(cssFiles, {read: false}), {name: 'test'})
...
Can someone point me in the right direction? Thanks
If this lib is meant for Gulp and Gulp only, perhaps change the name to "gulp-lazypipe" so that it works better with gulp-load-plugins
?
Can we get rid the dependency for event-stream? There is a recent malicious attack on this dominictarr/event-stream#116. We can lock the version to [email protected].
Hi.
I have the problem with one WP theme ('Sage') which use lazypipe.
Here is the root of problem (it isn't related with lazypipe).
But gulp-sass v.2.3.2 didn't install normal to my Windows10x64 PC, so I want to use the ugly hack: "I also replaced & with #{"&"} in the mixin and now it seems to work fine."
.pipe(replace, '&:', '#{&}:')
How to replace all '&:' '#{&}:' before running all others pipe() in this theme's gulp function?
var cssTasks = function (filename) {
return lazypipe()
.pipe(function () {
return gulpif(!enabled.failStyleTask, plumber());
})
.pipe(function () {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(replace, '&:', '#{&}:') // (!) looks like don't work - the error is present
.pipe(function () {
return gulpif('*.scss', sass({
outputStyle: 'nested', // libsass doesn't support expanded yet
precision: 10,
includePaths: ['.'],
errLogToConsole: !enabled.failStyleTask
}));
})
.pipe(concat, filename)
.pipe(autoprefixer, {
browsers: [
'last 2 versions',
'ie 9',
'android 4'
]
})
.pipe(minifyCss, {
advanced: false,
rebase: false
})
.pipe(function () {
return gulpif(enabled.rev, rev());
})
.pipe(function () {
return gulpif(enabled.maps, sourcemaps.write('.'));
})();
};
Context is:
var merged = merge();
manifest.forEachDependency('css', function (dep) {
var cssTasksInstance = cssTasks(dep.name);
if (!enabled.failStyleTask) {
cssTasksInstance.on('error', function (err) {
console.error(err.message);
this.emit('end');
});
}
merged.add(gulp.src(dep.globs, {base: 'styles'})
.pipe(cssTasksInstance));
});
return merged
.pipe(writeToManifest('styles'));
});
Hi, I want something like the following:
var prodCss = lazypipe()
.pipe(gulp.dest, destLocation)
.pipe(gzip);
gulp.task('css', function() {
return gulp.src(cssSrc)
.pipe(gulpif(PROD, prodCss()))
.pipe(gulp.dest(destLocation))
});
When the build isn't prod, it just copies the CSS to destLocation. When it is, it copies in the CSS, then gzips it and copies that into destLocation. However, currently it doesn't do anything for the gulp.dest call in the lazypipe, so it will only copy in the gziped CSS files for the prod build.
Not in a lazypipe this will work with the multiple gulp.dest calls.
Can this be made to work?
Here is my gulpfile:
'use strict';
var browserSync = require('browser-sync');
var conf = require('./conf');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var lazypipe = require('lazypipe')
var path = require('path');
var rename = require('gulp-rename')
var sourcemaps = require('gulp-sourcemaps')
var uglify = require('gulp-uglify')
var src = conf.getFiles('assets')('js')
var dest = path.join(conf.paths.static, 'js')
var compressjs = lazypipe()
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(uglify())
.pipe(sourcemaps.write())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(dest))
function scripts(watch, compress) {
return gulp.src(src)
.pipe(gulp.dest(dest))
.pipe(function() {
return gulpif(compress, compressjs)
})
.pipe(gulpif(watch, browserSync.reload({stream: true})))
}
gulp.task('scripts', function() {
return scripts(false, false);
});
And when I run gulp scripts
I get the following error:
/Users/shawn/www/projects/skiftcreative/skift/app/themes/material/node_modules/lazypipe/index.js:11
throw new Error("Invalid call to lazypipe().pipe(): argument is not a funct
^
Error: Invalid call to lazypipe().pipe(): argument is not a function.
Remember not to call stream creation functions directly! e.g.: pipe(foo), not pipe(foo())
at validateStep (/Users/shawn/www/projects/skiftcreative/skift/app/themes/material/node_modules/lazypipe/index.js:11:10)
at Function.build.pipe (/Users/shawn/www/projects/skiftcreative/skift/app/themes/material/node_modules/lazypipe/index.js:36:4)
at Object.<anonymous> (/Users/shawn/www/projects/skiftcreative/skift/app/themes/material/gulp/scripts.js:17:4)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at /Users/shawn/www/projects/skiftcreative/skift/app/themes/material/gulpfile.js:16:5
I have read #3 but looking over my code, it looks correct. Basically I want to use gulp-if
to test if I want to do compression (passed as 'true' in another task). But on this part of the code:
var compressjs = lazypipe()
.pipe(sourcemaps.init())
the .pipe()
method seems to be undefined. looking at all the examples, as well as here https://github.com/robrich/gulp-if#works-great-with-lazypipe
Any idea? Thanks.
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.