dev-flag.ts 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { readFile } from "fs/promises";
  2. import jscodeshift from "jscodeshift";
  3. import { Options } from "tsup";
  4. type Loader = NonNullable<
  5. NonNullable<
  6. Awaited<
  7. NonNullable<
  8. ReturnType<Parameters<Parameters<Plugin["setup"]>[0]["onLoad"]>[1]>
  9. >
  10. >
  11. >["loader"]
  12. >;
  13. type Plugin = NonNullable<Options["esbuildPlugins"]>[number];
  14. function replaceDev(source: string): string {
  15. if (/__DEV__/.test(source) !== true) {
  16. return source;
  17. }
  18. const j = jscodeshift.withParser("tsx");
  19. const root = j(source);
  20. root
  21. .find(j.Identifier, { name: "__DEV__" })
  22. .replaceWith(() =>
  23. j.binaryExpression(
  24. "!==",
  25. j.memberExpression(
  26. j.memberExpression(j.identifier("process"), j.identifier("env")),
  27. j.identifier("NODE_ENV"),
  28. ),
  29. j.stringLiteral("production"),
  30. ),
  31. );
  32. return root.toSource();
  33. }
  34. export const DevFlagPlugin: Plugin = {
  35. name: "dev-flag-plugin",
  36. setup(build) {
  37. build.onLoad(
  38. { filter: /\.(t|j)sx?$/, namespace: "file" },
  39. async ({ path }) => {
  40. const contents = await readFile(path, "utf-8");
  41. const ext = path.slice(path.lastIndexOf(".") + 1);
  42. const loader = (ext.match(/(j|t)sx?$/) ? ext : "js") as Loader;
  43. return {
  44. contents: replaceDev(contents),
  45. loader,
  46. };
  47. },
  48. );
  49. },
  50. };