7

I'm trying to refactor a library that uses Browserify by shimming certain modules out of the bundle using browserify-shim. Specifically, the library uses require("codemirror") but I want to provide a bundle that doesn't include CodeMirror but will rather use one that is provided via CDN.

So I've got browserify-shim config in my package.json like

  "browserify-shim": {
    "jquery": "global:jQuery",
    "codemirror": "global:CodeMirror"
  }

So far so good. require('jquery') and require('codemirror') have disappeared from the browserified bundle and been replaced by the expected code snippet to grab jQuery and CodeMirror off of the window object.

The library also requires some CodeMirror add-ons. For example require('codemirror/addon/hint/show-hint.js'). That's fine. I want that add-on bundled. However, within this add-on is a UMD wrapper that includes require("../../lib/codemirror"). Browserify is seeing this and is bundling the CodeMirror from /node_modules/codemirror/lib/codemirror.js because of this (I think). I want this to use window.CodeMirror as defined in the codemirror shim instead, but cannot figure it out. Have tried many variations including the following:

  "browserify-shim": {
    "jquery": "global:jQuery",
    "codemirror": "global:CodeMirror",
    "../../lib/codemirror": "global:CodeMirror",
    "codemirror/addon/hint/show-hint.js": { 
      "exports":null,
      "depends":["../../lib/codemirror:CodeMirror"]
    }
  }

That require("../../lib/codemirror") will not go away! I'm sure I'm missing something.

I'm running this from a Gulp script, but I don't think that should make any difference. Browserify version 3.38.1. Browserify-shim version 3.7.0.

Any ideas?

Ethan Jewett
  • 6,002
  • 16
  • 25
  • Looks like browserify-shim may have been the wrong way to go with this. Browserify option bundleExternal=false may solve the problem. Investigating... – Ethan Jewett Oct 09 '14 at 12:06
  • bundleExternal=false is not the full answer as it leaves the initial 'require' statements in place. So browserify-shim as in the first example is still needed. But it helps. With this setting, I can directly .require('codemirror/addon/hint/show-hint.js') before bundling in the Gulp script to get the add-on, but the external requirement of CodeMirror will be left off, it seems. – Ethan Jewett Oct 13 '14 at 14:57
  • Looks like in the latest version of browserify there is the option to apply { global: true } to the browserify-shim transformation, which will cause it to run on dependencies! This allows us to shim the require('../../lib/codemirror') successfully. – Ethan Jewett Oct 15 '14 at 18:34
  • did you ever find a definitive answer to this quesion. I'm having a very similar problem and posted it here questions/26696577/browserify-shim-grunt-dependency-mapping and am wondering if you have any feedback. – dtothefp Nov 02 '14 at 06:15
  • Yes, { global: true } gives the flexibility I needed for my use-case, at least. – Ethan Jewett Nov 03 '14 at 13:40

2 Answers2

12

If you add browserify-shim with {global: true}, it should be applied to your dependencies' dependencies (and so on) as well, which should hopefully do what you want.

Assuming you're using raw browserify in your Gulpfile, instead of:

b.transform('browserify-shim');

do:

b.transform({global: true}, 'browserify-shim');

If you're using gulp-browserify, I'm not sure whether there's any way to specify global transforms.

Alan Plum
  • 10,814
  • 4
  • 40
  • 57
-1
{global: true}

works for me... why is this not a default?

  • 2
    While this code may answer the question, providing additional context regarding _why_ and/or _how_ this code answers the question would significantly improve its long-term value. Please [edit] your answer to add some explanation. – Toby Speight Mar 17 '16 at 18:28