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

Move to ESM modules #8460

Merged
merged 2 commits into from Feb 5, 2024
Merged

Move to ESM modules #8460

merged 2 commits into from Feb 5, 2024

Conversation

Pessimistress
Copy link
Collaborator

@Pessimistress Pessimistress commented Jan 30, 2024

Changelist

  • Bump ocular-dev-tools
  • package.json
  • Remove babel config, use Typescript transforms
  • Minor change to bundle entry points to use transformed code, see comments inline
  • Minor change to some import paths (relative imports must reference filename, i.e. import {add} from '../utils' => import {add} from '../utils/index') see Move to ESM modules #8460 (comment)

Tested Workflows

  • Bootstrap
  • Build
    • ESM entry (import('@deck.gl/core'))
    • CJS entry (require('@deck.gl/core'))
    • Script bundle
  • Lint
  • Examples start-local
  • Test
    • node
    • browser-headless

TODO

  • The following modules do not build: arcgis, test-utils due to TypeScript errors, will address in future PRs
  • Migrate babel remove-glsl-comments plug-in to TS transform

examples/layer-browser/src/data-samples.js Show resolved Hide resolved
modules/aggregation-layers/bundle.ts Show resolved Hide resolved
@@ -16,7 +16,7 @@ import {
vectorQuerySource,
vectorTableSource,
vectorTilesetSource
} from '../sources';
} from '../sources/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could avoid all these 'xxxxxx/index' imports by using experimentalSpecifierResolution in tsconfig

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that these import paths don't just affect source code, they also persist into *.d.ts files, and will break in a downstream application with TSConfig using node16(+) or nodenext. See:

Ideally — I think we should either go one step further and add .js extensions, like ../sources/index.js, or else take @ibgreen's suggestion from visgl/luma.gl#1861 (comment) and post-process the *.d.ts files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.js extension is added with a custom typescript transform, hence xxx/index which is processed into xxx/index.js.

We could alternatively write all the extensions into src, I was trying to avoid too many changes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd missed the custom TS transform, that sounds like a good solution to me!

One other option would be to bundle the type definitions into a single file with something like tsup or dts-buddy — no need for extensions if there are no imports! — but if the custom TS transform is working already, I'd vote for that. 👍🏻

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I like the idea of bundling the d.ts files. Just like we now bundle both the ESM and commonJS code, it would be neat to bundle the types. If you are familiar with the tools, you could perhaps test it in some repo and then we can upstream to ocular?

@Pessimistress Pessimistress changed the title [WIP] Move to ESM modules Move to ESM modules Feb 4, 2024
@Pessimistress Pessimistress marked this pull request as ready for review February 4, 2024 19:22
Copy link
Collaborator

@ibgreen ibgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from removing the @luma.gl/webgl re-export in scripts, these are just nits and thoughts.

format: 'umd',
globals: {
'@deck.gl/*': 'globalThis.deck',
'@luma.gl/core': 'globalThis.luma',
'@luma.gl/engine': 'globalThis.luma',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: If the * notation works, might be useful for both luma and loaders? Any reason not to?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The luma and loaders global objects are to make sure that there is only one copy of a module. User access of the exported classes is just a bonus. This is also the reason why I'm not cherry picking the exports - what's exported is not determined by their usefulness, but by necessity if they are referenced anywhere in the code path. If we cherry pick, it's going to be a long list due to the sprawling interface between deck and luma, and the list has to be re-audited every time we make a change.

"module": "dist/index.js",
"exports": {
".": {
"import": "./dist/index.js",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

types?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module is still in js, see todo list.

@@ -16,7 +16,7 @@ import {
vectorQuerySource,
vectorTableSource,
vectorTilesetSource
} from '../sources';
} from '../sources/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I like the idea of bundling the d.ts files. Just like we now bundle both the ESM and commonJS code, it would be neat to bundle the types. If you are familiar with the tools, you could perhaps test it in some repo and then we can upstream to ocular?

@@ -32,7 +32,7 @@ export type {
RequestType,
QueryParameters,
QueryOptions
} from './api';
} from './api/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total nit: I am not a fan of nested index files, I'd just import from the individual files. But since this is the carto module my opinion doesn't matter :)

@@ -1,11 +1,7 @@
import {getLoggers} from '../src/debug/loggers';
// @ts-nocheck
import {getLoggers} from '@deck.gl/core/debug/loggers';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: Do we even need this module? It only seems to repackage core stuff? Something we could drop in v9?Are we trying to replace a call to deck.registerLoggers() with an require in scripts. Is it to handle some timing condition during imports? Not a big deal, if this is still useful feel free to keep it, no need to have long discussion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This importing from module subpaths is a bit of a yellow flag to me. It has caused me a lot of problems in the past with various build tools, so I would avoid it if possible. Maybe just export _getLoggers from the main package?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole point of this file is to NOT include verbose debug messages in the main bundle. https://deck.gl/docs/developer-guide/debugging#deckgl-logging

The import path is not exposed by the published package. This file is only used when building debug.min.js.

@@ -132,7 +139,7 @@ export type {PickingInfo, GetPickingInfoParams} from './lib/picking/pick-info';
export type {ConstructorOf as _ConstructorOf} from './types/types';
export type {BinaryAttribute} from './lib/attribute/attribute';
export type {Effect, PreRenderOptions, PostRenderOptions} from './lib/effect';
export type {PickingUniforms, ProjectUniforms} from './shaderlib';
export type {PickingUniforms, ProjectUniforms} from './shaderlib/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Is this listing of /index required by the new tooling or just a personal preference?
  • Total nit, my preference is to avoid nested index files. There are of course exceptions, but generally to me they end up just adding more clutter and indirection.
  • So I guess I could argues that this is a good change as doesn't actually add index files but rather shines a light on where we are using index files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can no longer import from directory in ESM.
#8460 (comment)

I don't have a strong opinion about code organization, just trying to keep irrelevant changes to the minimum in this PR.

export * from '@luma.gl/core';
export * from '@luma.gl/engine';
// @ts-ignore Module '@luma.gl/core' has already exported a member named 'AccessorObject'
export * from '@luma.gl/webgl';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be exposing the webgl module anymore. If there is any particular export we feel we need that isn't visible from core, it should be solved in luma.gl

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The webgl module does not work if there are multiple copies, so @deck.gl/core bundles it and exposes it under globalThis.luma. Unless you want the users of the scripting interface to always include an additional package from luma.gl, this has to stay.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summarize an offline discussion: we should make a follow-up pass of the code base to completely remove any direct reference of @luma.gl/webgl, after which this re-export will not be necessary.

@@ -1,15 +1,4 @@
#!/bin/bash

# Add commonjs entry points to pure ESM modules. Needed by running node tests.
npx babel node_modules/@mapbox/tiny-sdf/index.js > node_modules/@mapbox/tiny-sdf/index.cjs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess CJS applications using deck still need to do this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well that's not really within our control..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a replacement for these widget overrides somewhere else?

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

Successfully merging this pull request may close these issues.

None yet

5 participants