ecomfe / esl Goto Github PK
View Code? Open in Web Editor NEWenterprise standard loader
License: BSD 3-Clause "New" or "Revised" License
enterprise standard loader
License: BSD 3-Clause "New" or "Revised" License
如题,在require.js里面data-main属性指向的文件这个文件会第一个被require.js加载。这样的话,在开发过程中就可以少一个script标签引入config文件。
<script data-main="js/config" src="js/require.js"></script>
在 ESL的配置文档 中,
map 的配置项实例:
require.config( {
// ...
// some/newmodule模块中,require('foo')实际引用到的是foo2模块
// some/newmodule为前缀匹配,some/newmodule/index对foo的引用行为也将引用foo2
'some/newmodule': {
'foo': 'foo2',
'foo/bar': 'foo1.2/bar3'
}
} );
是不是应该再在外添加一层?
如:
require.config( {
// ...
// some/newmodule模块中,require('foo')实际引用到的是foo2模块
// some/newmodule为前缀匹配,some/newmodule/index对foo的引用行为也将引用foo2
'map' : {
'some/newmodule': {
'foo': 'foo2',
'foo/bar': 'foo1.2/bar3'
}
}
} );
情况描述:
在以下的两个DEMO中,用 esl 加载的 echarts ,虽然控制台报出 'echarts/chart/line' not found (http status 404)
,但是似乎并不影响啥,图表仍旧绘制;而用requirejs 加载的那个DEMO,报错不会绘制图表。
说明:
esl:http://blog.supertree.me/demo/line.html
requirejs:http://blog.supertree.me/demo/line-require.html
问题:
require([Array],callback)
的处理是否是只要有一个依赖加载成功,即执行callback,前提条件是callback里只有一个param
,且依赖都打包在一个文件里,就如DEMO中那样:require([
'echarts',
'echarts/chart/line'
], function(ec) {
// code
});
That's all.
Thanks.
现在打包后,模块定义都是最规范的写法。
假如提供一个mini版本,去除路径解析、匿名模块的兼容等功能,文件体积势必会小很多,供打包后线上使用代码量会有明显减小
复现环境不太好弄,今天我修改ESUI时,跑测试始终出现这样的错误:
[MODULE_MISS]esui/Helper is not exists!
我的代码大概是这样的:
function Control(options) {
options = options || {};
var Helper = require('./Helper');
/**
* 控件关联的{@link Helper}对象
*
* @type {Helper}
* @protected
*/
this.helper = new Helper(this);
}
把var Helper = require('./Helper');
拿到构造函数外面,做成硬依赖就不会出这事了。根据断点,是先进入了这个构造函数,再进入Helper
的factory
执行,似乎软依赖放过的条件有些太过宽松,导致在依赖确实加载完以前代码被执行了
我估计和上次与你说的问题同一个,先留个底
如果在一个模块a中依赖了b c d e 多个其他的模块,
那么这个模块在调用require('b')时, require('b')之前的代码会被执行多次
//a.js
define(function(require){
console.log('ssssss');
require('b');
require('c');
require('d');
require('e');
});
在模块b c d e没有加载完之前会重复输入多次sssss
.replace(/require(\s_(['"'])([^'"]+)\1\s_)/g,
是不是多了个单引号?['"']
当define一个模块时,没有把依赖的模块作为回调函数的参数时,导致依赖的模块的factory函数不执行,例如:
//mod a file
define('a',[],function(){
console.log('a factory call');
});
//mod b file
define('b',[],function(){
console.log('b factory call');
});
//mod all file
define('all',['a','b'],function(a){ //这里参数没有b
console.log('all factory call')
})
/call
require(['all'], function() {
console.log('all callback');
})
//执行结果
a factory call a.js:2
all factory call all.js:2
all callback
//其中b factory call 没有执行
现在edp install pkg之后,会自动生成一个esl-config.json的文件,一个示例的格式如下:
{
"packages": [
{
"name": "esl",
"location": "lib/esl/0.0.1"
},
{
"name": "jquery",
"location": "lib/jquery/1.9.1",
"main": "./src/jquery.min.js"
},
{
"name": "tangram",
"location": "lib/tangram/1.3.7",
"main": "./src/tangram.min.js"
}
]
}
这个文件的内容应该是作为require.config
的一部分,esl
应该支持一个参数能够自动的加载这个文件。
foo -> bar -> tpl!x
empty
如果tpl!x
已经预先require并ready时
require(['foo'],callback)
时,callback被调用,但是未来foo模块将不存在require(['foo', 'empty'],callback)
时,callback不被调用原因是因为,modAutoDefine会对每个需要自动定义的模块进行modPrepare、modUpdatePreparedState、modTryInvoke调用。modUpdatePreparedState中,会尝试调用其依赖模块的modPrepare。如果模块包含resource依赖,modPrepare中会在尝试在resource加载完后重新调起modAutoDefine。当resource当前已经处于ready状态时,这个过程会马上发起。从而导致一个运行过程中,同一个模块的modUpdatePreparedState被重入。而modUpdatePreparedState中,对模块状态的写入没有做判断,从而导致模块状态可能从defined回退到prepared。
过程如下:
script onload -> modAutoDefine -> modPrepare(foo) -> modUpdatePreparedState(foo) -> modPrepare(bar) -> requireResource -> modAutoDefine -> modPrepare(foo) -> modUpdatePreparedState(foo) -> modTryInvoke(foo) -> modTryInvoke(foo)
由于:
所以,采用解决方案为:modUpdatePreparedState中,对模块状态的写入做判断
if (!modIs(id, MODULE_PREPARED) {
mod.state = MODULE_PREPARED;
}
我的理解没错的话,一个loader plugin的缓存是交由loader管理的,通过normalized resource id作为key。
那么,CSS的loader plugin,在缓存上,特殊场景似乎会出现一些问题。
假设标准的Facebook Quickling模式,将一个业务系统划分为N个模块,每个模块有自己依赖的css和js,且模块是 完全独立 的,那么进入一个模块时,步骤是:
可以看到,因为CSS有相互覆盖的问题,所以这里有一步 清理当前CSS 的步骤,会移除掉一些使用loader加载的<link>
元素。
那么当 A -> B -> A 这要的顺序进入时,第2次进入A模块,因为CSS资源被loader识别为缓存,loader plugin并不会起作用,也就不会重新把<link>
元素加入到document,导致CSS的错误。
这个问题就现在公司的业务系统来看并不是非常迫切需要的,但就通用性而言,应当去考虑这样的需求。
就解决方案而言,建议修改CSS loader plugin,让loader不做缓存,自己控制一个内部的缓存来处理。在加载CSS前先看看有没有href
符合要求的<link>
元素,没有的再看自己的缓存区里有没有。
比如页面中有如下打包后的脚本
<script>
define('a', ['require','a1','a2'], function (r) {
var a1 = require('a1');
var a2= require('a2');
return {
name: 'a'
}
});
define('b', ['require','b1'], function (r) {
var a1 = require('b1');
return {
name: 'b'
}
});
require(['a'], function (a) {console.log(a.name)})
</script>
因为只有 a�
模块被async require了, b
模块暂时还没有用到。这时, 不应该去请求 b
模块的依赖模块
目前貌似map
是在packages
之后处理的,这样的配置会产生加载错误
require.config({
baseUrl: 'src',
packages: [
{
name: 'lang-0.1',
location: '../dep/lang/0.1.0/src',
},
{
name: 'lang-0.2',
location: '../dep/lang/0.2.0/src',
}
],
map: {
foo: {
lang: 'lang-0.1'
},
bar: {
lang: 'lang-0.2'
}
}
});
是否需要考虑提前对map
的处理?
如果运行了多个async require,多次加载多个模块,而其中某个模块有错误时,可能其他async require的模块已经可以完成define,但是callback没有正常运行
原因是由于modAutoInvoke会对标记为自动定义的模块进行尝试定义。如果其中某个factory invoke出错,会中断,导致下一个模块不会进行尝试。
解决办法是,当某个factory invoke出错时,不将其invoking状态归位,下次modAutoInvoke时,运行到它,此时认为它还在运行,就会跳过,执行下一个。
另外,在IE上,由于script标签的onload不一定紧跟随在其运行完,中间可能穿插其他script标签的运行和onload,其顺序是混乱的。在createLocalRequire中,将modAutoInvoke调用置于nativeAsyncRequire调用后,保证nativeAsyncRequire能够执行,module defined listener被顺利挂接。
当直接require([‘url'])的时候报错,用requirejs是ok的,不知道对于只是想异步加载一个js文件这种场景有没有好的办法?
requireConfig结构如下, pkg什么的都省略。想所有的模块都映射到echarts-upgrade上,但是对于baseId为nirvana开头的模块引用的还是echarts.
{
map: {
'*': {
echarts: 'echarts-upgrade'
},
'nirvana': {
deprecated: 'nirvana/deprecated'
}
}
}
必须要这么写
{
map: {
'*': {
echarts: 'echarts-upgrade'
},
'nirvana': {
echarts: 'echarts-upgrade',
deprecated: 'nirvana/deprecated'
}
}
}
如下:
// main.html
require.config({
'baseUrl': 'src',
'paths': {
'tpl': 'common/tpl'
}
});
// common/tpl.js
define(function(require){
var filter = require('./filter');
});
期望 filter 的加载路径是 src/common/filter.js,而实际加载了src/filter.js
看见源码中提到“因为高级浏览器在devtool的console面板会报错,再throw一个Error多此一举了”。
实际并非多此一举,在 onerror 回调函数里可关闭某些界面元素(因为它依赖的JS未导入),另外当访问A站点不可达时,可继续尝试B站点,现实一个应用就是国外A站被GFW封闭(或高峰期不可达),转而向国内后备站点发请求。
虽然 require(deps, callback, errback) 第3个参数并非 AMD要求,但 requirejs 实现了这个接口,它不是同步throw Error,而是异步回调errback函数。
require([ 'main', 'ui' ])
对于上面的代码,在线上环境,main里面可能打包了ui的define,额外的ui请求是无意义,浪费网络资源的。虽然系统运行的正确性没问题。所以,增加_noRequest
配置项。
说明:
Array.<string>
,每一项规则和AMD的配置项保持一致:prefix match。当define一个模块时,没有把依赖的模块作为回调函数的参数时,导致依赖的模块的factory函数不执行,例如:
//mod a file
define('a',[],function(){
console.log('a factory call');
});
//mod b file
define('b',[],function(){
console.log('b factory call');
});
//mod all file
define('all',['a','b'],function(a){ //这里参数没有b
console.log('all factory call')
})
/call
require(['all'], function() {
console.log('all callback');
})
//执行结果
a factory call a.js:2
all factory call all.js:2
all callback
//其中b factory call 没有执行
通过map或paths映射可以使一个文件拥有不同的module id, 这样require时会使得该模块初始化多次.
这各情况应该是框架来处理(比如将所有模块变成绝对的http地址作为module id) ? 还是由用户(如果用户碰到, 这是一个大坑)来解决?
开发者您好!我在使用esl 2.0.2的过程中发现了一个bug,即使用require函数时,模块的文件名中如果包含“.”,则模块可以加载成功,但无法执行成功后的回调函数。例如“jquery-1.11.1”。烦请核实。谢谢!
正常文档里使用
var name = 'book/List';
require(name);
这一步就不好用了。。。
特别在er里使用loadSubAction时,若简明的复用loadSubAction方法,提供action对应的name,那么require(name)应该能正确返回值的。
请看看这个是否需要更改。
使用esl 1.6.10。如下例:
<!DOCTYPE html>
<html>
<body>
<script src="http://s1.bdstatic.com/r/www/cache/ecom/esl/1-6-10/esl.source.js"> </script>
<script type="text/javascript">
require( ['x1'], function (x1) { x1(); } );
</script>
</body>
</html>
x1.js:
define(function (require) {
console.log('visit x1');
var x2 = require('./x2');
return function () {
console.log('in x1 fn');
x2();
};
});
x2.js:
define(function (require) {
console.log('visit x2');
return function () {
console.log('in x2 fn');
var x1 = require('./x1');
};
});
输出为:
visit x2
visit x1
in x1 fn
in x2 fn
visit x1
visit x2
如换requireJS,则输出为预期的:
visit x2
visit x1
in x1 fn
in x2 fn
目录结构
/a/b/c.js
/a/d/e.js
/f.js
require.config 配置如下:
baseUrl: './a'
/index.html
require(['b/c'], function(){})
/a/b/c.js
require('../d/e');
/a/d/e.js
require('../../f');
会出现 /a/b/f.js 的请求,期望应为 /f.js,换 require.js 测试如期
找了下几个统计代码执行覆盖率的库,都不能很好地配上AMD loader工作,blanket要用一个自带的requirejs所以根本跑不了esl控制的代码
最好esl能提供一个特殊的版本,使用该版本可以拥有和esl一样的接口,但是加载的文件均会被加上覆盖率统计功能
志龙那有一个覆盖率的脚本,可以和他商量下?
简单试用了一下,就发现了不少问题:
1.里面的正则定得有点“随便”,如我把path的某个key定义为$,然后就跑不了
2.按假设主入口为main,main require page, page依赖base,base依赖app,然后会发现app和base的factory都没有跑起来,只有page会跑
3.然后我都不敢再试下去了orz
如题。
建议保留loader的支持,有些页面使用了seajs/modjs作为加载器,建议esl保留自定义loader功能,这样第三方代码能够可以有自定义加载器来管理模块。
源码里面有个 dist/output 目录自动化处理一下压缩版本的输出?
loadplugin tpl.js 只能自己写一个吗,有没有在用的提供呢
在一个模块内,使用同一个已经初始化完成的plugin加载多个resources时,只会加载第一个resource,后面的resources无法加载。从而导致当前模块的初始化hang住,无法完成初始化。
问题: esl 不能有效 加载 jquery 和jquery ui。
说说背景:因为我要使用echart,后来又要使用zrender,所以就使用了esl。
后来又要使用 jquery ui,所以想继续使用 esl 来加载 jquery ui【备注,之前jquery一直是静态标签加载的】。
因为 jquery ui的需要, 所以改为 amd 方式 加载 jquery,
但是 require之后, 在浏览器中看页面代码, jquery 和 jquery ui的相关代码文件也都正确加载了,script标签都正确,但就是没有 那个 $, jQuery变量, 还有 jquery ui的相关部件 函数也没有加载到jquery的 fn中。且也不报错。
后来偶然机会试了网上的例子, 又在自己的 程序里试了 require.js 这个库,发现 jquery 和jquery ui的部件 可以正常使用了, 再换回 esl.js, 又不行了。再换回 require.js,又可以了。
所以我的初步判断是 esl 似乎在某些方面 有些不完备。
我不是js 专家,也是把 esl 当作 require.js 来使用的,所以这种差别, 还是有些困惑的。
下面贴上我的配置:
var zr, tl;
require.config({
//baseUrl: 'resource/js',
packages: [
{name: 'jquery', location: 'resource/js', main: 'jquery'},
{name: 'jqueryui', location: 'resource/js/jqueryui/ui', main: 'jqueryui' },
{ name: 'zrender',
location: 'resource/js/zrender',
main: 'zrender'
}
]
});
require([ 'zrender/zrender'
,'zrender/shape/Circle'
,'zrender/shape/Rectangle'],
function(zrender,_, _, timeline) {
//this.zrender = zrender;
this.zr = zrender.init(document.getElementById('cmain'));
}
);
require(['jquery'], function($){ //虽然网上有资料说这里要jquery,但试了 jquery/jquery 在require.js 时 也可以成功加载。
console.log($); //使用 require.js的时候,这里可以运行到,esl的时候不行,且不报错。
});
require(['jqueryui/dialog'], function(dialog){
console.log(dialog); //使用 require.js的时候,这里可以运行到,esl的时候不行,且不报错。
});
情况比较特殊,当modPreAnalyse
中pluginModuleIds
与modules
中同时存在同一个pluginA
,而且此时pluginA
正处于loading
状态,会导致pluginA
无法被正确地被定义(在loadModule
中第一判断就是是否处于loading
状态,如果是,直接return
导致对应的nativeReuqire
的回调函数不能被执行,不会继续进行modAnalyse
)
遇到了两种场景都会导致此问题:
require
分别引用moduleA
与moduleB
,两者都是使用了pluginA
,在IE7/8下(6没测),不稳定出现pluginA
无法正确被定义的情况,非IE还OK(define
函数的执行和completePreDefine
不对应)moduleA
未combine
,moduleB
做了combine
,所有浏览器下稳定出现pluginA
无法正确被定义的情况尝试了下,在modPreAnalyse
中在调用nativeRequire
之前对pluginModuleIds
与modules
进行去重,或者再简单点在loadModule
中将loading
与modExists
的判断对调下位置...
问题能修复就是不知道会不会引起其它bug...怕怕...(>_<)...
你好,关于currentlyAddingScript,我看到你是借鉴require.js中的写法。
将node赋值于currentlyAddingScript,是为了产生闭包这么写的么,注释中写道在ie6-8中因为某些缓存,导致script执行先于appendChild完成,不知道这个会导致什么bug呢?困扰了一晚上,还是没能想明白,希望予以解答,多谢多谢!
项目结构:
/
foo/
useExports.js
test.htm
useExports.js的内容:
define(
function(require, module, exports) {
exports.x = 1;
return exports;
}
);
test.htm的内容:
<script>
require(
['foo/useExports'],
function(useExports) {
console.log(useExports);
}
);
</script>
控制台中输出{ x: 1 }
控制台中输出{ id: "foo/useExports", factoryArgs: Array[3], hardDeps: Array[3], deps: Array[0], factory: function… }
在exports
中有太多的信息,这些信息是否应该在module
参数中?
该模块是否已经在生产环境使用?是否有应用的页面url参观学习下!
你好,esl可以支持text.js、domready.js和image.js吗,如果没有,有计划做吗,谢谢。
比如 package ei
,加载其 main 模块时,得到 define('搞错了的具名 id', ... )
。具名 id 与 ei/main 并不匹配,因而出错。但是 esl
并没有在报错信息中明确地给出此出错原因,难于排查。
问题版本2.0.2
示例:
require.config({
'baseUrl': 'src',
'bundles': { 'inf': ['er/Action', 'moment', 'etpl'] },
'packages': [
{
'name': 'eoo',
'location': '../dep/eoo/0.1.1/src',
'main': 'main'
},
{
'name': 'er',
'location': '../dep/er/3.1.0-beta.6/src',
'main': 'main'
},
{
'name': 'etpl',
'location': '../dep/etpl/2.1.2/src',
'main': 'main'
},
{
'name': 'mini-event',
'location': '../dep/mini-event/1.0.2/src',
'main': 'main'
},
{
'name': 'moment',
'location': '../dep/moment/2.7.0/src',
'main': 'moment'
}
]
});
对于er/Action
的处理是正确的, 而对于moment
和etpl
依旧发出了请求.
将bundles
的配置稍做修改就正常了.
'bundles': { 'inf': ['er/Action', 'moment/moment', 'etpl/main'] },
require.config
里有个东西很重要,就是开发时期的src
编译后变成了啥目录,通常是asset
,但加过版本号或者MD5就不一样了。
比如要创建一个图片:
var img = document.createElement('img');
img.src = 'src/xxx';
这个src/xxx
在编译后肯定要变,因此代码可能这么写:
var root = require.config('baseUrl');
img.src = root + '/xxx';
这个应该是最保险的了,其它的写Processor
之类的又麻烦又不靠谱
有这样的代码
<script>
define({});
</script>
之后其它匿名模块的定义都会出错
当然上面的代码并不会真的这么写,可能是在一个.js
文件中,然后被<script>
标签引入。因此esl遇到匿名模块且无法确定模块名称时,是否适当地采取抛弃或其它措施?
请问 如何做多个请求concat?
如题
function loadModule(moduleId) {
// 感觉这里的检测做法并不安全,还是可能出现多个module同时进行loading的极端情况
// loadingModules[moduleId]的检测和设置分散在两条语句
if (loadingModules[moduleId] || modModules[moduleId]) {
return;
}
loadingModules[moduleId] = 1;
我很难用文字描述这个情况,直接用代码表示吧。
首先是s.js
文件:
define('tpl', [], function () {
console.log('define tpl');
var ready = false;
return {
setReady: function () {
ready = true;
},
load: function (resourceId, parentRequire, load) {
console.log('load ' + resourceId + ' with tpl');
// 注意这个`setTimeout`,这是我认为esl2有BUG的关键
setTimeout(function () {
console.log('ready is ' + ready);
if (!ready) {
throw new Error('not ready');
}
load();
}, 1000);
}
};
});
define('common', ['tplReady', 'tpl!list'], function () {
console.log('define common');
});
define('tplReady', ['tpl'], function (tpl) {
console.log('define c');
tpl.setReady();
});
然后是html
文件:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="esl2.js"></script>
</head>
<body>
<script src="amd/s.js"></script>
<script>
require.config({
baseUrl: 'amd'
});
require(['common'], function () {
console.log('ok');
});
</script>
</body>
</html>
在使用esl2
的时候,输出为:
s.js:2 define tpl
s.js:10 load list with tpl
s.js:12 ready is false
s.js:14 Uncaught Error: not ready
在使用esl1
的时候,输出为:
s.js:2 define tpl
s.js:10 load list with tpl
s.js:27 define c
s.js:12 ready is true
s.js:23 define common
home.htm:15 ok
做一些简单的分析,从现象上来总结的话,当一个插件中有异步操作时,esl2
会等待直到load
实际完成(回调了callback
)之后,才会去调用下一个依赖的factory
。而esl1
则不会有这个等待,在插件异步操作的时候,esl去执行了后续的依赖,且因为后续依赖执行更快,setReady()
被调用了,没有出错
我个人感觉esl1的行为是正确的
先叫上人:@errorrik @leeight @firede @Justineo @wangyang0123 @chriswong @PengXing @treelite
最近requiejs把factory
改成第一次require
时才执行了,所以我觉得这个话题我们也可以讨论一下
factory
在define
时就执行主要会存在这样的问题:
当有些依赖是“概念上”而非“编码”上存在时,如果对模块进行合并,且在
factory
执行中直接依赖这些“概念依赖”,则会出错
此类问题很容易在shim一类的模块上出现,以es5shim
为例:
foo.js
:
define(function () {
// forEach在es5shim中
getArray().forEach(...
});
main.html
:
<script>
require(['es5shim'], function (es5shim) {
es5shim.enable(); // 假设shim必须手动启用
require('foo');
});
</script>
由于main.html
作为唯一的入口,会保证es5shim
已经加载并完成了对原生对象的扩展,所以在正常使用中并不会出错。
但如果把es5shim
和foo
合并在一起,则一定出错。
此问题可以通过延迟factory
的执行来实现,当require('foo')
执行时es5shim
由main.html
保证肯定已经准备完毕。
如果把factory
延迟执行,模块管理会非常类似于CMD,但又和CMD不同。CMD是通过对源码分析,将局部require
都改为全局的,将同步代码改为异步的来实现,可能存在一些问题:
require
后,可能函数执行一半要进行远程脚本的加载callee
的可能就直接挂了因此在AMD的基础上实现延迟的factory
执行并不代表我们使用了CMD
require
可能代表着一个或一系列的factory
的执行,且这个执行时间很可能和用户的操作路径相关,函数执行时间变得不那么可控,性能监控的数据的分析难度也随之加大loader
会不会为之有一些额外的负担,目前不明由于业务项目中很容易遇到本文最前面说的情况,因此我觉得延迟factory
执行是一个切实的需求
我建议再多一个esl-delayed.js
的文件,不影响当前esl
的实现,至于代码怎么复用,这是小问题
代码中存在s///g类似的正则表达式时,匹配注释会被匹配到,后续代码中require不会被检测到,导致运行时找不到模块
如:var reg = s///g; require('xxx'); 运行时提示module xxx missing
如果在一个script中包含模块定义时
<script>
define('a', ['a1','a2'], function (a1, a2){ ... });
</script>
esl将马上发起对依赖模块 a1
和 a2
的请求
但是可能模块只是预定义,未马上使用,可能在未来的某个时候才会用上。所以,期望在 a
模块被 async require 时,才发起对依赖模块的请求
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.