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

Bundle ink without devtools #571

Open
fantua opened this issue Mar 27, 2023 · 7 comments
Open

Bundle ink without devtools #571

fantua opened this issue Mar 27, 2023 · 7 comments

Comments

@fantua
Copy link

fantua commented Mar 27, 2023

I would like to bundle ink with esbuild using the following config:

bundle: true,
define: {
  'process.env.DEV': 'false'
},
platform: 'node',
format: 'esm'

'process.env.DEV': 'false' should do dead code elimination for this part:

ink/src/reconciler.ts

Lines 26 to 44 in fb66872

if (process.env['DEV'] === 'true') {
try {
await import('./devtools.js');
// eslint-disable-next-line @typescript-eslint/no-implicit-any-catch
} catch (error: any) {
if (error.code === 'MODULE_NOT_FOUND') {
console.warn(
`
Debugging with React Devtools requires \`react-devtools-core\` dependency to be installed.
$ npm install --save-dev react-devtools-core
`.trim() + '\n'
);
} else {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw error;
}
}
}

But devtools import still presents because we’re not using global process reference. Once I remove this line everything works as expected:

import process from 'node:process';

see evanw/esbuild#3015 for more details

@vadimdemedes
Copy link
Owner

What is the benefit of excluding devtools.js from the resulting bundle?

@sindresorhus
Copy link
Collaborator

But devtools import still presents because we’re not using global process reference. Once I remove this line everything works as expected:

This sounds like something esbuild should fix. If they support handling the global process, they should handle the imported one. Open an issue on esbuild instead.

@fantua
Copy link
Author

fantua commented Mar 27, 2023

First of all devtools is useful for dev mode only, I don't need it in production bundle.

Benefit of excluding devtools.js from the resulting bundle:

  • decrease bundle size
  • remove extra chunk (esbuild will create new chunk for devtools because of dynamic import)
  • fix for the following error (I don't install react-devtools-core as a dependency):
✘ [ERROR] Could not resolve "react-devtools-core"

    ../../node_modules/ink/build/devtools.js:5:21:
      5 │ import devtools from 'react-devtools-core';
        ╵                      ~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "react-devtools-core" as external to exclude it from the bundle, which will
  remove this error.

@fantua
Copy link
Author

fantua commented Mar 27, 2023

This sounds like something esbuild should fix. If they support handling the global process, they should handle the imported one. Open an issue on esbuild instead.

Issue description contains a link to esbuild issue alteady. Basically esbuild supports global variables only evanw/esbuild#3015 (comment).

@vadimdemedes
Copy link
Owner

vadimdemedes commented Mar 27, 2023

First of all devtools is useful for dev mode only, I don't need it in production bundle.

react-devtools-core isn't included with Ink and it's an optional peer dependency, so it shouldn't be part of your bundle if you didn't install it yourself.

fix for the following error (I don't install react-devtools-core as a dependency):

esbuild is suggesting a fix there to mark react-devtools-core as an external dependency. Try that.

This sounds like something esbuild should fix. If they support handling the global process, they should handle the imported one. Open an issue on esbuild instead.

Agree with @sindresorhus on this one. If Node.js recommends to import process now, it makes sense for bundlers to handle that scenario.

@eXhumer
Copy link

eXhumer commented Jun 1, 2023

I came across this issue while trying to bundle my scripts with webpack to package into an executable.

I found that replacing

if (process.env['DEV'] === 'true') {

if (process.env['DEV'] === 'true') {

with if (process.env['NODE_ENV'] === 'development') { fixes the issue for me with webpack. webpack correctly checks the node environment and ignores the devtools.js import and related imports in production builds.

@baublet
Copy link

baublet commented Mar 7, 2024

The way the dev tools are initialized (as a top-level await behind an if statement and shipped in with the build you're shipping to users) makes this library difficult to bundle and might be hindering adoption. As is, we need to utilize one of the heftier static analysis tools that can support understanding and removing the dead code if we want to use this in CJS code. Normal ESM/CJS problems, so might not be high on the priority list.

But at a glance, the entire library appears to be sync code except for where we're initializing the dev tools behind an if statement... it almost looks like a mistake that somehow made it into the prod builds.

The fix seems easy, though? Don't ship your dev tools to your users. Have a shim that initializes them before you import the rest of your (CJS) code and run that in development?

For what it's worth, though, thanks for the cool library, and hoping I don't have to switch off it!

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

Successfully merging a pull request may close this issue.

5 participants