evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
38.06k stars 1.14k forks source link

Bundled artifacts work on Chrome but not Firefox #1543

Closed nalzok closed 3 years ago

nalzok commented 3 years ago

I'm trying to use a package named frappe-gantt within an Express project, but the bundled artifacts only work on Chrome but not Firefox. I believe there is an issue with the bundler instead of the package itself because the demo site renders perfectly on both Firefox and Chrome.

For maximum reproducibility, I have set up an MCVE repository (by making minimal edit to a template project generated by express-generator), so that you can simply

git clone https://github.com/nalzok/frappe-gantt-example.git
cd frappe-gantt-example
npm run build && DEBUG=frappe-gantt-example:* npm start

Then navigate to localhost:3000 with the browsers. On Windows 10,

  1. Chrome 92.0.4515.159 renders the Gantt chart perfectly.
  2. Firefox 91.0.1 can render the Gantt chart statically, but the bars don't resize you drag them. (See screenshot below)

I have tried adding options like target: ["firefox57"], but that doesn't help, so I suspect the artifacts are not built correctly.

图片

By the way, since frappe-gantt ships pre-built artifacts with the package, can I ask esbuild to copy the files from node_modules/frappe-gantt/dist to outfile so that it can skip building from node_modules/frappe-gantt/src? I have tried marking the package as external with external: ["frappe-gantt"], only to get the following error in the browser console

Uncaught Error: Dynamic require of "frappe-gantt" is not supported
evanw commented 3 years ago

It looks to me like you're encountering a bug in Firefox and/or in that library. I tried building your code with Parcel instead of esbuild and the code has the exact same problem in Firefox. Here was what I tried:

diff --git a/package.json b/package.json
index 5d6455e..0d2631b 100644
--- a/package.json
+++ b/package.json
@@ -13,9 +13,11 @@
     "frappe-gantt": "^0.5.0",
     "hbs": "^4.1.2",
     "http-errors": "~1.6.3",
-    "morgan": "~1.9.1"
+    "morgan": "~1.9.1",
+    "parcel": "2.0.0-rc.0"
   },
   "devDependencies": {
+    "@parcel/transformer-sass": "2.0.0-rc.0",
     "esbuild": "^0.12.22",
     "esbuild-plugin-sass": "^0.6.0"
   }
diff --git a/views/index.hbs b/views/index.hbs
index 2372392..596b2b5 100644
--- a/views/index.hbs
+++ b/views/index.hbs
@@ -1,4 +1,4 @@
 <h1>{{title}}</h1>
 <p>Welcome to {{title}}</p>
 <svg id="gantt"></svg>
-<script src="/javascripts/bundled.js"></script>
\ No newline at end of file
+<script src="/parcel/main.js"></script>
diff --git a/views/layout.hbs b/views/layout.hbs
index 14cf757..1b66309 100644
--- a/views/layout.hbs
+++ b/views/layout.hbs
@@ -3,7 +3,7 @@
   <head>
     <title>{{title}}</title>
     <link rel='stylesheet' href='/stylesheets/style.css' />
-    <link rel='stylesheet' href='/javascripts/bundled.css' />
+    <link rel='stylesheet' href='/parcel/main.css' />
   </head>
   <body>
     {{{body}}}

Since your code is also broken in Firefox when built with Parcel, it's likely not esbuild's fault.

I believe the reason why the sample works and your build doesn't is that your build has <animate/> elements as children of the <rect/> elements that make up the bars in the chart while the sample doesn't. These stop Firefox from updating the width correctly. I assume this is a bug in Firefox. You can see this for yourself by inspecting the DOM of the sample and of your code. If you make this change to the library you are using then your code starts working fine in Firefox:

diff --git a/node_modules/frappe-gantt/src/svg_utils.js b/node_modules/frappe-gantt/src/svg_utils.js
index 44add70..2da5fcd 100644
--- a/node_modules/frappe-gantt/src/svg_utils.js
+++ b/node_modules/frappe-gantt/src/svg_utils.js
@@ -63,6 +63,7 @@ function getAnimationElement(
         keyTimes: '0; 1',
         keySplines: cubic_bezier('ease-out')
     });
+    if (attr !== 'width')
     svgElement.appendChild(animateElement);

     return svgElement;

TL;DR: This is a bug in Firefox and/or in your library, not in esbuild.

By the way, since frappe-gantt ships pre-built artifacts with the package, can I ask esbuild to copy the files from node_modules/frappe-gantt/dist to outfile so that it can skip building from node_modules/frappe-gantt/src? I have tried marking the package as external with external: ["frappe-gantt"], only to get the following error in the browser console

The files in node_modules/frappe-gantt/dist appear to be for use with <script> tags, not with bundlers. They don't export anything. Your problem is that you need to customize what happens when code imports from the frappe-gantt package. You could potentially inject the code in node_modules/frappe-gantt/dist using a <script> tag and then use an esbuild plugin to replace all imports from the frappe-gantt package to a file that looks something like this:

export default window.Gantt

But keep in mind this likely won't solve your problem because this is a bug in Firefox and/or in that library.

evanw commented 3 years ago

Ah here you go, an open bug about charts being broken in Firefox on the library you're using: https://github.com/frappe/gantt/issues/177. I'm going to close this issue since it's not related to esbuild.