volarjs / volar.js Goto Github PK
View Code? Open in Web Editor NEW💙🌊
Home Page: https://volarjs.dev/
License: MIT License
💙🌊
Home Page: https://volarjs.dev/
License: MIT License
In the following line, the language server attempts to search for all tsconfigs from the workspace root directory. If the user attempts to start vscode from the system root directory and opens a vue file, this could lead to performance issues for the language server searching through the entire file system for tsconfigs.
A better approach would be to attempt to search up for the tsconfig for each request.
Make core APIs completely based on uri
instead of fsPath
.
Based on the VSCode documentation on contributes.typescriptServerPlugins
, it’s possible to send configuration via an extension.
We could use this to provide a uniform interface to configure Volar based TypeScript plugins through either tsconfig.json
or VSCode settings.
The following VSCode extension:
import { activateTsPlugin } from '@volar/vscode'
export async function activate(context) {
await activateTsPlugin(
'@mdx-js/typescript-plugin',
context,
'mdx',
'config'
)
}
configures the TypeScript plugin using the following VSCode settings:
{
"mdx.config": {
"plugins": []
}
}
The TypeScript plugin would look something like this:
module.exports = createAsyncTSServerPlugin(
['.mdx'],
2,
// This tells Volar at which `tsconfig.json` key to look.
'mdx',
async (ts, info, options) => {
// The options are available here somehow.
}
)
This would be equivalen to having the following tsconfig.json
:
{
"compilerOptions": {/* … */},
"mdx": {}
}
Related:
the readme is not work in version 1.10.3
var item: Record<string, string> | undefined
var b= item?.name // => ?. is formatted correctly
var a= item?['name'] // => ?] is formatted as ternary operator instead (item ? ['name'])
I often use <script>
together with <script setup>
in SFC to cache some data across components.
Unfortunately it seems Volar wrongly formats this combination initially.
When I format manually, close and open the file, everything works fine afterwards, but that's annonying:
Tried the pre-release version - the same problem:
Vue Language Features (Volar)
v1.8.23
Visual Studio Code
Version: 1.84.1
Commit: 2b35e1e6d88f1ce073683991d1eff5284a32690f
Date: 2023-11-06T12:35:59.022Z (23 hrs ago)
Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.84.1 Chrome/114.0.5735.289 Electron/25.9.2 Safari/537.36
I was instructed to file this upstream from vuejs/language-tools#3511
My project directory contains a directory which is not readable (owned by a different user). The existence of this directory crashes the server.
sudo mkdir problem
The plugin ignores this error, perhaps emitting a warning, and continues to start. Alternatively, the plugin is configurable in some way to ignore certain files or directories within a project directory.
node:fs:1442
handleErrorFromBinding(ctx);
^
Error: EACCES: permission denied, scandir '/home/scott/src/kalkutago/db.mount'
at Object.readdirSync (node:fs:1442:3)
at t.readdirSync (node:electron/js2c/asar_bundle:2:10837)
at Object.readDirectory (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:77:33947)
at Object.readDirectory (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:77:30107)
at b (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:77:3184)
at /nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:77:1942
at w (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:76:38771)
at w (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:76:39220)
at Aoe (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:76:38625)
at Proxy.w (/nix/store/nrwr1bw6hdg4k34can4y4qig73x9fi98-vscode-extension-Vue-volar-1.7.11/share/vscode/extensions/Vue.volar/dist/server.js:77:1885) {
errno: -13,
syscall: 'scandir',
code: 'EACCES',
path: '/home/scott/src/kalkutago/db.mount'
}
Obviously there's no way to repro this in a repo, because this is an extension bug in VSCode, but on more than one occasion, if I'm working with a Vue SFC (in TypeScript), and I "Save as..." another file in the same folder, the script tag will say: Virtual script not found, may missing <script lang="ts"> / "allowJs": true / jsconfig.json
allowJs
is enabled and was working just fine in tsconfig.json. Creating a jsconfig.json
of course has no effect, because it's TypeScript (but I tried anyway). It happens only when duplicating a file. Restarting Volar is the only current fix.
If a project have a directory named "constructor" it could crash with error like
TypeError: Cannot read properties of undefined (reading '<something>')
I found it happening because of a bug in the file packages/typescript/src/sys.ts
, function getDirFromDir
function getDirFromDir(dir: Dir, name: string) {
let target = dir.dirs[name]; // <-------------- BUGGY LINE
if (!target) {
target = {
dirs: {},
files: {},
};
dir.dirs[name] = target;
}
return target;
}
The function getDirFromDir
gets called in a loop iterating through some directory path.
If there are a directory named "constructor" in the middle of the path then it will crash.
Getting name "constructor" of an empty object (which dir.dirs
could be) returns the actual object constructor instead of a Dir
object or undefined
.
Then the object constructor gets returned as if it was a Dir
found.
On the next call of getDirFromDir
function there will be the object constructor used as the dir: Dir
argument.
So if there is next call then the function throws a null-refference error because there is no dirs
in the object constructor.
I kind of reproduced the bug and it seems like changing the buggy line would fix the issue:
let target = name in dir.dirs ? dir.dirs[name] : undefined;
volar.config.js
has no effect on Windows because the language server fails to resolve the file path.
This happens because of the path
property on the URI class from vscode-uri
. On windows it returns /c:/path
instead of c:/path
.
The fix is to use fsPath
instead of path
when calling loadConfig
"tabs": {
"scope": "vue-html",
"prefix": [
"template:tabs",
],
"body": [
"a line",
"another line",
],
"description": "tabs"
}
This won't work in the template section in a SFC file.
It's been a bug since vetur.
We've pretty much disassembled the shared module's functions down to the actual used packages, and we'll be able to remove it.
When using @volar/monaco
, for third-party libraries that don't have types in package.json
(such as react
), can @types/xxx
be automatically added to obtain type prompts.
For example, when I import 'react' and it doesn't hava types
field in package.json
, I hope @volar/monaco
can add @types/react
automaticly.
Volar is not handling resolving external workspaces/packages within monorepo.
Reproduction: https://github.com/blake-newman/vue-tsc-import-resolution
When takeover mode is off it is able to auto import the modules/dependencies from external workspaces/packages
./packages/main/src/index.ts
try to use isFalse
function from b
package.
When takeover mode is on it is unable to auto import modules/dependencies from external workspaces/packages
./packages/main/src/index.ts
try to use isFalse
function from b
package.
The main purpose of a language plugin, is to provide (embdded) virtual files. These virtual files contain a snapshot and mappings. The Volar Labs VSCode extension provides a great way to inspect them. However, the mappings become pretty hard to interpret when writing tests (example).
It would be nice if Volar provides a way to represent virtual files in a way that’s friendly to the reader.
Idea: Add a function to represent a Volar virtual file as a markdown file containing annotated code blocks.
import { printVirtualFile } from '@volar/test-utils'
printSnapshot(printVirtualFile, {
comments: {
markdown: ['<!--', '-->'],
mdx: ['{/*', '*/}'],
typescriptreact: '//',
}
})
```mdx fileName="file.mdx"
{/* Exact match */}
import { Component } from './component.js'
Hello <Component name={props.name} />
```
```javascriptreact fileName="file.mdx.jsx"
import { Component } from './component.js'
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/**
* @deprecated
* Do not use.
*
* @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props
* The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.
*/
function _createMdxContent(props) {
return <><Component name={props.name} /></>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
/**
* Render the MDX contents.
*
* @param {{readonly [K in keyof MDXContentProps]: MDXContentProps[K]}} props
* The [props](https://mdxjs.com/docs/using-mdx/#props) that have been passed to the MDX component.
*/
export default function MDXContent(props) {
return <_createMdxContent {...props} />
}
// @ts-ignore
/** @typedef {0 extends 1 & Props ? {} : Props} MDXContentProps */
```
```markdown fileName="file.mdx.md"
<!-- ^ --->
Hello <!---->
<!-- ^^^^^^ ^ -->
```
The comment could be configured per language ID. Code is indented by the length of the opening comment. The commend uses ^
to indicate a character that matches the position in the parent virtual file, and shows the original character in case of a mismatch.
This file could be written to disk using any snapshotting library, or inlined in a multiline string.
Is there a way for me to manually add dts files instead of having them auto-fetched?
kit:
We need to refactor the architecture to reuse code to avoid possible inconsistent behavior.
It seems that vscode.env.openExternal cannot open files in remote (ssh). When I use vscode remote, there is no response when I click on it.
I need to find stats.html in os.tmpdir() and download it locally to open it. I am not familiar with vscode and do not know how to improve it.
Hello,
Function isValidPackageName
rejects packages whose name contain a dot while some valid packages contain dots.
Example : pixi.js https://www.jsdelivr.com/package/npm/pixi.js
volar.js/packages/cdn/lib/cdns/jsdelivr.ts
Line 206 in 007ed5a
I don't know exactly the goal of this check, but if it aims to rejects local modules (import x from "./X"
) then this would be better:
if (pkgName.indexOf('.') == 0 || pkgName.endsWith('/node_modules')) {
Thank you,
I enjoy using Volar - great work!
I found myself in need to:
With the help of @remcohaszing I managed to do both of those based on:
onRequest
, herevolar-service-typescript-twoslash-queries
is getting access to the TS language service, hereWith those references and some source code spelunking I managed to do something along those lines:
export const createServerPlugin =
(connection: Connection): ServerPlugin =>
({ modules }) => {
return {
typescript: {
extraFileExtensions: [],
},
watchFileExtensions: [
'cjs',
'cts',
'js',
'jsx',
'json',
'mjs',
'mts',
'ts',
'tsx',
],
async resolveConfig(config, env, projectContext) {
if (!modules.typescript) {
throw new Error('TypeScript module is missing');
}
(config.services ||= {}).typescript = createTypeScriptService(
modules.typescript,
);
return config;
},
onInitialized(projects) {
connection.onRequest(helloRequest, async ({ textDocument, name }) => {
if (!textDocument) {
connection.console.log(`Hello, ${name}!`);
return true;
}
const languageService = await getTypeScriptLanguageService(
textDocument.uri,
);
connection.console.log(
`Hello in "${languageService
.getProgram()
?.getCurrentDirectory()}", ${name}!`,
);
return true;
});
async function getTypeScriptLanguageService(uri: string) {
return (await projects.getProject(uri))
.getLanguageService()
.context.inject<Provide, 'typescript/languageService'>(
'typescript/languageService',
);
}
},
};
};
I think there is some opportunity in the API to make this use case easier
Currently Monaco support is implemented by https://github.com/Kingwl/monaco-volar only for Vue, we should add a general package for Monaco support in this repo.
Bug
Error: Debug Failure. False expression: y:/mapped_network_drive/path/to/project/node_modules/vue/dist/vue.d.ts linked to nonexistent file //server/linux/path/to/project/node_modules/vue/dist/vue.d.ts
Project Info:
Additional Infomation
[@volar-plugins/typescript] sourceFile not found file:///y%3A/path/to/project/app.vue.js
c:\Users\username\AppData\Local\Programs\Microsoft VS Code\resources\app\extensions\node_modules\typescript\lib\typescript.js:39898
Currently we have factory code for building commands in the following code, but it only works for VSCode (seems to work for coc too). We should judge the IDE of the language client to return the command format actually supported by the current IDE.
volar.js/packages/language-service/src/baseLanguageService.ts
Lines 129 to 197 in dfddd60
Based on mdx-js/mdx-analyzer#384, a bit of boilerplate is needed to define custom LSP request and notification handlers.
I think it would be neat if service plugins can specify request and notification handlers. This means language servers no longer have to deal with any of this.
The following service plugin:
export function createMdxServicePlugin() {
return {
name: 'mdx',
create(context) {
return {
notification: {
sayHi(params) {
// Handle notification
}
},
request: {
toggleStrong(params) {
// Handle request
}
}
}
}
}
}
Would be equivalent to the following language server code:
connection.onRequest('mdx/toggleStrong', params => {
// Handle request
})
connection.onNotification('mdx/sayHi', params => {
// Handle request
})
The service plugin name is used to scope the requests and notifications, and is therefor required.
This could also make usage from contexts other than a language server more straight-forward, e.g. for testing purposes or usage from Monaco editor.
I'm just logging this as a cross-repo feature request, as someone who would like to use this but isn't actively working on it.
We have now completed the Monaco integration and when I checked @vue/repl
I noticed it also uses another web code editor called CodeMirror, I was just considering whether it also needs LSP support.
The closest solution at the moment is codemirror-languageserver maintained by @hjr265.
But perhaps a compatibility package between Monaco worker and CodeMirror editor would be a better approach?
For now, I will keep this issue open but I may not do the work because I am not even sure if CodeMirror is still being used or maintained by the community.
Sometimes I have code in a string:
const js = `
const msg = 'this doesnt have any language server features';
console.log(msg);
`
There is a vscode extension that allows syntax highlighting for such template literals by prefixing it was a comment or use a tagged template:
// with comment
const js = /* javascript */ `
const msg = 'this code is highlighted';
console.log(msg)
`
// via tagged template
const js = javascript`
const msg = 'this code is highlighted';
console.log(msg)
`
Syntax highlighting alone is pretty cool. However, I run into bugs all the time because I have spelling errors or other easy to catch mistakes if those templates would also have language server support.
So I wanted to extend the ts language server to add this feature but I am not sure if extending a language server is even possible yet.
In a dream world you probably would use it like this:
const outerMsg = 'hello from outside'
const ts = javascript`
// inherits the scope of the sorrounding code
console.log(outerMsg); // outerMsg is "string"
`
const ts = javascript<Window>`
// scope is Window
window.console.log('much wow!')
`
Obviously you would still need to define the javascript
function in this case. So maybe its not the best solution but its a start.
Ref: sublimelsp/LSP#2295
vscode / builtin monaco will auto insert closing quotes / brackets, like typing (
will result in ()
with caret between it.
I doubt whether this feature related to @volar/monaco or @vue/repl itself
Hi,
I am using @volar/monaco/worker
to create a language service for monaco-editor
.
With the default monaco-editor
TypeScript worker I can use addExtraLib to add an extra type definition so I can define some globals types that do not require to be imported (check the next screenshot using a React code)
Type definition | Editor |
---|---|
During the creation of the language service, I wanted to use my own dtsHost
here:
createLanguageService({
config: resolveConfig(
{
services: {
typescript: createTsService({
dtsHost: myOwnDtsHost, // <-here
},
}
}
}
}
But I noticed that the types are fetched once the package is required in the code, it is not fetched by default. Debugging, I also noticed that typescript
, vue
, csstype
and other modules are loaded automatically. Is there a way to achieve the same with my custom library and custom type definitions?
Regards and thanks in advance.
I find that automatic type acquisition is achieved through createJsDelivrFs
+ decorateServiceEnvironment
in monaco worker. But packages whose type definitions in @types/xxx
such as react
、lodash
, monaco worker can't recognize their type definitions correctly.
<script setup lang="ts">
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
<template>
<input :model-value="modelValue" @input="$emit('update:modelValue', $event.target?.value)">
</template>
for a component as simple as this, I am getting type errors from Volar (im in takeover mode and forced TS version to 4.9.5) saying that "Property value does not exist on type 'EventType'"
also using nuxt 3.3.2 if that matters
tried looking around and finding other solutions as well, any help is greatly appreciated
Currently Labs requires the entire @volar/langauge-server
module, which should be reduced to a protocol object.
The coc API is very similar to vscode, I think it is suitable to integrate it in the core.
I think this issue needs to be in language-tools, but that repo has limited issue reporting to existing contributors, so I can't post this there. If it does need to be moved, I would appreciate a contributor adding it over there. Thank you in advance!
I use VS Code for Vue development with the Volar plugins. In my VS Code config I used to use source.organizeImports
in editor.codeActionsOnSave
but it deletes unused imports which can break an application. I read that VS Code v1.57 added the source.sortImports
action for javascript and typescript files. However, this action has no effect on .vue files.
Please add source.sortImports
support for .vue files so I can automatically organize my inputs in a non-destructive manner.
Thank you!
Hello,
Using NeoVim I have installed the volar
LSP via Mason
.
Now, when I edit a .vue
file, the volar LSP client immediately crashes with exit code 1 and signal 0.
This is the complete output in lsp.log
(I will split it in multiple lines for readability):
[START][2023-04-16 09:06:32] LSP logging initiated
[ERROR][2023-04-16 09:06:32] .../vim/lsp/rpc.lua:734 "rpc" "vue-language-server" "stderr"
"/home/vincent/.local/share/nvim/mason/packages/vue-language-server/node_modules/@volar/
vue-language-server/node_modules/@vscode/l10n/dist/main.js:846
throw new Error(e.responseText ?? (0, import_request_light.getErrorStatusDescription)(e.status) ?? e.toString());
SyntaxError: Unexpected token '?'
at wrapSafe (internal/modules/cjs/loader.js:915:16)
at Module._compile (internal/modules/cjs/loader.js:963:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at /home/vincent/.local/share/nvim/mason/packages/vue-language-server/node_modules/@volar/
vue-language-server/node_modules/vscode-html-languageservice/lib/umd/parser/htmlScanner.js:17:18
at /home/vincent/.local/share/nvim/mason/packages/vue-language-server/node_modules/@volar/
vue-language-server/node_modules/vscode-html-languageservice/lib/umd/parser/htmlScanner.js:7:17
at Object.<anonymous> (/home/vincent/.local/share/nvim/mason/packages/vue-language-server/
node_modules/@volar/vue-language-server/node_modules/vscode-html-languageservice/lib/umd/parser/
htmlScanner.js:13:3)"
See screenshot. getProgram
is getting called infinitely recursively. This is happening when using vite-plugin-checker 0.5.6 with vue-tsc 1.1.7 and typescript 4.9.5, although I don't think its anything that vite-plugin-checker is doing wrong.
If it helps, the stack frame before the one selected in my screenshot, resolveNamesWithLocalCache
, is trying to call program.getResolvedProjectReferenceToRedirect('C:/my/project/__inferred type names__.ts')
on every single stack frame that that function is repeated.
Hello there ! Thanks for making Volar, it is really awesome.
I want to implement server blocks for Nuxt nuxt/nuxt#20802
The SFC is going to look like this.
Under the hood, this entire block content would be removed, and processed separately by Nuxt. It wouldn't be present in the component itself, it's essentially isolated from blocks.
Adding lang="ts" make the color syntax work, but I want all the Typescript features to work, such as following the correct tsconfig and also typechecking.
I've considered using a <script server>
tag too, but it seems to be easier with a custom name.
What needs to happen with Volar to make something like this work ? I would appreciate if you could point me in the right direction.
Thanks !
Before:
volar.js/packages/language-service/src/types.ts
Lines 68 to 161 in b76317f
v1:
volar.js/packages/language-service/src/types.ts
Lines 77 to 125 in 3c85580
Hi, I'm working on a vscode extension ts-type-explorer that provides a view to know a type in the js
or ts
file and I added support for Vue files to this extension. See zcf0508/ts-type-explorer@c306370#diff-0d574bd7891645b07141f9f400e0830e391153bc3d2e7618245fcd8e86bd42fb .
I see that volar.js
2.0 is released recently, and I try to make my code compatible with it. See zcf0508/ts-type-explorer@e62e1cc#diff-0d574bd7891645b07141f9f400e0830e391153bc3d2e7618245fcd8e86bd42fb .
I used the program.__vue.langaugeContext
to get the virtualFile
and then calculate the new offset in the first commit.
But when I update the volar.js
to 2.0, the program
no longer exposes the languageContext
and virtualFile
. So I consider returning the FileRegistry
when using proxyCreateProgram
to create the program.Like thie.
// https://github.com/volarjs/volar.js/blob/v2.0.0/packages/typescript/lib/node/proxyCreateProgram.ts#L131
const program = Reflect.apply(target, thisArg, [options]);
decorateProgram(files, program);
+ program.files = files
return program;
If you have a plan to expose the FileRegistry
or the other relevant object in other ways, I will wait for you to finish before continuing with further modifications. Alternatively, I can submit a pr according to the above plan.
Rules:
import type
for typescript/lib/tsserverlibrary
typescript/lib/tsserverlibrary
instead of typescript
在使用Monaco 编辑器时发生的问题
JSON Worker
import * as worker from "monaco-editor-core/esm/vs/editor/editor.worker";
import type * as monaco from "monaco-editor-core";
import { resolveConfig } from "@vue/language-service";
import { createLanguageService } from "@volar/monaco/worker";
import createJsonService from "volar-service-json";
self.onmessage = () => {
worker.initialize((ctx: monaco.worker.IWorkerContext) => {
return createLanguageService({
workerContext: ctx,
config: resolveConfig(
{
services: {
json: createJsonService({
validate: true,
allowComments: true,
schemas: []
})
},
},
),
});
});
};
index.vue
import * as monaco from 'monaco-editor';
// ...
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
enableSchemaRequest: true,
allowComments: true,
schemas: [
{
uri: componentName!,
schema: JSONSchema
}
]
})
这两者似乎无法关联起来
Volar fails to start in eclipse theia because cant find typescript module:
Message: Request initialize failed with message: Can't find typescript.js or tsserverlibrary.js in
after some investigation, i found that volar is trying to load the typescript module from extensions/node_modules
, that seems to be the place where vscode contains this module.
volar.js/packages/vscode/lib/features/tsVersion.ts
Lines 156 to 166 in cd3695a
there's a workaround, installing the ms-vscode.vscode-typescript-next
extensions, that uses extensionPath
to find the node_modules
folder (i think that extensionPath is empty so it use the node_modules from de theia folder)
volar.js/packages/vscode/lib/features/tsVersion.ts
Lines 143 to 154 in cd3695a
here's the related issue in theia repo: eclipse-theia/theia#12443
is there any chance to add a fix to this problem (ie, validating that the extensions/node_modules exists)?
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.