Fixup TypeScript with export maps (#1284)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1284 This makes TypeScript resolution play nicely with export maps, and converts the entrypoints to TypeScript. We remove the non-export-map fallbacks as well, so the export maps are always followed. Tests are moved to load yoga from its external export, testing the entrypoints. This moves the only untyped bit to the binary wrapper, which another diff will move. Reviewed By: yungsters Differential Revision: D45713689 fbshipit-source-id: 228e6f2c9d53520230707a81e76c3c35fcd46de5
This commit is contained in:
committed by
Facebook GitHub Bot
parent
104646d8ca
commit
af89315fd4
@@ -7,20 +7,20 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
ignorePatterns: ["dist/**", "tests/generated/**"],
|
||||
extends: ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
plugins: ["prettier"],
|
||||
ignorePatterns: ['dist/**', 'tests/generated/**'],
|
||||
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
|
||||
plugins: ['prettier'],
|
||||
rules: {
|
||||
"no-var": "error",
|
||||
"prefer-arrow-callback": "error",
|
||||
"prefer-const": "error",
|
||||
"prefer-object-spread": "error",
|
||||
"prefer-spread": "error",
|
||||
"require-await": "error",
|
||||
'no-var': 'error',
|
||||
'prefer-arrow-callback': 'error',
|
||||
'prefer-const': 'error',
|
||||
'prefer-object-spread': 'error',
|
||||
'prefer-spread': 'error',
|
||||
'require-await': 'error',
|
||||
},
|
||||
env: {
|
||||
commonjs: true,
|
||||
@@ -28,44 +28,44 @@ module.exports = {
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["**/*.js"],
|
||||
parser: "@babel/eslint-parser",
|
||||
files: ['**/*.js'],
|
||||
parser: '@babel/eslint-parser',
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
configFile: path.join(__dirname, ".babelrc.js"),
|
||||
configFile: path.join(__dirname, '.babelrc.js'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.ts"],
|
||||
extends: ["plugin:@typescript-eslint/recommended"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
files: ['**/*.ts'],
|
||||
extends: ['plugin:@typescript-eslint/recommended'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: path.join(__dirname, "tsconfig.json"),
|
||||
project: path.join(__dirname, 'tsconfig.json'),
|
||||
},
|
||||
plugins: ["@typescript-eslint"],
|
||||
plugins: ['@typescript-eslint'],
|
||||
rules: {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/.eslintrc.js", "**/just.config.js"],
|
||||
files: ['**/.eslintrc.js', '**/just.config.js'],
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["jest.*", "tests/**"],
|
||||
files: ['jest.*', 'tests/**'],
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: ["plugin:jest/recommended"],
|
||||
extends: ['plugin:jest/recommended'],
|
||||
globals: {
|
||||
getMeasureCounter: "writable",
|
||||
getMeasureCounterMax: "writable",
|
||||
getMeasureCounterMin: "writable",
|
||||
Yoga: "writable",
|
||||
YGBENCHMARK: "writable",
|
||||
getMeasureCounter: 'writable',
|
||||
getMeasureCounterMax: 'writable',
|
||||
getMeasureCounterMin: 'writable',
|
||||
Yoga: 'writable',
|
||||
YGBENCHMARK: 'writable',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
1
javascript/.gitignore
vendored
1
javascript/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/binaries
|
||||
/build
|
||||
/dist
|
||||
/node_modules
|
||||
|
@@ -49,7 +49,7 @@ link_libraries(embind)
|
||||
|
||||
add_library(yogaObjLib OBJECT ${SOURCES})
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dist/build)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
|
||||
|
||||
add_executable(asmjs-sync $<TARGET_OBJECTS:yogaObjLib>)
|
||||
target_link_options(asmjs-sync PUBLIC
|
||||
|
@@ -44,7 +44,7 @@ For better performance and smaller packages, WebAssembly is preferred to asm.js
|
||||
A specific entrypoint may be specified on platforms which do not understand export conditions.
|
||||
|
||||
```ts
|
||||
import {loadYoga} from 'yoga-layout/dist/entrypoint/wasm-async';
|
||||
import {loadYoga} from 'yoga-layout/wasm-async';
|
||||
```
|
||||
|
||||
|
||||
|
@@ -9,13 +9,13 @@
|
||||
|
||||
module.exports = async () => {
|
||||
if (process.env['SYNC'] === '1' && process.env['WASM'] === '1') {
|
||||
globalThis.Yoga = require('./dist/entrypoint/wasm-sync');
|
||||
globalThis.Yoga = require('yoga-layout/wasm-sync').default;
|
||||
} else if (process.env['SYNC'] === '1') {
|
||||
globalThis.Yoga = require('./dist/entrypoint/asmjs-sync');
|
||||
globalThis.Yoga = require('yoga-layout/asmjs-sync').default;
|
||||
} else if (process.env['WASM'] === '1') {
|
||||
globalThis.Yoga = await require('./dist/entrypoint/wasm-async').loadYoga();
|
||||
globalThis.Yoga = await require('yoga-layout/wasm-async').loadYoga();
|
||||
} else {
|
||||
globalThis.Yoga = await require('./dist/entrypoint/asmjs-async').loadYoga();
|
||||
globalThis.Yoga = await require('yoga-layout/asmjs-async').loadYoga();
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -21,6 +21,8 @@ import {
|
||||
tscTask,
|
||||
} from 'just-scripts';
|
||||
|
||||
import {readFile, writeFile} from 'fs/promises';
|
||||
|
||||
import glob from 'glob';
|
||||
import path from 'path';
|
||||
import which from 'which';
|
||||
@@ -84,15 +86,38 @@ task(
|
||||
),
|
||||
);
|
||||
|
||||
task('prepack-package-json', async () => {
|
||||
const packageJsonPath = path.join(__dirname, 'package.json');
|
||||
const packageJsonContents = await readFile(packageJsonPath);
|
||||
const packageJson = JSON.parse(packageJsonContents.toString('utf-8'));
|
||||
|
||||
recursiveReplace(packageJson, /(.\/src\/.*)\.ts/, '$1.js');
|
||||
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
});
|
||||
|
||||
task(
|
||||
'prepublish',
|
||||
parallel(
|
||||
'build',
|
||||
tscTask({emitDeclarationOnly: true}),
|
||||
'prepack',
|
||||
series(
|
||||
parallel('build', tscTask({emitDeclarationOnly: true})),
|
||||
babelTransformTask({dir: 'src'}),
|
||||
'prepack-package-json',
|
||||
),
|
||||
);
|
||||
|
||||
function recursiveReplace(
|
||||
obj: Record<string, unknown>,
|
||||
pattern: RegExp,
|
||||
replacement: string,
|
||||
) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (typeof value === 'string') {
|
||||
obj[key] = value.replace(pattern, replacement);
|
||||
} else if (typeof value === 'object' && value != null) {
|
||||
recursiveReplace(value as Record<string, unknown>, pattern, replacement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function babelTransformTask(opts: {dir: string}) {
|
||||
return () => {
|
||||
const args = [
|
||||
|
@@ -7,22 +7,24 @@
|
||||
"type": "git",
|
||||
"url": "git@github.com:facebook/yoga.git"
|
||||
},
|
||||
"main": "./src/index.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"browser": "./src/entrypoint/wasm-async.js",
|
||||
"node": "./src/entrypoint/wasm-async.js",
|
||||
"default": "./src/entrypoint/asmjs-async.js"
|
||||
"browser": "./src/entrypoint/wasm-async.ts",
|
||||
"node": "./src/entrypoint/wasm-async.ts",
|
||||
"default": "./src/entrypoint/asmjs-async.ts"
|
||||
},
|
||||
"./sync": {
|
||||
"browser": "./src/entrypoint/asmjs-sync.js",
|
||||
"node": "./src/entrypoint/wasm-sync.js",
|
||||
"default": "./src/entrypoint/asmjs-sync.js"
|
||||
}
|
||||
"browser": "./src/entrypoint/asmjs-sync.ts",
|
||||
"node": "./src/entrypoint/wasm-sync.ts",
|
||||
"default": "./src/entrypoint/asmjs-sync.ts"
|
||||
},
|
||||
"./asmjs-async": "./src/entrypoint/asmjs-async.ts",
|
||||
"./asmjs-sync": "./src/entrypoint/asmjs-sync.ts",
|
||||
"./wasm-async": "./src/entrypoint/wasm-async.ts",
|
||||
"./wasm-sync": "./src/entrypoint/wasm-sync.ts"
|
||||
},
|
||||
"files": [
|
||||
"dist/**",
|
||||
"binaries/**",
|
||||
"src/**"
|
||||
],
|
||||
"scripts": {
|
||||
@@ -31,7 +33,7 @@
|
||||
"clean": "just clean",
|
||||
"lint": "just lint",
|
||||
"lint:fix": "just lint --fix",
|
||||
"prepublish": "just prepublish",
|
||||
"prepack": "just prepack",
|
||||
"test": "just test",
|
||||
"test:asmjs-async": "just test:asmjs-async",
|
||||
"test:asmjs-sync": "just test:asmjs-sync",
|
||||
|
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const wrapAsm = require('../wrapAsm');
|
||||
|
||||
module.exports = loadAsm => ({
|
||||
loadYoga: () => loadAsm().then(wrapAsm),
|
||||
...require('../generated/YGEnums'),
|
||||
});
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const wrapAsm = require('../wrapAsm');
|
||||
module.exports = asm => wrapAsm(asm());
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const asm = require('../build/asmjs-async');
|
||||
module.exports = require('./_entryAsync')(asm);
|
26
javascript/src/entrypoint/asmjs-async.ts
Normal file
26
javascript/src/entrypoint/asmjs-async.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import wrapAssembly from '../wrapAssembly';
|
||||
import type {Yoga} from '../wrapAssembly';
|
||||
|
||||
export * from '../generated/YGEnums';
|
||||
export type {
|
||||
Config,
|
||||
DirtiedFunction,
|
||||
MeasureFunction,
|
||||
Node,
|
||||
Yoga,
|
||||
} from '../wrapAssembly';
|
||||
|
||||
const loadAssembly = require('../../binaries/asmjs-async');
|
||||
|
||||
export async function loadYoga(): Promise<Yoga> {
|
||||
return wrapAssembly(await loadAssembly());
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const asm = require('../build/asmjs-sync');
|
||||
module.exports = require('./_entrySync')(asm);
|
23
javascript/src/entrypoint/asmjs-sync.ts
Normal file
23
javascript/src/entrypoint/asmjs-sync.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import wrapAssembly from '../wrapAssembly';
|
||||
|
||||
export * from '../generated/YGEnums';
|
||||
export type {
|
||||
Config,
|
||||
DirtiedFunction,
|
||||
MeasureFunction,
|
||||
Node,
|
||||
Yoga,
|
||||
} from '../wrapAssembly';
|
||||
|
||||
const loadAssembly = require('../../binaries/asmjs-sync');
|
||||
const Yoga = wrapAssembly(loadAssembly());
|
||||
export default Yoga;
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const asm = require('../build/wasm-async');
|
||||
module.exports = require('./_entryAsync')(asm);
|
26
javascript/src/entrypoint/wasm-async.ts
Normal file
26
javascript/src/entrypoint/wasm-async.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import wrapAssembly from '../wrapAssembly';
|
||||
import type {Yoga} from '../wrapAssembly';
|
||||
|
||||
export * from '../generated/YGEnums';
|
||||
export type {
|
||||
Config,
|
||||
DirtiedFunction,
|
||||
MeasureFunction,
|
||||
Node,
|
||||
Yoga,
|
||||
} from '../wrapAssembly';
|
||||
|
||||
const loadAssembly = require('../../binaries/wasm-async');
|
||||
|
||||
export async function loadYoga(): Promise<Yoga> {
|
||||
return wrapAssembly(await loadAssembly());
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
const asm = require('../build/wasm-sync');
|
||||
module.exports = require('./_entrySync')(asm);
|
23
javascript/src/entrypoint/wasm-sync.ts
Normal file
23
javascript/src/entrypoint/wasm-sync.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import wrapAssembly from '../wrapAssembly';
|
||||
|
||||
export * from '../generated/YGEnums';
|
||||
export type {
|
||||
Config,
|
||||
DirtiedFunction,
|
||||
MeasureFunction,
|
||||
Node,
|
||||
Yoga,
|
||||
} from '../wrapAssembly';
|
||||
|
||||
const loadAssembly = require('../../binaries/wasm-sync');
|
||||
const Yoga = wrapAssembly(loadAssembly());
|
||||
export default Yoga;
|
15
javascript/src/index.d.ts
vendored
15
javascript/src/index.d.ts
vendored
@@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {Yoga} from './wrapAsm';
|
||||
|
||||
export * from './generated/YGEnums';
|
||||
export * from './wrapAsm';
|
||||
|
||||
export function loadYoga(): Promise<Yoga>;
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
// Fallback for when the export map is not followed
|
||||
module.exports = require('./entrypoint/asmjs-async');
|
16
javascript/src/sync.d.ts
vendored
16
javascript/src/sync.d.ts
vendored
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {Yoga} from './wrapAsm';
|
||||
|
||||
export * from './generated/YGEnums';
|
||||
export * from './wrapAsm';
|
||||
|
||||
declare const yoga: Yoga;
|
||||
export default yoga;
|
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
// Fallback for when the export map is not followed
|
||||
module.exports = require('./entrypoint/asmjs-sync');
|
@@ -187,5 +187,5 @@ export type Yoga = {
|
||||
};
|
||||
} & typeof YGEnums;
|
||||
|
||||
declare const wrapAsm: () => Yoga;
|
||||
declare const wrapAsm: (assembly: unknown) => Yoga;
|
||||
export default wrapAsm;
|
@@ -10,6 +10,9 @@
|
||||
|
||||
import path from 'path';
|
||||
|
||||
import YogaAsmjs from 'yoga-layout/asmjs-sync';
|
||||
import YogaWasm from 'yoga-layout/wasm-sync';
|
||||
|
||||
const WARMUP_ITERATIONS = 3;
|
||||
const BENCHMARK_ITERATIONS = 10;
|
||||
|
||||
@@ -18,9 +21,7 @@ const testFiles = process.argv.slice(2);
|
||||
const testResults = new Map<string, Map<string, number>>();
|
||||
|
||||
for (const type of ['asmjs', 'wasm']) {
|
||||
globalThis.Yoga = require(type === 'asmjs'
|
||||
? '../../dist/entrypoint/asmjs-sync'
|
||||
: '../../dist/entrypoint/wasm-sync');
|
||||
globalThis.Yoga = type === 'asmjs' ? YogaAsmjs : YogaWasm;
|
||||
|
||||
for (const file of testFiles) {
|
||||
globalThis.YGBENCHMARK = (name: string, fn: () => void) => {
|
||||
|
@@ -6,8 +6,11 @@
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
// TODO: moduleResolution: "nodenext" is buggy with this if the absolute
|
||||
// path contains any capital letters
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"baseUrl": ".",
|
||||
"moduleResolution": "nodenext",
|
||||
"paths": {
|
||||
"yoga-layout": ["src"]
|
||||
}
|
||||
|
Reference in New Issue
Block a user