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(adapter-node): support all esbuild build options #1692

Closed
wants to merge 2 commits into from

Conversation

sastan
Copy link
Contributor

@sastan sastan commented Jun 15, 2021

This PR allows changing the options passed to esbuild build which allows to customize the server generation like target node version, sourcemap, inject, and more.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpx changeset and following the prompts

@changeset-bot
Copy link

changeset-bot bot commented Jun 15, 2021

🦋 Changeset detected

Latest commit: 3ee4efe

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/adapter-node Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@jthegedus
Copy link
Contributor

jthegedus commented Jun 15, 2021

I think it would be more clear if these options were nested under a single esbuildOptions param field instead of spread amongst the base param obj.

@sastan
Copy link
Contributor Author

sastan commented Jun 16, 2021

I think it would be more clear if these options were nested under a single esbuildOptions param field instead of spread amongst the base param obj.

I have adjusted the PR to use a esbuildOptions parameter. I changed the default options to use outdir instead of outfile to support code splitting. This still creates a single build/index.js file because the entrypoints filename is index.js. If the outfile option is set outdir will not be used because esbuild expects either outfile or outdir.

@sastan sastan force-pushed the adapter-node-esbuild-options branch 2 times, most recently from e530e1e to dfae928 Compare June 16, 2021 07:26
@mohe2015
Copy link
Contributor

Commit message has a typo.

@sastan sastan force-pushed the adapter-node-esbuild-options branch from dfae928 to 8e765d3 Compare June 16, 2021 15:49
@sastan
Copy link
Contributor Author

sastan commented Jun 16, 2021

Commit message has a typo.

Sorry, I do not know what you mean.

@mohe2015
Copy link
Contributor

c6075d7
I assume the title is supposed to be "adapter" and not "adpater"

@sastan sastan changed the title feat(adpater-node): support all esbuild build options feat(adapter-node): support all esbuild build options Jun 16, 2021
@sastan sastan force-pushed the adapter-node-esbuild-options branch 3 times, most recently from bd65b73 to 9ae2301 Compare June 16, 2021 16:42
@mohe2015
Copy link
Contributor

c6075d7
I assume the title is supposed to be "adapter" and not "adpater"

Same thing in the commit message. (Don't know if you will fix it later or overlooked it)

@sastan
Copy link
Contributor Author

sastan commented Jun 17, 2021

c6075d7
I assume the title is supposed to be "adapter" and not "adpater"

Same thing in the commit message. (Don't know if you will fix it later or overlooked it)

I can not fix that now. But I believe that PRs are squashed and use the PR title (which is fixed) as commit message.

@jthegedus
Copy link
Contributor

Just thought I would raise before we adopt esbuild more significantly, but the initial usage of esbuild was a suggested soln

Mostly just playing around for now, but this is intended to solve the perennial problem of dependencies behaving weirdly, by allowing adapters to determine what gets bundled.

-Rich Harris in #1091

Has there been more thought on alternative solutions or is esbuild usage likely to stick around? @Conduitry @benmccann

@benmccann
Copy link
Member

@jthegedus it's not an area I understand well, so I will defer to Rich and Conduitry

@benmccann
Copy link
Member

benmccann commented Jun 21, 2021

There's a related PR for adapter-vercel here: #1732

This PR allows to change the options passed to esbuild build which allows  to customize the server generation like target node version, sourcemap, inject and more.

It contains one braking change: `out` is renamed to `outdir` to follow the esbuild API. It is possible to avoid a breaking change by making `out` an alias for `outdir`. I'm happy to adjust the PR.
@sastan sastan force-pushed the adapter-node-esbuild-options branch from 9ae2301 to 3ee4efe Compare June 22, 2021 05:41
@sastan
Copy link
Contributor Author

sastan commented Jun 22, 2021

It looks like this PR needs to be rebased

Done.

There's a related PR for adapter-vercel here: #1732

I do not know if using config.kit.vite().esbuild is the best way here. In my specific use-case I want to use a different esbuild config (mainly target and format).

Maybe a hybrid approach:

{
	...config?.kit?.vite()?.esbuild,
	...esbuildOptions,
}

But that would make reasoning about the resulting config difficult.

What is your take on this?

@sastan
Copy link
Contributor Author

sastan commented Jun 25, 2021

Is there anything I can do to progress this PR?

@jasonlyu123
Copy link
Member

Since the common js output format is also available in this PR. I'm wondering if we can check if __dirname and require already exist before shim it, so the configuring is easier. I tried building it to cjs before and it's throwing an error in the runtime because import.meta.url is undefined.

But regarding how to check if __dirname exists, I can only think of some hack like this:

var __dirname;
__dirname = __dirname ?? dirname(fileURLToPath(import.meta.url))

(Sorry I spamed the notification. accidently deleted the previous comment)

@sastan
Copy link
Contributor Author

sastan commented Jun 26, 2021

Since the common js output format is also available in this PR. I'm wondering if we can check if __dirname and require already exist before shim it, so the configuring is easier. I tried building it to cjs before and it's throwing an error in the runtime because import.meta.url is undefined.

But regarding how to check if __dirname exists, I can only think of some hack like this:

var __dirname;
__dirname = __dirname ?? dirname(fileURLToPath(import.meta.url))

(Sorry I spamed the notification. accidently deleted the previous comment)

I use define + inject:

shim-node-cjs.js

import { pathToFileURL } from 'url'

export const shim_import_meta_url = /*#__PURE__*/ pathToFileURL(__filename)

And the in the esbuild config:

    // Or something like path.relative(import.meta.url, './shim-node-cjs.js')
    inject: [require.resolve('./shim-node-cjs.js')],
    define: {
      'import.meta.url': 'shim_import_meta_url',
    },

This works quite well for single file outputs.

@jasonlyu123
Copy link
Member

I'm also fine with an example in the doc. I just thought making it work out of the box would be a little bit easier for the user.

@benmccann
Copy link
Member

Why are you wanting to change target and format?

@sastan
Copy link
Contributor Author

sastan commented Jun 28, 2021

Why are you wanting to change target and format?

We are bundling the server and the assets using pkg into an executable. pkg needs cjs as format and we can use a higher target (v16).

@jasonlyu123
Copy link
Member

And we're hosting with Windows IIS with iisnode, which doesn't seem to support ESM.

People using other hosting platforms that don't already have an official adapter may want to leverage the node adapter. And since some other adapters also ship common js. I think it would a good idea to allow configuring node adapter to output common js.

@benmccann
Copy link
Member

@sastan it looks like this PR will need to be rebased

@benmccann
Copy link
Member

I do not know if using config.kit.vite().esbuild is the best way here

I agree. It's better to keep them separately configurable

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

Successfully merging this pull request may close these issues.

5 participants