evanw / evanw/esbuild

Incorrect order of imports after bundling

Open
#2,983 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
40.1k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

[Here](https://github.com/vobyjs/voby/tree/master/demo/ssr_esbuild)'s a repro. `npm i && npm run dev` to see the error.

Basically inside `./server/index.tsx` I have the following:

```ts
import 'linkedom-global'; //TODO: Delete this dependency
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import {favicon, serveStatic} from 'noren/middlewares';
import Server from 'noren/node';
import livereload from 'tiny-livereload/express';
import {renderToString} from 'voby';
import {useRouter} from 'voby-simple-router';
import Routes from '../src/app/routes';
import App from '../src/app';
```

Where the order of those imports is significant, because first of all I'm shimming the DOM by loading `linkedom-global`, which other things will subsequently rely upon.

The problem is that after bundling that code (`npm run dev:bundle:server` to just bundle that file), the order imports changes, which is the bug in question, which in this case breaks my app.

```ts
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};

// src/pages/loader.tsx
var loader_exports = {};
__export(loader_exports, {
default: () => loader_default
});
import { Suspense } from "voby";
import { useLoader } from "voby-simple-router";
import { jsx as jsx4, jsxs as jsxs4 } from "voby/jsx-runtime";
var PageLoader, loader_default;
var init_loader = __esm({
"src/pages/loader.tsx"() {
PageLoader = () => {
const resource = useLoader();
const value = () => resource().value;
return /* @__PURE__ */ jsx4(Suspense, { fallback: /* @__PURE__ */ jsx4("h1", { children: "Loading..." }), children: /* @__PURE__ */ jsxs4("h1", { children: [
"Loaded: ",
value
] }) });
};
loader_default = PageLoader;
}
});

// server/index.tsx
import "linkedom-global";
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { favicon, serveStatic } from "noren/middlewares";
import Server from "noren/node";
import livereload from "tiny-livereload/express";
import { renderToString } from "voby";
import { useRouter } from "voby-simple-router";
```

For whatever reason some imports now happen before the `linkedom-global` import.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the demo/ssr_esbuild repro, run npm i && npm run dev, and inspect server/index.tsx alongside the output from npm run dev:bundle:server. The fix is done when bundling preserves linkedom-global before imports that rely on its DOM shim and the repro no longer errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
build-system, compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.