Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yoga 2.0.0 Beta Release Feedback #1320

Closed
NickGerleman opened this issue Jun 30, 2023 · 8 comments
Closed

Yoga 2.0.0 Beta Release Feedback #1320

NickGerleman opened this issue Jun 30, 2023 · 8 comments

Comments

@NickGerleman
Copy link
Contributor

Today we released Yoga 2.0.0-beta.1 across multiple channels. We've introduced a good number of changes, and would like feedback from users who are upgrading to it from older versions of Yoga.

Please leave a comment on this thread with any feedback from using the release.

@Omxjep3434
Copy link

I'm so excited that an npm package is getting attention! I was previously using the yoga-layout-prebuilt package.

I could use advice on how to deal with the asynchronous nature of loadYoga(). In a simple project where all code is in one file, it is quite trivial. But in a real-world project where code is split into multiple files, what is the best way to deal with this? For example, I am writing a UI framework where multiple classes create nodes, and they need to be created synchronously. With a synchronous Yoga, this is a non-issue - you can just call Yoga.createNode() anywhere. I am thinking that the correct pattern is to have a global initialization method for my framework that calls loadYoga() and populates some variable such as MyFramework.yoga. Then, other classes create nodes using MyFramework.yoga.createNode(), assuming that the user of my framework called the global initialization method. Am I on the right track with this pattern, or is there a simpler way to handle this issue?

Also, I noticed that 2.0.0-beta.1 doesn't work with Webpack and opened an issue here: #1321

@NickGerleman
Copy link
Contributor Author

NickGerleman commented Jul 1, 2023

I could use advice on how to deal with the asynchronous nature of loadYoga()

If you have an environment that supports top-level await, I would recommend this pattern:

// YogaInstance.js
import {loadYoga} from 'yoga-layout';

const YogaInstance = await loadYoga();
export default YogaInstance;
// YogaUser.js
import Yoga from './YogaInstance';
...

That way, you get a sync looking import, but the import system awaits for the async compilation. This also matches the behavior which is being specced for WebAssembly ESM integration.

I hoped to use these semantics in the package, but the tooling compatibility wasn't there yet to make a library that could work out-of-the-box everywhere. So right now Yoga is a CommonJS interoperable JS module, embedding WebAssembly. In the future I would like to use proper WebAssembly ESM integration, for smaller binaries, sync interface, and streaming compilation of remote assets.

I am thinking that the correct pattern is to have a global initialization method for my framework that calls loadYoga() and populates some variable such as MyFramework.yoga. Then, other classes create nodes using MyFramework.yoga.createNode(), assuming that the user of my framework called the global initialization method. Am I on the right track with this pattern, or is there a simpler way to handle this issue?

I think that is the rough solution if you cannot hide it behind the import system. Explicitly await somewhere, to cache an instance, so you can use it synchronously in the future.

@jordanebelanger
Copy link

Bit disappointed with end of support for Yogakit.

I use this yogakit wrapper in my projects and it works great, superb alternative to spring&strut and autolayout (lmao).

The less broken version of SwiftUI is still only compatible with iOS 15 and up, so native rewrites of major apps with it are still years off.

@thosil
Copy link

thosil commented Jul 6, 2023

Hello,

I'm very happy for the new direction of this project :-)

I'm trying to use it with Next.js and had some issue to make them working together with other dependencies (like @vercel/analytics, next-auth, @headlessui/react, ...).

Here's how I got it to work:

  1. Upgrade packages:
    1. next → 13.4.8
    2. typescript → 5.1.6
  2. In tsconfig.json, set moduleResolution to "bundler", but sometimes next.js modify the file and set it back to "node". Node16 or NodeNext will not work with other packages.
  3. In next.config.js add a webpack custom config.resolve.fallback with fs and path to false
  4. For next-auth, import type Provide as import {Provider} from "next-auth/providers/index" (the "index" is the key to make ts happy)

Example next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.fallback = {
      fs: false,
      path: false,
    };
    return config;
  },
};

module.exports = nextConfig;

That said, it would be easier if we could leave moduleResolution to "node". Before trying the new version, I used the npm package "yoga-wasm-web" which didn't required to modify the default config.

@NickGerleman
Copy link
Contributor Author

Bit disappointed with end of support for Yogakit.

I use this yogakit wrapper in my projects and it works great, superb alternative to spring&strut and autolayout (lmao).

The less broken version of SwiftUI is still only compatible with iOS 15 and up, so native rewrites of major apps with it are still years off.

We released a (deprecated) YogaKit 2.0.0-beta.1 package, for projects which may rely on YogaKit, and need updates for XCode 14.3 compat. My hope is that this can be used in the short term by any projects which may need it. YogaKit itself has not changed in many years, so I expect projects relying on it may choose to inline or fork it in the longer term.

@NickGerleman
Copy link
Contributor Author

Also, I noticed that 2.0.0-beta.1 doesn't work with Webpack and opened an issue here: #1321

  1. In next.config.js add a webpack custom config.resolve.fallback with fs and path to false

Example next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.fallback = {
      fs: false,
      path: false,
    };
    return config;
  },
};

module.exports = nextConfig;

I am going to split the WASM entrypoints into separate flavors for Node and Web. This will mean that a bundler targeting web will no longer reach code which attempts to import Node APIs. It also lets us make the Node entrypoint more efficient.

Downside, is this goes further down the rabbit hole of relying on ESM resolution for per-platform code.

@NickGerleman
Copy link
Contributor Author

NickGerleman commented Jul 11, 2023

That said, it would be easier if we could leave moduleResolution to "node". Before trying the new version, I used the npm package "yoga-wasm-web" which didn't required to modify the default config.

This one is really annoying. At the same time ESM resolution really does give us a lot, and feels like a more forward-looking option.

I think, we could maybe add documentation to use imports like yoga-layout/src/entrypoint/wasm-async-web in environments which do not fully support ESM resolution. It is a little bit kludgey though, especially with Next.JS not supporting ESM resolution with typechecking out-of-the-box. This would also potentially cause problems where the bundler but not the typechecker is configured to use this.

@NickGerleman NickGerleman changed the title Yoga 2.0.0-beta.1 Release Feedback Yoga 2.0.0 Beta Release Feedback Jul 12, 2023
@NickGerleman
Copy link
Contributor Author

I removed the beta label and marked the package as 2.0.0 now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants