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

feat(build)!: Introduce ESM entrypoints #8091

Merged
merged 4 commits into from
May 10, 2024
Merged

Conversation

cpcallen
Copy link
Contributor

The basics

The details

Resolves

Work towards #7449

Proposed Changes

Introduce an import conditional export for each of the entrypoints (blockly, blockly/core, blockly/blocks, blockly/javascript, etc., blockly/msg/en, blockly/msg/fr, etc.), and point these at wrappers created by build_tasks.js
that import the corresponding index.js / <chunk>_compressed.js / msg/<lang>.js CJS module and export its named exports.

Reason for Changes

Providing ESM entrypoints, even ones that are just wrappers of the existing CJS entrypoints, is the first step towards publishing Blockly as a pure-ESM package.

Test Coverage

  • Verified that npm test runs successfully.
  • Verified that import * as … from 'blockly/…' works correctly and as expected when run in node.js.
  • Verified that npm test runs successfully in blockly-samples rc/v11.0.0 branch, when linked against Blockly from this branch.

No changes to manual test procedures expected.

Documentation

  • Release notes should contain the breaking change notice below.
  • We need to check our published documentation and code samples for any incorrect imports. (The blockly-samples repository has already been checked and fixed in the rc/v11.0.0 branch.)

Additional Information

The ESM entrypoints provided by this PR are unfortunately still not directly importable by browsers, hence not being a complete fix for #7449. This is due to them directly importing the CJS (actually UMD) modules, which is supported by node.js and most build tooling but not by browsers, which do not natively support CJS. It may be possible to fix this in a future commit by providing a require polyfill, but doing this in a way that is compatible with build tooling and does not re-introduce the dual package hazard is not straightforward.

BREAKING CHANGE:

Importing Blockly via

import Blockly from 'blockly';

(and similarly for the other entrypoints) has worked until now because most build tools (including webpack in particular)
fulfil the request for the default export of a CJS module by providing the module.exports object, rather than an explicitly-named default export as they would for an ES module.

Since core/blockly.ts (the notional entrypoint for blockly/core) and the other chunk entrypoints do not provide a default export, the wrappers created by this PR do not either.

Code of the above form will therefore break, and should be updated to use a wildcard:

import * as Blockly from 'blockly';

Introduce an "import" conditional export for each of the chunk
entrypoints (blockly/core, blockly/blocks, blockly/javascript
etc.), and point these at wrappers created by build_tasks.js
that import the corresponding <chunk>_compressed.js file and
export its named exports.

BREAKING CHANGE:

Importing Blockly via

    import Blockly from 'blockly/core';

(and similarly for the other chunk entrypoints) has worked until
now because most build tools (including Webpack in particular)
fuilfil the request for the default export of a CJS module by
providing the module.exports object, rather than an
explicitly-named default export as they would for an ES module.

Since core/blockly.ts (the notional entrypoint for blockly/core)
does not provide a default export, the wrappers created by this
PR do not either.

Code of the above form will therefore break, and should be updated
to use a wildcard:

    import * as Blockly from 'blockly/core';
Introduce an "import" conditional export for the top-level
package entrypoint (blockly), and point it at a wrappers
created by build_tasks.js that imports the existing index.js
file.

BREAKING CHANGE:

Importing Blockly via

    import Blockly from 'blockly';

has worked until now because most build tools (including Webpack
in particular) fuilfil the request for the default export of a
CJS module by providing the module.exports object, rather than an
explicitly-named default export as they would for an ES module.

Since core/blockly.ts does not provide a default export, the
wrapper created by this PR does not either.

Code of the above form will therefore break, and should be updated
to use a wildcard:

    import * as Blockly from 'blockly';
Introduce an "import" conditional export for each of the
langfile entrypoints (msg/en, msg/fr, etc.),, and point them
at wrappers created by build_tasks.js that import the
existing <lang>.js file.

BREAKING CHANGE:

Importing languages via

    import en from 'blockly/msg/en';

has worked until now because most build tools (including Webpack
in particular) fuilfil the request for the default export of a
CJS module by providing the module.exports object, rather than an
explicitly-named default export as they would for an ES module.

Code of the above form will therefore break, and should be updated
to use a wildcard:

    import * as en from 'blockly/msg/en';
For some reason we had a typings/msg/yue.d.ts that did not
correxpond to any msg/json/yue.json.  Delete it.
@cpcallen cpcallen added component: build process breaking change Used to mark a PR or issue that changes our public APIs. PR: feature Adds a feature labels May 10, 2024
@cpcallen cpcallen requested a review from a team as a code owner May 10, 2024 21:23
@cpcallen cpcallen requested a review from NeilFraser May 10, 2024 21:23
@github-actions github-actions bot added breaking change Used to mark a PR or issue that changes our public APIs. PR: feature Adds a feature and removed PR: feature Adds a feature breaking change Used to mark a PR or issue that changes our public APIs. labels May 10, 2024
@cpcallen
Copy link
Contributor Author

It might be helpful when reviewing to know that the generated wrappers have the form (e.g. blockly.mjs):

import Blockly from './blockly_compressed.js';
export const {
  ASTNode,
  BasicCursor,
  Block,
  // ...
  utils,
  zelos,
} = Blockly;

@cpcallen cpcallen merged commit 2ebdc0b into google:rc/v11.0.0 May 10, 2024
11 checks passed
@cpcallen cpcallen deleted the feat/7449 branch May 10, 2024 21:42
@cpcallen cpcallen mentioned this pull request May 10, 2024
13 tasks
@cpcallen cpcallen mentioned this pull request May 22, 2024
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Used to mark a PR or issue that changes our public APIs. component: build process PR: feature Adds a feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants