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

Can’t require module with Browserify #2

Closed
pushred opened this issue Sep 10, 2014 · 8 comments
Closed

Can’t require module with Browserify #2

pushred opened this issue Sep 10, 2014 · 8 comments

Comments

@pushred
Copy link

pushred commented Sep 10, 2014

To test this I’ve been trying to require it into a project using Browserify. Since it’s a UMD module this should work, but currently nothing is happening if I require it as-is. No markup, no errors, no XHR.

Here’s my code:

var Subscribe = require('subscribe-email');

document.addEventListener('DOMContentLoaded', function(){

  new Subscribe({
    element: '#subscribe',
    service: 'universe',
    key: '2366edcf-805b-43bf-b043-9c2f527967d9'
  });

});

I’ve installed the module as a folder at e8b4c40. But when I load my page, nothing’s happening. I confirmed that the DOMContentLoaded event is firing, but I’m not seeing my #subscribe markup populated with anything or any network activity.

Taking a peek at the module I saw that it was pointing to src, which should be fine. But I don’t think this will work under normal conditions because it’s dependent upon hbsfy being present where I’m requiring the module. That’s not a huge ask, I love hbsfy. But this isn’t a standalone UMD module then. So I tried pointing the module’s main to the built version, and I’m getting major resolve errors when I try to compile my project:

[Error: Cannot find module './templates/BEM-with-messaging.hbs' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './handlebars/base' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './handlebars/safe-string' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './handlebars/exception' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './handlebars/utils' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './handlebars/runtime' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './utils' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './exception' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './utils' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './exception' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './base' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './base' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './safe-string' from '/project/node_modules/subscribe-email/build']
[Error: Cannot find module './dist/cjs/handlebars.runtime' from '/project/node_modules/subscribe-email/build']

This is maybe reflective of what happens without hbsfy in the mix. So I suspected that hbsfy might not work properly in a standalone Browserify build. So to learn more about how things are being put together, I created a simple reduction that simply exports an object with a template function generated by hbsfy. To contrast, I also implemented another version that pre-compiles the templates with the Handlebars binary, and requires the runtime. This however turned out to produce a file surprisingly identical to hbsfy’s output, unless I’m missing something. I’ve even added a h1 sanity check on the pre-compiled version to make sure I’m testing the right one.

I’ve pushed up the results of this here: https://github.com/blocks/template

When I run the hbsfy version in the browser (with Beefy) I get:

Error: Cannot find module './template.hbs' from '/template'
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:42:25
    at load (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:60:43)
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:66:22
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:21:47
    at Object.oncomplete (fs.js:107:15)

I would say this means my bundle isn’t being transformed with hbsfy, but it is. I see both my precompiled template and the Handlebars runtime in the bundle output. Running the manually pre-compiled version, I get:

Error: Cannot find module './runtime.js' from '/template'
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:42:25
    at load (/usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:60:43)
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:66:22
    at /usr/local/lib/node_modules/browserify/node_modules/resolve/lib/async.js:21:47
    at Object.oncomplete (fs.js:107:15)

Resolution problems all around. Digging into this a bit, I took a look at the Handlebars precompiler and among it’s options tried the CommonJS output and requiring a runtime on my own. I found an alias provided just for Browserify, which I’m now using. hbsfy previously did this shim of sorts: https://github.com/epeli/node-handlebars-runtime, which I also tried.

Turns out, Handlebars is weird. I don’t fully understand that discussion, but I think it’s related to our problems here. I have had success in running the template function from the bundle’s source if I move my code outside of modules.exports or some combination like that. I just can’t export it and can’t recreate that working combo at the moment either.

Browserify’s bundling is explained in it’s excellent handbook and looking at the output I think this is working properly. But I’ve no idea why we’re getting all these errors.

One approach I’ve thought of but haven’t tried is using browserify-shim to access the Handlebars.templates global that they still seem to insist on using (Handlebars 2 is out!). But I feel like I shouldn’t have to do that.

Source export vs. UMD

@josiahsprague One other thing we should look into here is the UMD wrapper in the source index. I was really expecting to find just a simple module.exports in there, with Browserify’s own standalone option used to generate the version in build. I know we discussed that but can’t recall whether there was some issue with that approach. Perhaps it’s partly to blame for the hbsfy approach above not working though?

Another option I found: https://github.com/phated/gulp-wrap-umd

@joanniclaborde
Copy link
Member

See browserify/browserify#374

Browserify used to apply derequire to standalone modules by default, but it slows down the process, so they removed it. I added it back (with gulp-derequire) to the browserify gulp task, and I can now require('subscribe-email') in my script, and browserify it, successfully.

  • gulp/browserify.js
var browserify   = require('browserify');
var bundleLogger = require('./util/bundleLogger');
var gulp         = require('gulp');
var handleErrors = require('./util/handleErrors');
var source       = require('vinyl-source-stream');
var derequire    = require('gulp-derequire');

gulp.task('browserify', function() {
  var bundler = browserify({
    entries: ['./src/subscribe-email.js'],
    extensions: ['.hbs'],
    standalone: 'SubscribeEmail'
  });

  var bundle = function() {
    bundleLogger.start();

    return bundler
      .bundle()
      .on('error', handleErrors)
      .pipe(source('subscribe-email.js'))
      .pipe(derequire())
      .pipe(gulp.dest('./build/'))
      .on('end', bundleLogger.end);
  };

  return bundle();
});

@localjo
Copy link
Contributor

localjo commented Sep 12, 2014

I added derequire in #1 and moved handlebars and hbsfy to dependencies instead of devDependencies and I can now require the module via Browserify or <script> tags with no issues. @pushred can you confirm that it works for you?

@pushred
Copy link
Author

pushred commented Sep 12, 2014

Confirmed! 👏

@joanniclaborde
Copy link
Member

I'm curious: why do you need to include handlebars and hbsfy to dependencies?

@localjo
Copy link
Contributor

localjo commented Sep 15, 2014

Handlebars and hbsfy are still dependencies when this module is a dependency itself (not just in development). If they're in devDependencies, Browserify complains that they're missing when this module is required.

@joanniclaborde
Copy link
Member

I tried the latest commit 1b060b8 with beefy installed locally, and browserify installed both locally and globally, and I can require this module as expected. This was done in the vagrant-solidus vm.

@joanniclaborde
Copy link
Member

I also tried it with a Solidus site, works as expected.

@pushred
Copy link
Author

pushred commented Sep 16, 2014

Fixed as of 23d151e

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

3 participants