Skip to content

sea: support embedding assets#50960

Closed
joyeecheung wants to merge 5 commits intonodejs:mainfrom
joyeecheung:sea-assets
Closed

sea: support embedding assets#50960
joyeecheung wants to merge 5 commits intonodejs:mainfrom
joyeecheung:sea-assets

Conversation

@joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Nov 29, 2023

src: print string content better in BlobDeserializer

When it's a short string, print it inline, otherwise print it
from a separate line. Also add the missing line breaks finally.

sea: support embedding assets

With this patch:

Users can now include assets by adding a key-path dictionary
to the configuration as the assets field. At build time, Node.js
would read the assets from the specified paths and bundle them into
the preparation blob. In the generated executable, users can retrieve
the assets using the sea.getAsset() and sea.getAssetAsBlob() API.

{
  "main": "/path/to/bundled/script.js",
  "output": "/path/to/write/the/generated/blob.blob",
  "assets": {
    "a.jpg": "/path/to/a.jpg",
    "b.txt": "/path/to/b.txt"
  }
}

The single-executable application can access the assets as follows:

const { getAsset } = require('node:sea');
// Returns a copy of the data in an ArrayBuffer
const image = getAsset('a.jpg');
// Returns a string decoded from the asset as UTF8.
const text = getAsset('b.txt', 'utf8');
// Returns a Blob containing the asset without copying.
const blob = getAssetAsBlob('a.jpg');

Drive-by: update the documentation to include a section dedicated
to the injected main script and refer to it as "injected main
script" instead of "injected module" because it's a script, not
a module.

Refs: nodejs/single-executable#68

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/loaders
  • @nodejs/single-executable
  • @nodejs/startup

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Nov 29, 2023
@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Nov 29, 2023
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Nov 29, 2023
@nodejs-github-bot
Copy link
Collaborator

@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Nov 29, 2023
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Nov 29, 2023
@nodejs-github-bot
Copy link
Collaborator

@targos
Copy link
Member

targos commented Nov 29, 2023

Should we have a getAssetNames() API or something else that allows the user to list the bundled assets?

@joyeecheung
Copy link
Member Author

From #50941 (comment)

What is wrong with saying in docs here is an ArrayBuffer, but if you mess with it you’ll crash? Then as a developer I could just adhere to that and live happily ever after.

One thing we need to decide: should we expose getRawAsset() to allow users reading the asset directly without copying. With a Blob users still have to do some form of copying at the end of the day unless their use case is piping the whole thing. Currently if you get the raw buffer and then wrap it with an ArrayBufferView and then mutate any of the elements, the process would crash due to access protection (probably because the segments postject uses are protected, or I'm not sure if there are unprotected segments we can do this injection with)

@pipobscure
Copy link
Contributor

Just a note: I really appreciate this happening. I have previously been using nexe and pkg and therefore know a lot of the pain points of trying to keep current with node. So I just want to give @joyeecheung huge thanks and kudos for moving this forward! THANKS

Copy link
Contributor

@aduh95 aduh95 left a comment

Choose a reason for hiding this comment

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

A few nits

"disableExperimentalSEAWarning": true, // Default: false
"useSnapshot": false, // Default: false
"useCodeCache": true // Default: false
"useCodeCache": true, // Default: false
Copy link
Member

Choose a reason for hiding this comment

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

@nodejs/single-executable I recommend creating a JSON schema and distributing it through nodejs.org, to have better intellisense when this json includes "$schema" parameter. This could help with maintenance and usability.

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you want to open an issue in https://github.com/nodejs/single-executable/issues instead?

@targos
Copy link
Member

targos commented Dec 4, 2023

Just repeating #50960 (comment) in case you missed it:

Should we have a getAssetNames() API or something else that allows the user to list the bundled assets?

@marco-ippolito marco-ippolito mentioned this pull request Mar 1, 2024
@richardlau richardlau mentioned this pull request Mar 25, 2024
@CMCDragonkai
Copy link

Can this be used for native so binaries and then pass them somehow into process.dlopen?

@pipobscure
Copy link
Contributor

pipobscure commented May 18, 2024 via email

@CMCDragonkai
Copy link

What about the VFS idea?

@pipobscure
Copy link
Contributor

pipobscure commented May 18, 2024 via email

@joyeecheung
Copy link
Member Author

VFS would need to built on top of proper fs hooks which is related to SEA, but also there are many other use cases for such hooks, one previous proposal is nodejs/single-executable#43 (I think there are others, but can't find the links).

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

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants