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

Support require fallback for strange environments #624

Open
bmeck opened this issue Feb 3, 2014 · 10 comments
Open

Support require fallback for strange environments #624

bmeck opened this issue Feb 3, 2014 · 10 comments

Comments

@bmeck
Copy link

bmeck commented Feb 3, 2014

See: https://twitter.com/rwaldron/status/430414189413138433

Basically: there is a need to allow non-browserifieds modules to defer to another require function. In this example @rwaldron wanted to use node-serialport from node-webkit's require inside of a browserify bundle.

Solution: --require-fallback $name

Make a CLI option to fallback to an environment's require function if we did not bundle that file.

@andreypopp
Copy link
Contributor

If I understand you correctly, currently you can add a piece of code like this to implement needed functionality:

window.require = function() { return $name.apply(null, arguments); }

because browserify already defers lookup to another function named require if it presents at the time of the bundle execution.

@bmeck
Copy link
Author

bmeck commented Feb 3, 2014

This is going to be a bit more complex actually:

~ cat b.js
require('X');
~ browserify b.js
Error: module "X" not found from "/.../b.js"

When the flag is enabled we need to defer to $name rather than freak out at bundle time.
Preferably doing this hygienically as well.

@ghost
Copy link

ghost commented Feb 3, 2014

This can almost be done with --ignore-missing:

$ echo "require('./x.js')" | browserify --ignore-missing
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
require('./x.js')

},{"./x.js":2}],2:[function(require,module,exports){

},{}]},{},[1])

The problem is that ignore-missing doesn't seem to defer to an existing require call in the environment properly.

@calvinmetcalf
Copy link
Contributor

since all the modules are getting wrapped in function(require,module,exports){} wrappers the call will always get bound to that name, you'd need to have browserify pass the re-call the function at require time, i.e the final step before throwing an error tries window.require

@bmeck
Copy link
Author

bmeck commented Feb 4, 2014

@calvinmetcalf , just to be clear, we don't always want a global require to be what we defer to some places (mongodb, etc.) do not leave require as a global.

@yuchi
Copy link

yuchi commented Feb 12, 2014

Shouldn’t this be doable with --excludes? Always if @andreypopp comment is incorrect of course.

@bmeck
Copy link
Author

bmeck commented Feb 12, 2014

@yuchi unsure what you mean? This all came from @rwaldron being unable to require node-serialport inside of node-webkit.

@yuchi
Copy link

yuchi commented Feb 12, 2014

Sorry, probably I got this wrong. But the std prelude searches for an already present require function in the outer scope to defer calls to. If you can exclude the incriminated require call you can then use a custom prelude which searches for the correct outer require. An excluded path/module is simply ignored in AOT resolution.

Here for example I had to change the call to the outer require because Titanium’s implementation throws when you call it with more than one argument.

@terinjokes
Copy link
Contributor

As noted, the standard prelude already calls to a global require if a module can't be found. You should be able to implement a global require before including the browserify bundle that delegates to any (sync) source that you want, and have browserify exclude bundling the modules you don't want to bundle.

Does this resolve the issue for everyone?

@moll
Copy link

moll commented Jul 31, 2015

I don't believe there's a way to ignore a whole module with its files currently if you don't have a local copy of it. Something like --external some-module/* tries to glob at compile time and then still fails given a require("some-module/some-file").

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

No branches or pull requests

7 participants