Skip to content

How to trigger a throw on import / require #1729

Closed

Description

@kmalakoff

I'm a big fan of webpack and have stumbled on an interesting pattern for electron where I can shim browser stubs or versions like this so I don't need to modify the node code directly:

// electron

config.externals = {
  'fs': require.resolve('fs')
}

// browser

config.alias = {
  'fs': require.resolve('fs-memory/singleton')
}

Really amazing!

I have a case that I'm trying to solve....I want to throw in the browser like this since the module import is being wrapped by a try / catch already to fallback to a less efficient implementation...

// electron

config.externals = {
  'fsevents': require.resolve('fsevents'),
}

// browser

config.alias = {
  'fsevents': THROW AN ERROR!
}

I originally, naively implemented it like:

// browser

config.alias = {
  'fsevents': require.resolve('stubs/throw')
}

but when I have multiple throwing shims or the module is loaded in multiple places, it only throws the first time as you would expect since the second time the module is in cache.

How can I throw each and every time for multiple modules and multiple import / require call?

config.alias = {
  'fsevents': THROW AN ERROR!,
  'somethingelse': THROW AN ERROR!
}

Activity

  1. kmalakoff commented on Dec 10, 2015

    @kmalakoff
    Author

    @bebraw thank you! I'm not sure if it is a question or a feature request.

  2. sokra commented on Aug 30, 2016

    @sokra
    Member
    externals: {
      fsevents: "(function() { throw new Error("test"); }())"
    }
  3. kmalakoff commented on Sep 6, 2016

    @kmalakoff
    Author

    Thank you for the configuration. I realized that my description wasn't clear...

    I've put together a test repo to show the problem.

    If you compare webpack to node, you'll see they behave differently:

    Node.js

    $ node entry.js
    
    Module1: pre-require
    Module1: post-require (error)
    Module1: post-require (finally)
    Module2: pre-require
    Module2: post-require (error)
    Module2: post-require (finally)
    
    $ webpack
    $ open index.html
    
    (console)
    Module1: pre-require
    Module1: post-require (error)
    Module1: post-require (finally)
    Module2: pre-require
    Module2: async undefined
    Module2: post-require (finally)
    

    Basically, node throws each time the module is required, but webpack only throws the first time.

    The use case I had was where multiple libraries used require('fsevents') to feature detect whether fsevents was available inside a try / catch block. The first library caught the exception which changed the program flow, but the second library received an empty object from webpack so their try / catch logic for fallback wasn't triggered.

    This might be an edge-case where webpack doesn't need to be identical to node. I just ran into the discrepancy so filed the "bug" / "feature".

    Thank you for webpack!

  4. sokra commented on Sep 6, 2016

    @sokra
    Member

    webpack should behave identical to node.js here.

  5. sokra commented on Sep 6, 2016

    @sokra
    Member

    This requires a try-catch block in the webpack runtime. This would have big performance implications...

    As nobody noticed it for year, we could be incompatible to node.js here, for performance reasons.

  6. kmalakoff commented on Sep 7, 2016

    @kmalakoff
    Author

    The performance, feature parity, and "hasn't been a problem for anyone so far" arguments all make sense.

    I've found a work around by forking one of the libraries so not a problem for me anymore so I'll leave it in your hands to discuss and decide. Thank you!

  7. sokra commented on Sep 7, 2016

    @sokra
    Member

    Ok we discuss it and will add a opt-in option to enable correct behavior for exceptions while module loading.

  8. kmalakoff commented on Sep 7, 2016

    @kmalakoff
    Author

    Sounds like a good balance. Thank you!

  9. added this to the 2.1-RC Blocking milestone on Sep 9, 2016
  10. added a commit that references this issue on Nov 16, 2016
    b87bfc0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions