Giter Club home page Giter Club logo

k6-template-typescript's Introduction

banner

Template to use TypeScript with k6

.github/workflows/push.yml

This repository provides a scaffolding project to start using TypeScript in your k6 scripts.

Rationale

While JavaScript is great for a myriad of reasons, one area where it fall short is type safety and developer ergonomics. It's perfectly possible to write JavaScript code that will look OK and behave OK until a certain condition forces the executor into a faulty branch.

While it, of course, still is possible to shoot yourself in the foot with TypeScript as well, it's significantly harder. Without adding much overhead, TypeScript will:

  • Improve the ability to safely refactor your code.
  • Improve readability and maintainability.
  • Allow you to drop a lot of the defensive code previously needed to make sure consumers are calling functions properly.

Installation

Creating a project from the template-typescript template

To generate a TypeScript project that includes the dependencies and initial configuration, navigate to the template-typescript page and click Use this template.

Install dependencies

Clone the generated repository on your local machine, move to the project root folder and install the dependencies defined in package.json

npm install

Running the test

To run a test written in TypeScript, we first have to transpile the TypeScript code into JavaScript running a bundler. This project uses Babel and Webpack to bundle the different files into ES modules (ESM), using its webpack.config.js configuration.

The next command transforms each TypeScript test in ./src to the ./dist folder as ES modules.

npm run bundle

Once that is done, we can run our script the same way we usually do, for instance:

k6 run dist/get-200-status-test.js

See also

k6-template-typescript's People

Contributors

aklaus avatar awls99 avatar dependabot[bot] avatar hinatades avatar mstoykov avatar nicolevanderhoeven avatar pexa-slee avatar ppcano avatar shavo007 avatar simskij avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

k6-template-typescript's Issues

Please clarify what version of Node.js is needed

I happened to have v18.16.0 installed due to other things i'm working on, and on a fresh clone, I get:

dowideit.sven@ABC-KC00PW16GC k6 % npm install
npm WARN deprecated [email protected]: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)

added 340 packages, and audited 341 packages in 6s

25 packages are looking for funding
  run `npm fund` for details

7 vulnerabilities (2 moderate, 4 high, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues, run:
  npm audit fix --force

Run `npm audit` for details.
dowideit.sven@ABC-KC00PW16GC k6 % npm start

> [email protected] start
> webpack

Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db

Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)
    at BulkUpdateDecorator.hashFactory (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/util/createHash.js:144:18)
    at BulkUpdateDecorator.update (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/util/createHash.js:46:50)
    at SourceMapSource.updateHash (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack-sources/lib/SourceMapSource.js:233:8)
    at NormalModule._initBuildHash (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/NormalModule.js:839:17)
    at handleParseResult (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/NormalModule.js:904:10)
    at /Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/NormalModule.js:995:4
    at processResult (/Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/NormalModule.js:718:11)
    at /Users/dowideit.sven/src/rockset/k6/node_modules/webpack/lib/NormalModule.js:778:5 {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v18.16.0

Module build failed : Unexpected token, expected ","

I am new to k6 and have been using it to test a react web application written in typescript. So I am using this template to compile the typescript component to javascript. I cloned the template to the existing project folder and created a .ts file and scripted the test script in it. It calls to other components in the project folder that is in typescript. So when I imported them in the current test script and I run the "npm run bundle" I am repeatedly getting the same error in 4 different components

ERROR in ../src/e2e/helpers/resetLocalStorage.ts
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: C:\Users\vignesh.t\SkillfitFrontend\src\e2e\helpers\resetLocalStorage.ts: Unexpected token, expected "," (6:47)

 4 | import { HTTPRequest } from 'puppeteer';
 5 |
> 6 | export const resetLocalStorage = async (browser: BrowserContext, url: string): Promise<void> => {
   |                                                                                 ^
 7 |   const page = await browser.newPage();
 8 |   await page.setRequestInterception(true);
 9 |   page.on('request', (req) => { 

can someone please help me with this?

Add a simple example that shows how to leverage typescript in a test

When we simplified this project from the previous (significantly more complete example) we, unfortunately, ended up with only two test files.

This means the repo no longer contains any example on how to define your own types and have typescripts compile-time type-checking prevent you from using types in a non-compatible way. This should be re-added, but as this is a template repo, it needs to be small, useful, and non-invasive. ๐Ÿค”

Add other lifecycle functions to examples

Hi folks,

I'm having a great time using K6. Has been a big help in diagnosing some bottlenecks in my team's application. It's a beast!

Our K6 tests have traditionally been written in JS, but I'd like to convert them to TypeScript in line with the rest of our code. That's when I stumbled upon this useful repo.

However, my tests are more complex than the examples in this repo's /src folder. They use a setup() step, which then passes an object to the main function. I'm getting a lot of TS errors

Screenshot 2023-04-11 at 16 00 52

Admittedly I'm not the most proficient in TS, but I imagine that this would be helpful for others as well.

[Question] How do I copy an image (jpg) from /src/assets to the /dist folder

Hi, I'm using the normal webpack config settings:

/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable no-undef */
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const GlobEntries = require('webpack-glob-entries')

module.exports = {
  mode: 'production',
  entry: GlobEntries('./src/*.ts'), // Generates multiple entry for each test
  output: {
    path: path.join(__dirname, 'dist'),
    libraryTarget: 'commonjs',
    filename: '[name].js',
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
  target: 'web',
  externals: /^(k6|https?:\/\/)(\/.*)?/,
  // Generate map files for compiled scripts
  devtool: 'source-map',
  stats: {
    colors: true,
  },
  plugins: [
    new CleanWebpackPlugin(),
    // Copy assets to the destination folder
    // see `src/post-file-test.ts` for an test example using an asset
    new CopyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, 'assets'),
          noErrorOnMissing: true,
        },
      ],
    }),
  ],
  optimization: {
    // Don't minimize, as it's not used in the browser
    minimize: false,
  },
}

I have no idea how to webpack, would you be able to provide some guidance in terms of including the jpg file below to the /dist folder?

Untitled

Huge memory footprint with Typescript and webpack

After the initial setup and first test implemented I've noticed that the VUs are consuming huge amount of memory (17-20MB per each), while the output files in dist/ are around 300-500KB. Initially I thought it was due to the node_modules being packed , but I did cut those and the memory consumption stays the same. My webpack config below:

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const GlobEntries = require('webpack-glob-entries');

module.exports = {
  mode: 'production',
  entry: GlobEntries('./tests/*test*.ts'), // Generates multiple entry for each test
  output: {
    path: path.join(__dirname, 'dist'),
    libraryTarget: 'commonjs',
    filename: '[name].js',
  },
  resolve: {
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
    ],
  },
  target: 'node',
  externals: /^(k6|https?\:\/\/)(\/.*)?/,
  // Generate map files for compiled scripts
  devtool: false,
  stats: {
    colors: true,
  },
  plugins: [
    new CleanWebpackPlugin(),
    // Copy assets to the destination folder
    // see `src/post-file-test.ts` for an test example using an asset
    new CopyPlugin({
      patterns: [{ 
        from: path.resolve(__dirname, 'assets'), 
        noErrorOnMissing: true 
      }],
    }),
  ],
  optimization: {
    minimize: true,
    splitChunks: {
      cacheGroups: {
        graphql: {
          test: /[\\/]deps[\\/]/,
          name: 'deps',
          chunks: 'all',
        }
      }
    }
  },
};

How could I split dependencies in chunks?

Hi @simskij ,

I'm struggling with making your template working with chunking files.

It works great when each output script embeds everything (its own imports) in its final .js file, but it makes my computer rewriting each time this full file for nothing (because only my k6 scenario changes, not imported dependencies).

The idea has been to add:

optimization: {
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        // cacheGroupKey here is `commons` as the key of the cacheGroup
        name(module, chunks, cacheGroupKey) {
          return `${cacheGroupKey}`;
        },
        chunks: 'all'
      }
    }
  }
},

So dependencies are in their own final .js file and are imported by the scenario files (test1.js and test2.js in your example). But... I get this error:

ReferenceError: window is not defined at file:///Users/XXXXXXXXX/dist/test2.js:144:28(64)

Indeed this line will break:

var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];

It seems to be necessary to append dependencies...

since we are not in a real browser when executing the scenario... I tried multiple possibilities but never succeed. Setting target=node is not working also to prevent compiling dependencies with browser stuff.

Do you know a workaround so I can chunk common files while being able to import them?

Thank you,

Adding Type Safety to __ENV Variables

Hi guys, I added Typescript into my k6 scripts and I'm finding it difficult to extend the __ENV type. There are some __ENV variables I defined to be a number, but Typescript will define the value as a string rather than a number due to this type definition

// global.d.ts
declare global {
    const __ENV: { [name: string]: string };
}

Is there a way for me to extend the __ENV type definition? One thing I tried was defining my own global.d.ts file with the following:

declare global {
    namespace __ENV {
        const VUS: number
    }
}

but that didn't work.

Please clarify the license

The license for this template does not seem to be clearly stated. This means that it is virtually impossible to use this template.
I would expect you to apply an appropriate license to this template, a license that is closer to the public domain, such as CC0.

Babel error when running webpack with no modifications

I've tried pulling down the repo and tried running the following commands as set out in the readme.

yarn install
yarn webpack

Upon running, I get the following errors:

Hash: 425773d28b54dd08feef
Version: webpack 4.43.0
Time: 243ms
Built at: 09/02/2021 15:59:12
   Asset      Size  Chunks             Chunk Names
test1.js  8.54 KiB   test1  [emitted]  test1
test2.js  8.44 KiB   test2  [emitted]  test2
Entrypoint test1 = test1.js
Entrypoint test2 = test2.js
[./test1.ts] 4.22 KiB {test1} [built] [failed] [1 error]
[./test2.ts] 4.13 KiB {test2} [built] [failed] [1 error]

ERROR in ./test1.ts
Module build failed (from ../node_modules/babel-loader/lib/index.js):
SyntaxError: D:\dev\wealthkernel\template-typescript\src\test1.ts: Unexpected token, expected ";" (5:18)

  3 | import http from 'k6/http';
  4 |
> 5 | export let options:Options = {
    |                   ^
  6 |   vus: 50,
  7 |   duration: '10s'
  8 | };
    at Parser._raise (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:746:17)
    at Parser.raiseWithData (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:739:17)
    at Parser.raise (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:733:17)
    at Parser.unexpected (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:8807:16)
    at Parser.semicolon (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:8789:40)
    at Parser.parseVarStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11625:10)
    at Parser.parseStatementContent (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11223:21)
    at Parser.parseStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11156:17)
    at Parser.parseExportDeclaration (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12365:17)
    at Parser.maybeParseExportDeclaration (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12321:31)
    at Parser.parseExport (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12251:29)
    at Parser.parseStatementContent (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11260:27)
    at Parser.parseStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11156:17)
    at Parser.parseBlockOrModuleBlockBody (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11731:25)
    at Parser.parseBlockBody (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11717:10)
    at Parser.parseTopLevel (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11087:10)
    at Parser.parse (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12768:10)
    at parse (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12821:38)
    at parser (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\parser\index.js:54:34)
    at parser.next (<anonymous>)
    at normalizeFile (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transformation\normalize-file.js:93:38)
    at normalizeFile.next (<anonymous>)
    at run (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transformation\index.js:31:50)
    at run.next (<anonymous>)
    at Function.transform (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transform.js:27:41)
    at transform.next (<anonymous>)
    at step (D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:254:32)
    at D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:266:13
    at async.call.result.err.err (D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:216:11)
    at D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:184:28

ERROR in ./test2.ts
Module build failed (from ../node_modules/babel-loader/lib/index.js):
SyntaxError: D:\dev\wealthkernel\template-typescript\src\test2.ts: Unexpected token, expected ";" (5:18)

  3 | import http from 'k6/http';
  4 |
> 5 | export let options:Options = {
    |                   ^
  6 |   vus: 50,
  7 |   duration: '10s'
  8 | };
    at Parser._raise (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:746:17)
    at Parser.raiseWithData (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:739:17)
    at Parser.raise (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:733:17)
    at Parser.unexpected (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:8807:16)
    at Parser.semicolon (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:8789:40)
    at Parser.parseVarStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11625:10)
    at Parser.parseStatementContent (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11223:21)
    at Parser.parseStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11156:17)
    at Parser.parseExportDeclaration (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12365:17)
    at Parser.maybeParseExportDeclaration (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12321:31)
    at Parser.parseExport (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12251:29)
    at Parser.parseStatementContent (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11260:27)
    at Parser.parseStatement (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11156:17)
    at Parser.parseBlockOrModuleBlockBody (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11731:25)
    at Parser.parseBlockBody (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11717:10)
    at Parser.parseTopLevel (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:11087:10)
    at Parser.parse (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12768:10)
    at parse (D:\dev\wealthkernel\template-typescript\node_modules\@babel\parser\lib\index.js:12821:38)
    at parser (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\parser\index.js:54:34)
    at parser.next (<anonymous>)
    at normalizeFile (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transformation\normalize-file.js:93:38)
    at normalizeFile.next (<anonymous>)
    at run (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transformation\index.js:31:50)
    at run.next (<anonymous>)
    at Function.transform (D:\dev\wealthkernel\template-typescript\node_modules\@babel\core\lib\transform.js:27:41)
    at transform.next (<anonymous>)
    at step (D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:254:32)
    at D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:266:13
    at async.call.result.err.err (D:\dev\wealthkernel\template-typescript\node_modules\gensync\index.js:216:11)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

I assume I'm doing something stupid here but not sure what. Any advice?

Add support for k6 remote modules

It is not supported in TypeScript yet - Add support for URI style import.

You need to use ts-ignore to skip the compiler error.

import { sleep, check } from 'k6';
import { Options } from 'k6/options';

/* @ts-ignore */
import { randomIntBetween } from 'https://jslib.k6.io/k6-utils/1.1.0/index.js';
import http from 'k6/http';

export let options:Options = {
  vus: 50,
  duration: '10s'
};

export default () => {
  const res = http.post('https://httpbin.org/status/400');
  check(res, {
    'status is 400': () => res.status === 400,
  });
  sleep(randomIntBetween(1,5));
};

TypeScript examples for unit testing modules that use k6/crypto

I have a use case where I need to build a module that assists us with our K6 unit tests, this module will reduce code repetition in each of our projects that need load testing. The module imports the k6/crypto and uses functions such as crypto.createHash('sha256').

I've managed to get the module built properly using rollup (via Vite) and using TypeScript, and this is compiling to JS correctly and working as expected in our load testing projects.

I want to add some unit tests to the module I have created using vitest, to ensure that future changes to not break the implementation.

I can't seem to add any tests, as soon as I do I get the error:

Error: Failed to load url k6/crypto (resolved id: k6/crypto) in path/to/file/src/main.ts. Does the file exist?
 โฏ loadAndTransform node_modules/vite/dist/node/chunks/dep-abb4f102.js:54840:21

Is there a way for us to be able to unit test NPM packages that utilise k6 modules, or are we not able to do so?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.