web-infra-dev / garfish Goto Github PK
View Code? Open in Web Editor NEWA powerful micro front-end framework 🚚
Home Page: https://www.garfishjs.org
License: Other
A powerful micro front-end framework 🚚
Home Page: https://www.garfishjs.org
License: Other
get error
let treeWalker = document.createTreeWalker(
document,
NodeFilter.SHOW_ELEMENT,
{ acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
false
);
reason
document is a proxy object and cannot be used as a Node node type
none
yarn
none
vueBridge is a tool function for vue sub-app provided by garfish. Currently there are some problems as follows:
It is best to divide bridge for vue 2 into 3 development packages, so that I only need to care about the vue version used by my current business, and it is easier to pass parameters, and it is also more convenient for developers to maintain.
No response
No response
what?
npm
win 10
问题
目前 garfish 和 remote-module 的 externals 配置,均需要先引入依赖再设置,使得主应用难以做懒加载
目前的写法:
setExtenals({
react: require('react'),
});
期望的使用方式
支持懒加载
setExtenals({
react: () => import('react'),
// 或者
react: () => require('react'),
});
可能的解决方式
子应用使用 amd 格式,使用自定义的 define 函数执行
以下为示例,可能没有正确实现 amd loader 格式
const exec = (code: string) =>
new Promise((resolve) => {
async function define(depNames: string[], factor: () => any) {
const deps = await Promise.all(depNames.map((depName) => externals[depName]()));
resolve(factor(...deps));
}
const func = new Function('define', code);
func(define);
});
问题
目前 garfish 使用的是 commonjs 格式,需要想办法兼容
目前官网文档里面的内容太少,也没有具体的一些demo可以参考
复现代码和结果
问题结果
无法正常获取内容
问题原因
none
npm
System:
OS: macOS 12.2.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 92.13 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.13.1 - /usr/local/bin/node
Yarn: 1.22.10 - ~/.npm-global/bin/yarn
npm: 8.5.2 - ~/.npm-global/bin/npm
Browsers:
Chrome: 100.0.4896.60
Firefox: 98.0.2
Safari: 15.3
npmPackages:
garfish: ^1.4.4 => 1.4.4
假设存在下列html entry:
<!-- foo.html -->
<head>
<link href="./base.css" />
</head>
其中 base.css 的内容是:
// base.css
@import "./box.css";
注意,其@import语句没有使用标准的 url() 格式,这是允许的。
最终主应用能够正确摘录出base.css,并创建 <style> 标签容纳其内容。
但 box.css 的路径没有处理为相对于 foo.html,最终解析为相对于主应用路径,大概率404。
从 https://github.com/modern-js-dev/garfish/blob/main/packages/loader/src/managers/style.ts#L4 显然可见并未处理这种语法。
https://github.com/yanni4night/garfish-issue-reproduction/tree/issue-446
npm
System:
OS: macOS 12.2.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 63.02 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.13.1 - /usr/local/bin/node
Yarn: 1.22.10 - ~/.npm-global/bin/yarn
npm: 8.5.2 - ~/.npm-global/bin/npm
Browsers:
Chrome: 100.0.4896.60
Firefox: 98.0.2
Safari: 15.3
npmPackages:
garfish: ^1.4.4 => 1.4.4
example
const fetchInstance = window.fetch;
Garfish.run({
loader: {
fetch: fetchInstance,
},
});
No response
No response
可以通过官网 Demo 这里复现:https://stackblitz.com/edit/garfish-demo?file=sub%2Fpublic%2Findex.html 在这个文件 的 body 里加一行
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
https://stackblitz.com/edit/garfish-demo?file=sub%2Fpublic%2Findex.html
pnpm
System:
OS: macOS 12.4
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 160.57 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm
Browsers:
Chrome: 102.0.5005.115
Safari: 15.5
npm
garfish: 1.8.2
我看:
__export(exports, { reactBridge: () => reactBridge, vueBridge: () => vueBridge });
是否还不支持angula框架?
This issue provides visibility into Renovate updates and their statuses. Learn more
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@babel/core
, @babel/plugin-proposal-class-properties
, @babel/plugin-proposal-decorators
, @babel/plugin-transform-react-jsx
, @babel/plugin-transform-runtime
, @babel/preset-env
, @babel/runtime
, @testing-library/react
, @vue/cli-plugin-babel
, @vue/cli-plugin-eslint
, @vue/cli-service
, antd
, babel-eslint
, babel-loader
, classnames
, core-js
, css-loader
, element-ui
, eslint
, html-webpack-plugin
, jest-fetch-mock
, less-loader
, mobx
, mobx-vue
, react
, react-app-rewired
, react-dom
, react-router-dom
, react-shadow-dom-retarget-events
, regenerator-runtime
, style-loader
, ts-loader
, vue
, vue-router
, vue-template-compiler
, vuex
, webpack
, webpack-cli
, webpack-dev-server
)@types/jest
, jest
)@typescript-eslint/eslint-plugin
, @typescript-eslint/parser
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
@docusaurus/core
, @docusaurus/plugin-ideal-image
, @docusaurus/preset-classic
)react
, react-dom
)TS -> https://github.com/modern-js-dev/garfish/blob/master/packages/bridge/src/reactBridge.ts
skip
npm
skip
when run pnpm build. its will throw error
BTW, the Validations's docs is not found
https://github.com/modern-js-dev/garfish/tree/main
pnpm
https://github.com/modern-js-dev/garfish/blob/main/package.json
虽然Garfish声称支持esModule,但应该是支持其语法,获取provider仍然依赖 __GARFISH_EXPORTS__ 变量,在不使用 @garfish/bridge 的情况下,需要如此导出:
if (window.__GARFISH__ && typeof __GARFISH_EXPORTS__ === "object" && __GARFISH_EXPORTS__) {
__GARFISH_EXPORTS__.provider = provider;
}
显然,这与UMD格式下如出一辙。如果说UMD环境需要检测window新挂载属性不那么靠谱,必须使用 __GARFISH_EXPORTS__ 辅助的话,那么ESM本身就自带**导出**语义,本来不需要多此一举依赖额外的变量:
export const provider = () => {
return {
render,
destroy() { },
}
};
目前Garfish的实现,应该说面向ESM转译成的CommonJS更友好,对 @garfish/bridge 过度依赖了。
以上问题可通过 https://github.com/yanni4night/garfish-issue-reproduction/tree/issue-447 复现
考虑存储 https://github.com/modern-js-dev/garfish/blob/main/packages/core/src/module/esModule.ts#L201 的 resolve 结果。这里可以直接获取到 Promise<{ provider }>。
No response
No response
一堆报错,能不能提高一下你们框架代码的质量和稳定性
一堆报错,能不能提高一下你们框架代码的质量和稳定性
pnpm
一堆报错,能不能提高一下你们框架代码的质量和稳定性
When I use garfish routing, the API is somewhat similar to vue route, but there is some confusion in the query handling
let name;
router.push({
path: '/test',
query: {
name
}
})
// vue location.href
http://localhost:8080/test
// garfish location.href
http://localhost:8080/test?name=undefined
undefined
doesn't make much sense in terms of paths and adds judgment to processing, so expect it to be filtered out by default
We set the default filter and then provide the relevant custom configuration externally, overriding the default method, for example by passing in a custom stringifyQuery via options
No response
@garish/loader提供一个自定义fetch逻辑的接口,业务根据需要设计一个比较特殊的请求函数,然后通过loader暴露接口设置业务fetch,request执行原生fetch前,先判断业务fetch是否存在且执行是否返回结果,如果是就使用该结果执行后续非fetch的操作,否则就执行原生fetch。
文档业务会html中嵌入一个script标签对子应用的modulejs进行预加载,预加载的js资源会用一个变量存放到全局,即使js资源加载完成了,执行Garish.loadApp时,loader还是会用fetch去请求一遍modulejs资源,此时实际上完全可以用业务预加载的modulejs资源,这里的再次请求是没有必要。因此,这里需要在loader request的时候禁止loader内原生的fetch功能,然后使用业务自己生成的结果执行fetch后续的工作。
在@garish/loader中,可以如下实现
export interface IBusinessFetch {
(url, config)?: Promise<{
code: string;
result: { url: string; };
mimeType: {
type: string;
subType: string;
}
}>
}
let businessFetch = noop;
export function setBusinessFetch(fn: IBusinessFetch) {
businessFetch = fn;
}
function checkoutFetchResult(result) {
// 检测result数据是否符合要求
}
async function request(url, config) {
try {
const businessFetchResult = await businessFetch();
// 检测业务返回的数据是否符合loader需要
if (checkoutFetchResult(businessFetchResult)) {
return businessFetchResult;
}
} catch (err) {
console.log(...)
}
const result = await fetch(url, config || {});
// 执行原request逻辑
}
业务使用使用package-patch,在安装依赖时修改node_modules中@garish/loader的代码,这个方式太hack,每次升级garish都要重新开发一个patch文件,当@garish/loader的request操作有break change时很容易导致业务这边出现异常。
No response
// 独立运行可以正常触发回调,在微前端环境无法正常触发
window.onmessage = function () {
// 可以正常获取微前端应用回调
}
将 dom 零级事件转换成,addEventListener
window.addEventListener('message',() => {
})
https://github.com/modern-js-dev/garfish/tree/main/dev
pnpm
System:
OS: macOS 11.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 310.52 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.18.3 - ~/.nvm/versions/node/v14.18.3/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 6.14.15 - ~/.nvm/versions/node/v14.18.3/bin/npm
Browsers:
Chrome: 100.0.4896.88
Safari: 14.1.2
npmPackages:
garfish: 1.5.2
In browser-vm, the main field indicates the cjs exports however it does not exist in package published to npm.
看了微信的文章,https://mp.weixin.qq.com/s/L9wbfNG5fTXF5bx7dcgj4Q 目前看下来方案跟 qiankun 大同小异
背景
emotion 等 css-in-js 库在生产环境下默认会使用 CSSStyleSheet 添加样式,而不是直接在 style 元素中添加文本,这样可以提高性能
问题
目前 garfish 的沙盒机制会在子应用卸载的时候从 head 中移除 style 等元素,等重新进入子应用的时候将之前移除的元素重新添加回 head
然而 CSSStyleSheet 存在个问题,当从 dom 中移除 style 元素后,上面的 sheet 属性会变为 null,导致将 style 标签重新添加回去后,样式会丢失
可能的解决方案
在移除 style 元素之前将上面的样式保存下来,等重新添加的时候将之前保存的样式恢复回去
window.onload = function () {
let root = document.querySelector('#root');
root.addEventListener('click',(event)=>{
console.log(event instanceof MouseEvent); // result is false
// expect is true
});
}
none
pnpm
System:
OS: macOS 12.4
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 46.05 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.15.0 - ~/.nvm/versions/node/v16.15.0/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 8.5.5 - ~/.nvm/versions/node/v16.15.0/bin/npm
Browsers:
Chrome: 102.0.5005.61
Safari: 15.5
npmPackages:
@garfish/es-module: workspace:* => 1.7.2
garfish: workspace:* => 1.7.2
// main.ts
import { vueBridge } from '@garfish/bridge'
import { createPinia } from 'pinia'
import { createApp, h } from 'vue'
import App from './App'
import { newRouter } from './router'
const pinia = createPinia()
export const provider = vueBridge({
createApp,
rootComponent: App,
appOptions: () => {
return {
el: '#app',
render: () => h(App)
}
},
handleInstance: (vueInstance, { basename }) => {
vueInstance.use(newRouter(basename))
vueInstance.use(pinia)
}
})
if (!window.__GARFISH__) {
const app = createApp(App)
const router = newRouter('/')
app.use(router)
app.use(pinia)
app.mount('#app')
}
https://gitee.com/jh_shot/micro-template
pnpm
System:
OS: Windows 10 10.0.22000
CPU: (12) x64 Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz
Memory: 5.39 GB / 15.84 GB
Binaries:
Node: 16.14.2 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.18 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.5.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22000.120.0), Chromium (101.0.1210.53)
Internet Explorer: 11.0.22000.120
when using macOS Monterey, use pnpm install deps, gyp compiler an error, error message: /src/cld.cc:9:12: error: no member named 'unexpected_handler' in namespace 'std' │ using std::unexpected_handler;
.
I think it was a problem with node-cld, so I adjusted the node-cld dependency to 2.7.1 and it went through the build.
related issue: dachev/node-cld#66
so, please update the cld dependencies
https://github.com/modern-js-dev/garfish.git
pnpm
System:
OS: macOS 12.3.1
CPU: (8) x64 Intel(R) Core(TM) i7-4710MQ CPU @ 2.50GHz
Memory: 105.31 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 18.6.0 - /usr/local/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 8.14.0 - /usr/local/bin/npm
Browsers:
Chrome: 103.0.5060.134
Safari: 15.4
目前garfish文档内容较少,而且部署部分几乎空白,所以大佬们可以出一份部署相关的文档供学习嘛?蟹蟹
No response
No response
Garfish bridge support react18
none
pnpm
pnpm
every example
npm
System:
OS: macOS 11.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 4.86 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.18.3 - ~/.nvm/versions/node/v14.18.3/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 6.14.15 - ~/.nvm/versions/node/v14.18.3/bin/npm
Browsers:
Chrome: 100.0.4896.75
Safari: 14.1.2
npmPackages:
@garfish/bridge: ^1.4.0 => 1.4.0
garfish: 1.4.4
官方大大,非常感谢你们辛苦付出!
子应用使用了 vue3 + vite,但是没办法接入进去。想问一下,是否支持 vite?官方有什么建议嘛?
目前模块联邦导致子应用必须异步引入,那render过程就一定是异步的,所以看provider 的 render如果能支持promise的话,Garfish的生命周期才更准确吧
callRender(provider, isMount) {
if (provider && provider.render) {
return provider.render({
appName: this.appInfo.name,
dom: this.rootElement,
basename: this.appInfo.basename,
appRenderInfo: { isMount },
props: this.appInfo.props
});
}
}
...
try{
const { asyncScripts } = await this.compileAndRenderContainer();
const provider = await this.getProvider();
if (!this.stopMountAndClearEffect())
return false;
await this.callRender(provider, true);
this.display = true;
this.mounted = true;
this.context.activeApps.push(this);
this.hooks.lifecycle.afterMount.emit(this.appInfo, this, false);
await asyncScripts;
No response
No response
子应用的加载无可避免是异步的,需要消耗一定的时间,但页面的路由变更在有脚步触发、用户操作(点击链接、点击前进返回按钮)之下,往往是“实时”变化的,这需要框架能正确(并尽可能及时地)处理最后一次用户的导航请求,即应用的最终状态需要匹配页面最终的路由,无论之前经过过多少次其它路由跳转。
Garfish对于render和destroy这两个hook认为其为同步函数(勘误?#441),这省去了不少异步并发处理复杂度,但对于provider,支持其为async函数,@garfish/bridge 的 loadRootComponent 异步函数也证明了这一点。
假设子应用foo带有一个1000ms延时的provider,而子应用bar没有延时。现在如下 快速 导航路由:
/ -> /foo -> /bar -> /foo
上面的“快速”,用以模拟foo还未完成provider异步解析的情况。
虽然由于中间bar的干扰,foo被取消,但最终路由停留在/foo,仍然要求foo能继续挂载。
目前现状是,foo 的 active 为false一次后,没能继续最终的渲染,如果在开发模式下,可以看到控制台的warning:
The app "foo" rendering process has been blocked
我猜测是代码在处理并发环节的状态同步有一定问题,此现象可用demo轻易复现。
https://github.com/yanni4night/garfish-issue-reproduction/tree/issue-448
npm
System:
OS: macOS 12.2.1
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 92.13 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.13.1 - /usr/local/bin/node
Yarn: 1.22.10 - ~/.npm-global/bin/yarn
npm: 8.5.2 - ~/.npm-global/bin/npm
Browsers:
Chrome: 100.0.4896.60
Firefox: 98.0.2
Safari: 15.3
npmPackages:
garfish: ^1.4.4 => 1.4.4
// in sub app
window.a = '123';
console.log((new Function("return window.a"))()); // get undefined
请提供angular子应用的例子 或者文档说明!
谢谢!
主应用不支持框架路由,只能使用garfish router
官方demo
pnpm
"garfish": "^1.4.0",
vm 沙箱应用缓存模式下清除 dom 副作用里列表内存泄漏:
复现条件
问题原因
!this.rootElement.contains(parentNode)
判断始终为 false如何解决
https://github.com/modern-js-dev/garfish/tree/main/dev
pnpm
System:
OS: macOS 11.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Memory: 310.52 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.18.3 - ~/.nvm/versions/node/v14.18.3/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 6.14.15 - ~/.nvm/versions/node/v14.18.3/bin/npm
Browsers:
Chrome: 100.0.4896.88
Safari: 14.1.2
npmPackages:
garfish: 1.5.2
GarfishBrowserSnapshot plugin use global variables, causing sub app configurations to pollute each other.
A variable is used in the GarfishBrowserSnapshot plugin to identify whether an application has enabled snapshot sandbox mode, but unfortunately, it is a global variable, which causes the sub-application to be loaded later to be polluted by the previous sub-application,affecting the initial state of the plugin.
For example, if the previous app closes the snapshot sandbox, the apps loaded later will also be judged to close the sandbox because the global variable has been marked as false, which will result in an application initialization error, as a result, the post-loaded sub-application snapshot sandbox is invalid.
reproducible in the situation described above
npm
System:
OS: macOS 10.15.7
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 408.61 MB / 32.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 16.13.0 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 8.1.0 - /usr/local/bin/npm
Browsers:
Chrome: 100.0.4896.88
Safari: 15.4
npmPackages:
@garfish/es-module: 1.5.0
garfish: workspace: 1.5.0
类似于vue的keep alive,在不同子应用之间来回切换时,能够缓存页面
类似于vue的keep alive,在不同子应用之间来回切换时,能够缓存页面
No response
No response
目前对于需要服务端渲染的巨石应用也希望做一个微前端类似拆分
支持SSR
No response
No response
andt 的select 组件 或者 rc-selector ,开展下拉 options 列表的时候,始终挂载在主应用的html下,不会在对应的子应用下,导致开启严格隔离的时候展开的 options 列表会失去样式
@garfish/bridge 1.3.0
yarn
System:
OS: macOS 12.0.1
CPU: (8) arm64 Apple M1
Memory: 88.14 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.4.2 - /usr/local/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 7.18.1 - /usr/local/bin/npm
Browsers:
Chrome: 97.0.4692.99
Safari: 15.1
npmPackages:
garfish: workspace:* => 1.3.0
1)基座项目设置了共享依赖
Garfish.setExternal({
react: React,
"react-dom": ReactDOM,
"react-router-dom": ReactRouterDom,
});
2)子项目 webpack 中配置了 externals
externals: {
react: "React",
"react-dom": "ReactDOM",
"react-router-dom": "ReactRouterDOM",
},
3)加载子项目时,会提示如下错误
[Garfish warning]: Package "ReactDOM" is not found
[Garfish warning]: Package "React" is not found
npm
System:
OS: macOS 12.4
CPU: (8) x64 Apple M1 Pro
Memory: 17.45 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 12.22.12 - /usr/local/bin/node
Yarn: 1.22.18 - /usr/local/bin/yarn
npm: 8.6.0 - /usr/local/bin/npm
Browsers:
Safari: 15.5
If many sub app has same dependency, Like a ui framework, we would like to move it into external with Garfish.setExternal
to avoid duplicate bundle.
But if main app not need it, maybe we dont wanna load it first time in main app, but we need to load it before sub app mount.
So maybe Garfish.setExternal
can support Lazyload ?
For example, we can do like its.
in main app:
// avoid ambiguity between Garfish.setExternal
Garfish.setLazyExternal({
'mobx-react': () => import('mobx-react'),
});
in sub app:
export const provider = reactBridge({
el: '#root', //mount node
// a promise that resolves with the react component. Wait for it to resolve before mounting
loadRootComponent: (appInfo: AppInfo) => {
_root = getRootDom(appInfo.dom);
_props = appInfo;
return Promise.resolve(() => <RootComponent {...appInfo} />);
},
errorBoundary: (e: any) => <ErrorBoundary />,
externalRequired: ["mobx-react"]
});
No response
If you have no time, i can try to append this feature. Its just a technical discussion
在中文版的readme中,quick start地址没有同步更新
https://github.com/modern-js-dev/garfish/blob/main/README.ch.md
npm
System:
OS: macOS 10.15.7
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 15.14 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 14.16.1 - ~/.nvm/versions/node/v14.16.1/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v14.16.1/bin/yarn
npm: 6.14.12 - ~/.nvm/versions/node/v14.16.1/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Browsers:
Chrome: 103.0.5060.134
Firefox: 102.0.1
Safari: 15.6
我主应用路由懒加载,子应用路由懒加载。在切换几次后 Loading chunk 1 failed 子应用的路由加载就失效了,是我设置得不对吗
文档什么时候可以上线呢?
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.