Revive JavaScript Bindings (#1177)

Summary:
Yoga's JavaScript bindings do not work past Node 10, or on recent versions of Ubuntu even using it. This is due to a reliance on `nbind`, a library which is no longer maintained. `nbind` itself abstracts over `embind` running Emscripten to generate an asm.js build, along with building Node native modules. In the meantime, [yoga-layout-prebuilt](https://www.npmjs.com/package/yoga-layout-prebuilt) has been used by the community instead of the official package.

https://github.com/facebook/yoga/pull/1177 was contributed as a conversion of bindings created using `nbind` to instead use `embind` directly.

I continued building on this to add more:
1. WebAssembly support (required to be async in browsers)
2. CMake + Ninja Build for the 4 flavors
3. TypeScript typings (partially generated)
4. yarn scripts to build (working on macOS, Ubuntu, Windows)
5. A README with some usage and contribution instructions
6. Updated tests to work with Jest, and updated general infra
7. ESLint and clang-format scripts
8. More GitHub actions (and now testing Windows)
9. Probably more I kinda got carried away here lol

The plan is to eventually publish this to NPM, but there is a little bit of work after this before that happens.

Pull Request resolved: https://github.com/facebook/yoga/pull/1177

Test Plan: The bindings pass Jest tests (both manual and generated). GitHub actions added for the different yarn scripts. Did some manual checks on using the library as TS.

Reviewed By: christophpurrer

Differential Revision: D42207782

Pulled By: NickGerleman

fbshipit-source-id: 1dc5ce440f1c2b9705a005bbdcc86f952785d94e
This commit is contained in:
Dmitry Ivakhnenko
2022-12-28 01:27:12 -08:00
committed by Facebook GitHub Bot
parent 8035456330
commit 1813748eaa
110 changed files with 24702 additions and 22470 deletions

View File

@@ -1,49 +1,55 @@
{
"name": "yoga-layout",
"version": "1.9.3",
"description": "Yoga is a cross-platform layout engine enabling maximum collaboration within your team by implementing an API many designers are familiar with, and opening it up to developers across different platforms.",
"version": "2.0.0-beta.1",
"description": "JavaScript bindings for the Yoga layout engine",
"license": "MIT",
"repository": {
"type": "git",
"url": "git@github.com:facebook/yoga.git"
},
"main": "./dist/entry-node",
"browser": "./dist/entry-browser",
"config": {
"platform": "all"
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"browser": "./dist/entrypoint/wasm-async.js",
"node": "./dist/entrypoint/wasm-async.js",
"default": "./dist/entrypoint/asmjs-async.js"
},
"./sync": {
"browser": "./dist/entrypoint/asmjs-sync.js",
"node": "./dist/entrypoint/wasm-sync.js",
"default": "./dist/entrypoint/asmjs-sync.js"
}
},
"files": [
"dist/**",
"src_js/**"
],
"scripts": {
"which": "which",
"autogypi": "autogypi",
"node-gyp": "node-gyp",
"emcc-path": "emcc-path",
"is-monolithic": "test \"$(basename \"$(pwd)\")\" = javascript",
"copy-sources": "! npm -s run is-monolithic || (rsync -r --checksum --delete ../yoga/ sources/yoga/)",
"build:node": "npm run copy-sources && autogypi && node-gyp configure build",
"build:browser": "npm run copy-sources && autogypi && node-gyp configure build --asmjs=1",
"build:all": "npm run build:node && npm run build:browser",
"build": "cross-env \"npm --if-present run build:$npm_package_config_platform\"",
"test:node": "TEST_ENTRY=node time mocha --compilers js:babel-core/register --expose-gc -r tests/tools.js tests/Facebook.Yoga/**/*.js",
"test:browser": "TEST_ENTRY=browser time mocha --compilers js:babel-core/register --expose-gc -r tests/tools.js tests/Facebook.Yoga/**/*.js",
"test": "npm run test:node && npm run test:browser",
"benchmark": "npm run prepublish && node tests/run-bench $(find tests/Benchmarks -name '*.js')",
"install": "npm run build:node",
"prepublish": "npm run copy-sources && babel sources --out-dir dist && flow-copy-source sources dist"
},
"dependencies": {
"autogypi": "^0.2.2",
"nbind": "^0.3.14",
"node-gyp": "^3.6.2"
"benchmark": "just benchmark",
"build": "just build",
"lint": "just lint",
"lint:fix": "just lint --fix",
"test": "just test",
"test:asmjs-async": "just test:asmjs-async",
"test:asmjs-sync": "just test:asmjs-sync",
"test:wasm-async": "just test:wasm-async",
"test:wasm-sync": "just test:wasm-sync"
},
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-plugin-replace-require": "^0.0.4",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^4.0.0",
"flow-copy-source": "^2.0.7",
"mocha": "^3.2.0"
"@babel/cli": "^7.20.7",
"@babel/core": "^7.20.7",
"@babel/eslint-parser": "^7.19.1",
"@babel/preset-env": "^7.20.2",
"clang-format": "^1.8.0",
"eslint": "^8.30.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^27.1.7",
"eslint-plugin-prettier": "^4.2.1",
"glob": "^8.0.3",
"jest": "^29.3.1",
"just-scripts": "^2.1.0",
"prettier": "^2.4.1",
"which": "^3.0.0"
}
}