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

chore: update esbuild #6884

Merged
merged 10 commits into from
Dec 2, 2024
Merged

chore: update esbuild #6884

merged 10 commits into from
Dec 2, 2024

Conversation

threepointone
Copy link
Contributor

@threepointone threepointone commented Oct 3, 2024

  • A version of this changeset could probably live in the docs

What this PR solves / how to test

Fixes #5222

This patch updates esbuild from 0.17.19 to 0.24.0. That's a big bump! Lots has gone into esbuild since May '23. All the details are available at https://github.com/evanw/esbuild/blob/main/CHANGELOG.md / https://github.com/evanw/esbuild/blob/main/CHANGELOG-2023.md.

  • We now support all modern JavasScript/TypeScript features suported by esbuild (as of September 2024). New additions include standard decorators, auto-accessors, and the using syntax.

  • 0.18 introduced wider support for configuration specified via tsconfig.json Proposed tsconfig.json changes evanw/esbuild#3019. After observing the (lack of) any actual broken code over the last year for this release, we feel comfortable releasing this without considering it a breaking change.

  • 0.19.3 introduced support for import attributes

    import stuff from './stuff.json' with { type: 'json' }

    While we don't currently expose the esbuild configuration for developers to add their own plugins to customise how modules with import attributes are bundled, we may introduce new "types" ourselves in the future.

  • 0.19.0 introduced support for wildcard imports. Specifics here (https://github.com/evanw/esbuild/blob/main/CHANGELOG-2023.md#0190). tl;dr -

    • These 2 patterns will bundle all files that match the glob pattern into a single file.

      const json1 = await import("./data/" + kind + ".json");
      const json2 = await import(`./data/${kind}.json`);
    • This pattern will NOT bundle any matching patterns:

      const path = "./data/" + kind + ".js";
      const json2 = await import(path);

      You can use find_additional_modules to bundle any additional modules that are not referenced in the code but are required by the project.

    Now, this MAY be a breaking change for some. Specifically, if you were previously using the pattern (that will now include all files matching the glob pattern in the bundle), BUT find_additional_modules was NOT configured to include some files, those files would now be included in the bundle. For example, consider this code:

    // src/index.js
    export default {
    	async fetch() {
    		const url = new URL(request.url);
    		const name = url.pathname;
    		const value = (await import("." + name)).default;
    		return new Response(value);
    	},
    };

    Imagine if in that folder, you had these 3 files:

    // src/one.js
    export default "one";
    // src/two.js
    export default "two";
    // src/hidden/secret.js
    export default "do not share this secret";

    And your wrangler.toml was:

    name = "my-worker"
    main = "src/index.js

    Before this update:

    1. A request to anything but http://localhost:8787/ would error. For example, a request to http://localhost:8787/one.js would error with No such module "one.js".

    2. Let's configure wrangler.toml to include all .js files in the src folder:

    name = "my-worker"
    main = "src/index.js"
    
    find_additional_modules = true
    rules = [
      { type = "ESModule", globs = ["*.js"]}
    ]

    Now, a request to http://localhost:8787/one.js would return the contents of src/one.js, but a request to http://localhost:8787/hidden/secret.js would error with No such module "hidden/secret.js". To include this file, you could expand the rules array to be:

    rules = [
      { type = "ESModule", globs = ["**/*.js"]}
    ]

    Then, a request to http://localhost:8787/hidden/secret.js will return the contents of src/hidden/secret.js.

    After this update:

    • Let's put the wrangler.toml back to its original configuration:
    name = "my-worker"
    main = "src/index.js
    • Now, a request to http://localhost:8787/one.js will return the contents of src/one.js, but a request to http://localhost:8787/hidden/secret.js will ALSO return the contents of src/hidden/secret.js. THIS MAY NOT BE WHAT YOU WANT. You can "fix" this in 2 ways:

      1. Remove the inline wildcard import:
      // src/index.js
      export default {
      	async fetch() {
      		const name = new URL(request.url).pathname;
      		const moduleName = "./" + name;
      		const value = (await import(moduleName)).default;
      		return new Response(value);
      	},
      };

      Now, no extra modules are included in the bundle, and a request to http://localhost:8787/hidden/secret.js will throw an error. You can use the find_additional_modules feature to include it again.

      1. Don't use the wildcard import pattern:
      // src/index.js
      import one from "./one.js";
      import two from "./two.js";
      
      export default {
      	async fetch() {
      		const name = new URL(request.url).pathname;
      		switch (name) {
      			case "/one.js":
      				return new Response(one);
      			case "/two.js":
      				return new Response(two);
      			default:
      				return new Response("Not found", { status: 404 });
      		}
      	},
      };

      Further, there may be some files that aren't modules (js/ts/wasm/text/binary/etc) that are in the folder being included (For example, a photo.jpg file). This pattern will now attempt to include them in the bundle, and throw an error. It will look like this:

      [ERROR] No loader is configured for ".png" files: src/photo.jpg

      To fix this, simply move the offending file to a different folder.

      In general, we DO NOT recommend using the wildcard import pattern. If done wrong, it can leak files into your bundle that you don't want, or make your worker slightly slower to start. If you must use it (either with a wildcard import pattern or with find_additional_modules) you must be diligent to check that your worker is working as expected and that you are not leaking files into your bundle that you don't want. You can configure eslint to disallow dynamic imports like this:

      // .eslintrc.js
      {
      	"rules": {
      		"no-restricted-syntax": [
      			"error",
      			{
      				"selector": "ImportExpression[argument.type!='Literal']",
      				"message": "Dynamic imports with non-literal arguments are not allowed.",
      			},
      		],
      	},
      }

Author has addressed the following

  • Tests
    • TODO (before merge)
    • Tests included
    • Tests not necessary because: no functional change
  • E2E Tests CI Job required? (Use "e2e" label or ask maintainer to run separately)
    • I don't know
    • Required
    • Not required because:
  • Changeset (Changeset guidelines)
    • TODO (before merge)
    • Changeset included
    • Changeset not necessary because:
  • Public documentation
    • TODO (before merge)
    • Cloudflare docs PR(s):
    • Documentation not necessary because: no functional changes

@threepointone threepointone added the e2e Run wrangler e2e tests on a PR label Oct 3, 2024
Copy link

changeset-bot bot commented Oct 3, 2024

🦋 Changeset detected

Latest commit: 3994b48

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

This PR includes changesets to release 2 packages
Name Type
@cloudflare/vitest-pool-workers Minor
wrangler Major

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

Copy link
Contributor

github-actions bot commented Oct 3, 2024

A wrangler prerelease is available for testing. You can install this latest build in your project with:

npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-wrangler-6884

You can reference the automatically updated head of this PR with:

npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/prs/6884/npm-package-wrangler-6884

Or you can use npx with this latest build directly:

npx https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-wrangler-6884 dev path/to/script.js
Additional artifacts:
npx https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-create-cloudflare-6884 --no-auto-update
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-kv-asset-handler-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-miniflare-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-pages-shared-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-vitest-pool-workers-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-workers-editor-shared-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-workers-shared-6884
npm install https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/runs/12118790774/npm-package-cloudflare-workflows-shared-6884

Note that these links will no longer work once the GitHub Actions artifact expires.


wrangler@3.90.0 includes the following runtime dependencies:

Package Constraint Resolved
miniflare workspace:* 3.20241106.1
workerd 1.20241106.1 1.20241106.1
workerd --version 1.20241106.1 2024-11-06

Please ensure constraints are pinned, and miniflare/workerd minor versions match.

@threepointone threepointone mentioned this pull request Oct 3, 2024
12 tasks
@threepointone threepointone marked this pull request as ready for review October 3, 2024 23:29
@threepointone threepointone requested review from a team as code owners October 3, 2024 23:29
Copy link
Contributor

@Cherry Cherry left a comment

Choose a reason for hiding this comment

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

I absolutely LOVE this! Being stuck with an older esbuild version has bugged me in many projects.

However, the breaking changes caveats seem like a lot of possible concern, not to mention the platforms supported dropped in newer esbuild versions that wrangler still technically supports today with its node.js 16 minimum version req.

Is this the time to just rip off the band-aid and do more frequent majors, making this part of a v4? 👀

There's a quote from one of the recent esbuild releases that I love, and I hope wrangler can follow too one day:

This release doesn't contain any deliberately-breaking changes. However, it contains a very complex new feature and while all of esbuild's tests pass, I would not be surprised if an important edge case turns out to be broken. So I'm releasing this as a breaking change release to avoid causing any trouble.

@threepointone
Copy link
Contributor Author

I'm not convinced this should be a major release, but we haven't taken a call on it yet.
I'm now working to see if we can list the extra modules being included in the terminal, much like find_additional_modules would, when this feature is used.

@threepointone
Copy link
Contributor Author

@Cherry Could you try this release (with npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/prs/6884/npm-package-wrangler-6884) and see if your own projects are okay?

@Cherry
Copy link
Contributor

Cherry commented Oct 5, 2024

Sadly almost all of my non-trivial projects use custom builds for things like Sentry releases, etc. but on the few personal projects I've tried this on, it all seems to be working fine.

@bawerd
Copy link

bawerd commented Oct 30, 2024

@Cherry Could you try this release (with npm install --save-dev https://prerelease-registry.devprod.cloudflare.dev/workers-sdk/prs/6884/npm-package-wrangler-6884) and see if your own projects are okay?

Hi and thanks for this! I came in here to file an issue but you were already on it. :)

For what it is worth: I tried this on my shopify app project using the latest cloudflare workers for remix deploy method and it now succesfully builds!
Previously I got the Expected ";" but found "with" error when the deploy script executed wrangler pages functions build --outdir build/worker

@threepointone
Copy link
Contributor Author

awesome. I'm continuing work on this. we've figured out a way to make this opt-in, but it'll take a little effort.

@penalosa penalosa changed the base branch from main to next November 25, 2024 16:51
@penalosa penalosa added the breaking change Change that will result in breaking existing behavior label Nov 25, 2024
@penalosa penalosa force-pushed the update-esbuild-2 branch 2 times, most recently from 1a08fd5 to 167d36b Compare November 29, 2024 15:37
@penalosa penalosa merged commit 8547e14 into next Dec 2, 2024
32 checks passed
@penalosa penalosa deleted the update-esbuild-2 branch December 2, 2024 12:26
penalosa added a commit that referenced this pull request Feb 18, 2025
penalosa added a commit that referenced this pull request Feb 18, 2025
penalosa added a commit that referenced this pull request Feb 18, 2025
esbuild 0.24.2 variable naming changes
penalosa added a commit that referenced this pull request Feb 26, 2025
penalosa added a commit that referenced this pull request Feb 26, 2025
esbuild 0.24.2 variable naming changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Change that will result in breaking existing behavior e2e Run wrangler e2e tests on a PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Upgrade esbuild to 0.19.0+
5 participants