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

Import isn't getting imported with code splitting / chunks enabled #2208

Open
taoeffect opened this issue Apr 24, 2022 · 5 comments
Open

Import isn't getting imported with code splitting / chunks enabled #2208

taoeffect opened this issue Apr 24, 2022 · 5 comments

Comments

@taoeffect
Copy link

taoeffect commented Apr 24, 2022

We have a rather large project using esbuild 0.14.38 and the esbuild-sass-plugin, and when splitting is enabled using the following config, esbuild fails to import files when it should:

  const esbuildOptionBags = {
    // Native options that are shared between our esbuild tasks.
    default: {
      bundle: true,
      chunkNames: '[name]-[hash]-cached',
      define: {
        'process.env.BUILD': "'web'", // Required by Vuelidate.
        'process.env.CI': `'${CI}'`,
        'process.env.GI_VERSION': `'${GI_VERSION}'`,
        'process.env.LIGHTWEIGHT_CLIENT': `'${LIGHTWEIGHT_CLIENT}'`,
        'process.env.NODE_ENV': `'${NODE_ENV}'`,
        'process.env.VUEX_STRICT': VUEX_STRICT
      },
      external: ['crypto', '*.eot', '*.ttf', '*.woff', '*.woff2'],
      format: 'esm',
      incremental: true,
      loader: {
        '.eot': 'file',
        '.ttf': 'file',
        '.woff': 'file',
        '.woff2': 'file'
      },
      minifyIdentifiers: production,
      minifySyntax: production,
      minifyWhitespace: production,
      outdir: distJS,
      sourcemap: development,
      // Warning: split mode has still a few issues. See https://github.com/okTurtles/group-income/pull/1196
      splitting: !grunt.option('no-chunks'),
      watch: false // Not using esbuild's own watch mode since it involves polling.
    },
    // Native options used when building the main entry point.
    main: {
      assetNames: '../css/[name]',
      entryPoints: [`${srcDir}/main.js`]
    },
    // Native options used when building our service worker(s).
    serviceWorkers: {
      entryPoints: ['./frontend/controller/serviceworkers/primary.js']
    }
  }

Specifically, I have a fileB that looks like this:

import '~/shared/fileC.js'

I have a fileA that looks like this:

import '~/shared/fileC.js'
import '~/shared/fileB.js'

When fileA is loaded, fileB is loaded, but inside of it, it thinks that fileC isn't loaded.

The hack we've been forced to use is to import something from that file. In fileB:

import { something } from '~/shared/fileC.js'

console.debug('esbuild import hack:', something)

Then things work.

I'm not sure if this issue is related to #399 or not.

@hyrious
Copy link

hyrious commented Apr 24, 2022

I don't understand. Can you provide some example code to demonstrate what's wrong and what's your expected behavior?

e.g. repl link

@taoeffect taoeffect changed the title Import isn't getting improted with code splitting / chunks enabled Import isn't getting imported with code splitting / chunks enabled Apr 24, 2022
@taoeffect
Copy link
Author

I edited my comment to make it a little clearer what's happening.

Also, now the bug has disappeared. I changed something but I don't know what exactly caused it to disappear.

However, I've also found a commit where I can reproduce the behavior if you'd like to take a look at this esbuild-bug branch in our project.

To test you'll need to clone the project and use that branch, then npm i -g grunt-cli && npm install in the project folder. Then grunt dev and wait for it to say Local: http://localhost:3000. Then visit http://localhost:3000

To enable the hack/fix, in the file ~/frontend/model/contracts/chatroom.js, change line 6 from:

import '~/shared/domains/chelonia/chelonia.js'

To:

import { GIMessage } from '~/shared/domains/chelonia/chelonia.js'

And then uncomment lines 26-27:

// HACK: work around esbuild code splitting / chunking bug: https://github.com/evanw/esbuild/issues/399
// console.debug('esbuild import hack', GIMessage && '')

Then save the file and wait a few seconds, and refresh the page.

@taoeffect
Copy link
Author

taoeffect commented Apr 24, 2022

Technically the line import '~/shared/domains/chelonia/chelonia.js' is also a hack that shouldn't be there because it was imported earlier from a different file. So this is really 2 bugs and 2 hacks. But now (for unknown reasons) we're back down to 1 hack. :P

@hyrious
Copy link

hyrious commented Apr 28, 2022

Although I didn't successfully narrow down your project to a minimal reproduction, it looks really like 399 where common chunks may change their execution order. Your sbp requires the order to work. In which situation turning off code splitting is the right choice.

The correct way to solve this problem involves a big refactoring to the bundler to carefully capture side effects in each files and replay them in the correct order. That's exactly what parcel2's hoisting does (at the end of its hoisting doc, although not very obvious, it requires you to config splitting thresholds in package.json and manually add dummy codes to enlarge the file). Evan has thought of it but still lack of time to do this.

@taoeffect
Copy link
Author

Thanks for looking into this @hyrious! I admit I don't really understand what you're saying, and it's confusing to me why esbuild can't simply build a graph of sorts of the order in which files are included and include them in that order. We definitely need code-splitting because of the size of the project (the site would take too long to load on a slow connection otherwise).

But anyway, just wanted to say thanks again for looking into this, hopefully Evan or someone else can figure this out. esbuild is a great project, we're mostly very happy with it, and we're very grateful for the speed improvement it gives.

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

No branches or pull requests

2 participants