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

🚀 Feature Request: Option to output esbuild metafile #4633

Open
janpio opened this issue Dec 19, 2023 · 6 comments
Open

🚀 Feature Request: Option to output esbuild metafile #4633

janpio opened this issue Dec 19, 2023 · 6 comments
Assignees
Labels
enhancement New feature or request quick win Potentially easy/straightforward issue to tackle

Comments

@janpio
Copy link

janpio commented Dec 19, 2023

Describe the solution

Esbuild's metafile is a great way to get additional information about a build, and for example use it in Esbuild Size Analyzer to understand the bundle size. If the CLI could "export" the Esbuild metafile it creates under the hood, that would be optimal.

As this is currently not implements, I quickly hacked together this almost-close-enough esbuild script that uses similar plugins. It brings most of my workers pretty close in size and code - so I am ok using this for now:

import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
import { build } from 'esbuild'
import fs from 'fs'
import { relative, resolve } from "node:path";
import path from "path"


// ChatGPT
function isNodeCompat() {
  const filePath = 'wrangler.toml'; // Hardcoded file path as 'wrangler.toml'

  try {
    // Read the content of the file
    const data = fs.readFileSync(filePath, 'utf8');

    // Parse the content to extract variables
    const lines = data.split('\n');
    const variables = {};
    lines.forEach((line) => {
      const match = line.match(/^\s*([\w_]+)\s*=\s*(.+)/);
      if (match) {
        const key = match[1];
        const value = match[2].trim();
        variables[key] = value;
      }
    });

    // Check for the presence and value of node_compat
    return variables.node_compat && variables.node_compat.toLowerCase() === 'true';
  } catch (err) {
    console.error('Error reading the file:', err);
    return false;
  }
}

let plugins = [
  {
    name: "Copy wasm next to bundle",
    setup(build) {
      build.onResolve({ filter: /.*\.(wasm)$/ }, async (args) => {
        const to = resolve(path.join("dist-esbuild", args.path))
        fs.mkdirSync(path.dirname(to), { recursive: true })
        fs.copyFileSync(resolve(args.resolveDir, args.path), to)
        return {
          path: args.path,
          external: true
        };
      });
    },
  },
  // via https://github.com/cloudflare/workers-sdk/blob/3b5407a968189e60974233c5db8615162db37fd2/packages/wrangler/src/deployment-bundle/esbuild-plugins/cloudflare-internal.ts
  {
    name: "Cloudflare internal imports plugin",
    setup(pluginBuild) {
      pluginBuild.onResolve({ filter: /^cloudflare:.*/ }, () => {
        return { external: true };
      });
    },
  }
]
if (isNodeCompat() === true) {
  console.log("found node_compat=true, adding plugins")
  // via https://github.com/cloudflare/workers-sdk/blob/1b34878287e3c98e8743e0a9c30b860107d4fcbe/packages/wrangler/src/deployment-bundle/bundle.ts#L327-L329
  plugins.push(
    NodeGlobalsPolyfillPlugin({ buffer: true }), 
    NodeModulesPolyfillPlugin()
  )
}

let result = await build({
  plugins: plugins,
  entryPoints: ['function.js'],
  bundle: true,
  outfile: 'dist-esbuild/function.js',
  metafile: true,
  format: 'esm',
  sourcemap: 'external',
  platform: 'node',
  // via https://github.com/cloudflare/workers-sdk/blob/3b5407a968189e60974233c5db8615162db37fd2/packages/wrangler/src/deployment-bundle/bundle.ts#L27-L31
  target: "es2022",
	loader: { ".js": "jsx", ".mjs": "jsx", ".cjs": "jsx" },
  // mainFields: ['workerd', 'worker', 'Here is our `esbuild.mjs`: 
browser', 'module', 'main'],
  conditions: ["workerd", "worker", "browser"]
})

fs.writeFileSync('dist-esbuild/meta.json', JSON.stringify(result.metafile, null, 2))
@janpio janpio added the enhancement New feature or request label Dec 19, 2023
@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Dec 19, 2023
@admah admah added the start-dev-worker Relating to the startDevWorker API label Jan 10, 2024
@admah
Copy link
Contributor

admah commented Jan 10, 2024

@janpio thanks for this suggestion. We have some upcoming work around the build system so I'm adding this feature request to that milestone.

@admah admah added this to the Wrangler as a Library milestone Jan 10, 2024
@lrapoport-cf lrapoport-cf moved this from Untriaged to Backlog in workers-sdk Feb 1, 2024
@lrapoport-cf lrapoport-cf removed this from the Wrangler as a Library milestone Feb 1, 2024
@lrapoport-cf
Copy link
Contributor

hi @janpio :) we've moved this from the milestone but just wanted to let you know that we we are still tracking this suggestion through the start-dev-worker and enhancement labels :)

@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Feb 12, 2024
@lrapoport-cf lrapoport-cf moved this from Untriaged to Backlog in workers-sdk Feb 12, 2024
@DaniFoldi
Copy link
Contributor

Hi @lrapoport-cf 👋,

I'm not quite sure what the removal from the project means, is this still on the roadmap? I'd also love to see this, the metafile would've saved me hours of debugging time yesterday.

I see that it's tagged with start-dev-worker which can complicate matters, for my use case a simple --metafile <filename> would be sufficient which saves the metafile after a full build.

@lrapoport-cf lrapoport-cf removed the start-dev-worker Relating to the startDevWorker API label Sep 24, 2024
@github-project-automation github-project-automation bot moved this to Untriaged in workers-sdk Sep 24, 2024
@lrapoport-cf
Copy link
Contributor

hi @DaniFoldi :) we were doing issue cleanup and assigning feature requests not actively being worked on to be solely in the workers-sdk roadmap project. however, this should be relatively straightforward to address -- @penalosa will follow up 👍 we've moved it back into the workers-sdk project and assigned it accordingly :)

@lrapoport-cf lrapoport-cf moved this from Untriaged to Backlog in workers-sdk Sep 24, 2024
@MonsterDeveloper
Copy link

+1

It'd also be nice to have this option for Pages Functions as well (with wrangler pages functions build)

@Cherry
Copy link
Contributor

Cherry commented Nov 8, 2024

Another vote for this feature.

I often have to reach for a custom build with my own esbuild setup to get this kind of information out. Especially with Cloudflare adding more polyfills when using nodejs_compat and things, being able to extract esbuild's metafile and analyse the size impact of my own code vs boilerplate code for example would be really nice.

@penalosa penalosa added the quick win Potentially easy/straightforward issue to tackle label Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request quick win Potentially easy/straightforward issue to tackle
Projects
Status: Backlog
Development

No branches or pull requests

7 participants