Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Browserify with external dependencies?

I am trying to slowly introduce Browserify into my site, but I don't want to rewrite all the js and I don't want duplicate instances of jquery and other libraries bundled with my Browserify build.

If I build my module listing jquery as an external dependency, how do I then point it at my global jquery instance? Also the goal is to eliminate the mylibs global (example below), so I don't want to use it in my module.

This is what I'm trying to do (psudo-code). This would be in my site's repo - not the module's. The module would be installed with Bower:

var mylibs.jQuery = $.noConflict(); // global used by lots of existing code module.exports = {     jquery: mylibs.jQuery // can be imported by my module as require('jquery') }; 

Something like that is what I'm trying to achieve. Is this possible?

like image 316
cobbdb Avatar asked Apr 17 '14 05:04

cobbdb


People also ask

How do I NPM a Browserify package?

Run the dist/ directory through Browserify to produce a package. bundle. js file and include that as a script tag. This seems to run without error, but the main function I need to instantiate the logic I need isn't present in the browser.

Is Browserify a dev dependency?

We can also include browserify itself as a dependency, however it isn't a dependency for the project to run – any user to our app can find Superman without needing to run Browserify. It is one of our devDependencies – modules required for developers to make updates to this app.


2 Answers

You can achieve that by using browserify-shim. Assuming that you've got a module named mymodule.js that depends on jQuery in the global scope with the following contents:

var $ = require('jQuery');  console.log(typeof $); 
  1. Install browserify-shim:

    npm install browserify-shim --save-dev 
  2. In package.json file, tell browserify to use browserify-shim as a transform:

    {     "browserify": {         "transform": [ "browserify-shim" ]     } } 
  3. In package.json file, tell browserify-shim to map jQuery to the jQuery in the global scope:

    {     "browserify-shim": {         "jQuery": "global:jQuery"     } } 
  4. Run browserify

    browserify mymodule.js > bundle.js 

If you examine bundle.js you will notice that require('jQuery') is replaced with (window.jQuery).

like image 79
katranci Avatar answered Sep 24 '22 20:09

katranci


Browserify-shim is not transitive across node modules: it can be used to correctly shim top-level (in your own package.json) modules, but it cannot shim modules in other npm packages (with their own package.json files).

This is awkward when dealing with a node module that depends on the jQuery module (eg. a plugin that has a peer dependency), but the jQuery library should still be external.

My solution - similar in concept to the pseudo-code - was to create a custom 'preload shim', with the help of browserify itself.

  1. Exclude the jquery module from the generation of bundle.js, but otherwise build the bundle normally.

    Install the appropriate node/npm modules to meet the build requirements. The to-be-excluded "external" modules will not be included in the bundle but are required to fulfill the compilation dependency resolution.

     browserify -x jquery .. > dist/bundle.js 
  2. Create a file called jquery.js and include this content:

     module.exports = window.jQuery; // or whatever 
  3. Generate a shim.js including just the previous file.

     browserify -r jquery.js > dist/shim.js 

    Then edit the file to use jQuery as the module name.

  4. In the browser, load jquery (the external dependency), shim.js, and then bundle.js.

    When the bundle file tries to load the jquery module - which it does not define - it will fallback to the module (previously) defined in the shim file and run the custom code. In this case that's piping through a previously defined global.

    Or: what browserify-shim "global:" tries to do, only actually .. globally.


Using the browserify module directly - instead of grunt, which I am re-growing to loathe - may have resulted in a 'more refined' solution.

like image 38
user2864740 Avatar answered Sep 22 '22 20:09

user2864740