Skip to content

Design Meeting Notes, 2/12/2021 #42783

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

ECMAScript Module Blocks Proposal

https://github.com/tc39/proposal-js-module-blocks

@RyanCavanaugh's notes

  • For web workers projects you have an entry point that is a separate file
  • Typically there is tight coupling between the invoker and the worker
  • Proposal: Instead of a filename, you can have a "module block"
  • This block is not lexically scoped (from a value perspective)
    • So what does TS do with scoping here?
  • Web workers are already a pain in TS because you need two (or more likely three, for shared types) "projects"
  • Can we implement this reasonably?
  • Q: Why do you need two projects?
    • A: WebWorker is on webworker context, "main" is on DOM. These have conflicting globals
  • The crux is what "script" (nonmodule) files contribute to each area's globals
  • Technically these module blocks can participate in multiple contexts
    • Maybe we need a concept of a "type" of the global scope, that could be even a union
    • Is that a real use case?
  • Downleveling - technically possible in Node?
  • We need to establish some boundaries on what you can and cannot use this for, e.g. multiple envs vs just single-env configurability
  • Questions
    • Could we tool this?
    • Do we support this proposal broadly?
    • Mixed opinions. Analogues in other languages are... not great
    • Some people like the tooling side effects
      • (joke about "side effects tho")
    • The scoping is confusing
    • But the scenario is compelling
    • Is the configurability desirable in other contexts?
  • Is this a blocking concern?
    • 🤷‍♂️
    • Concerns about complexity vs. value calculation
    • The configurability here is potentially very complex
  • (Sidebar: Discussion of implementation of program and symbol table incrementality)

My notes from when I forgot Ryan was also taking notes:

  • One idea is multiple global scopes, merged in different ways.
  • Ideally, each of these modules would be able to tell you when you're going to run it in an incompatible context.
    • Need to represent modules as functions from global scope to themselves.
      • Yes... that's why this proposal feels strange to some on the team. A new type of deferred code block.
      • That seems potentially fine.
  • This is very similar to the idea of "strict global environments" that Ryan was playing with a while back.
    • Problem then and now: how are two utterances of the same type from different global scopes compatible?
  • From a compilation perspective, there needs to be some place where you specify what exactly you wanted.
    • Likely we won't do the enforcement of "only allow this module to run in this context". You have to know what context you're going to run the module in, use it responsibly.
  • Could support module {} blocks, but not separate checking contexts.
    • // @ts-nocheck at top of module {} 😅
    • But the proposal champions seem interested in the "can we tool this correctly in TypeScript" case.
  • Backing up - what is the general feedback about the proposal itself?
    • Not a fan of new scoping rules
    • Reminded by blocks, procs confusion from Ruby?
    • "It's kinda like AppDomains"
      • "Yeah I didn't like AppDomains either"
    • Seems like this solves real problems though - "split your project into multiple" seems like a bad solution.
  • Want to communicate that module blocks will introduce a fair bit of complexity in how users will think about both their global and lexical environments - same applies to tooling authors. Unclear if it's really a net benefit in mental model.
    • Web workers are really not a simple scenario or API - a novice user who reaches for it might not realize it's overkill. A user who really understands might be building a full project anyway.
  • We are still interested in supporting multiple global environments.

Emit Change For Imports

#35420
#35877

  • Polyfill for promise.allsettled package.
    • Does something different depending on the this context.
  • If you write import allSettled from "promise.allsettled"
    • we transform references to that to promiseallsettled.default(...)
    • Babel transforms it to (0, promiseallsettled).default(...)
  • Point of (0, obj).method(...) is to avoid binding this incorrectly.
  • Editor's note: this is so annoying.
  • This is also an issue with namespaces.
  • Editor's note: 🙄
  • Perf impact?
    • Adds a very small amount of time to emit.
    • Non-zero but negligible
    • Only hits CommonJS, namespace code.
  • Pack the PR, get some partner teams to try it out.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions