Closed JakobJingleheimer closed 1 year ago
What about enabling sourcemap?
In production you can set --sourcemap=external , Then add sourcemap manually to Chrome when you want to inspect it with React Dev tools
I'm not sure about the "auto add property" behavior. Did you see some other tools (babel plugin or webpack plugin) doing the same thing?
What about enabling sourcemap?
In production you can set --sourcemap=external ,
Then add sourcemap manually to Chrome when you want to inspect it with React Dev tools
I already have source-maps, and they do not address the issue.
I'm not sure about the "auto add property" behavior. Did you see some other tools (babel plugin or webpack plugin) doing the same thing?
Yes, the reffed issue cites the babel plugin that did it 🙂
Yes, the reffed issue cites the babel plugin that did it.
Thanks, I missed that. With that babel plugin you can easily write an esbuild plugin based on that:
First of all, download that plugin and prepare the project
$ mkdir test && cd test
$ pnpm init && pnpm add -D @babel/core @babel/helper-plugin-utils @babel/preset-react esbuild
$ curl https://raw.githubusercontent.com/zendesk/babel-plugin-react-displayname/master/src/index.js -o react-displayname.cjs
$ touch build.js
Here's the build.js content:
import fs from "fs";
import reactDisplayName from "./react-displayname.cjs";
import { transformSync } from "@babel/core";
import { build } from "esbuild";
await build({
entryPoints: ["./main.jsx"],
bundle: true,
plugins: [
{
name: "react-displayname",
setup({ onLoad }) {
onLoad({ filter: /\.jsx$/ }, (args) => {
var code = fs.readFileSync(args.path, "utf8");
// https://github.com/zendesk/babel-plugin-react-displayname/blob/master/src/index.test.js
code = transformSync(code, {
babelrc: false,
configFile: false,
plugins: [reactDisplayName],
presets: [["@babel/preset-react", { pure: false }]],
}).code;
return { contents: code, loader: "default" };
});
},
},
],
}).catch(() => process.exit(1));
Thanks for your answer @hyrious. I'm closing this because this has been answered.
Thanks @hyrious! Won't that basically inject babel core + that plugin into the build process? I'm not otherwise using babel, so ideally it wouldn't literally use babel for this.
@JakobJingleheimer Yes, it uses babel. This is because the babel plugin you referenced to implements the function by analyzing the AST node of JSX files and guess if a normal function is a component. esbuild does not allow you to access AST so you cannot do something based on that, so to achieve the same effect you have to invoke babel core to run that plugin.
As you may already looked into the esbuild plugin's API, the onLoad
callback asks you to provide the code contents
using the resolved path
. You can do anything during this step to achieve your goals. For example, if you decide to enforce some kind of code style like that all components should use titlecase on a function name, you can write a simple string-search based plugin too.
onLoad({ filter: /\.jsx$/ }, (args) => {
var code = fs.readFileSync(args.path, "utf8"), names = new Set();
// let's say that 'function Titlecase(' must be a component
code.replace(/^function ([A-Z][^\s\(]+)/g, (_, name) => {
names.add(name);
});
// append '{name}.displayName = "{name}"' to the end
for (var name of names)
code += "\n" + name + ".displayName = " + JSON.stringify(name);
return { contents: code, loader: "default" };
})
I would like to make a plugin to append some content to a module, specifically:
Input:
Additional/new output:
The problem I'm trying to solve is making the outputted code compatible with React devtools' Components inspector, which is broken when
format=esm
+minify
are set.ESBuild → Try
Refs: https://github.com/evanw/esbuild/issues/2475
This is a very common feature in past build systems but is understandably outside the scope of ESBuild core. I'm hoping for some guidance on writing this plugin (which I would happily contribute back to the plugin registry).
ESBuild's built-in JSX loader is already doing the vast majority (probably ~99%) of the setup work I would need, so I'm hoping to somehow tie into that, but I don't see any way to do it. I think
onLoad
callback is the appropriate one to use.