capaj / require-globify

transform for browserify, which allows to require files with globbing expressions
MIT License
70 stars 11 forks source link

modules that require globs cannot run on native nodejs (without applying the transform) #11

Closed zenflow closed 9 years ago

zenflow commented 9 years ago

Proposed solution: rename the 'require' function to 'requireglob' and publish a server-side runtime of that name on npm.

I would be willing to help with the implementation of this. Thoughts anyone?

call-a3 commented 9 years ago

I am inclined to say that this goes beyond the scope of this plugin...

However you are right that globbed requires could be a very useful feature in server-side code as well. I'll try out some strategies on how this functionality should/could be implemented. The beauty of this transform is (according to me) that it tries to keep the "require" call as closely to the original interface as possible, so I'd try to mimic this in a node.js-only implementation as well.

EDIT: Actually, a similar module already exists that does this: require-glob

zenflow commented 9 years ago

I agree that it is important to keep the require call as close to the original as possible. This is why I think it should be left alone (that is the closest possible) and glob-requiring functionality should be moved to a function of a different name. There is an inherent value in conforming to the commonjs (or common-j-esque as it is implemented on node) module standard. However, modules depending on this transform currently conform to neither.

This is why for requiring text files, substack (creator of browserify) also created the fs.readFileSync transform, rather than allowing us to require('some.html'). I cannot find the reference for this, but i recall reading his explanation saying that he did not want to change the "require" interface. This makes sense, since browserify was built to work with node modules, not some new kind of module format.

In practical terms, my objective (which would be useful to me and probably many others) is to be able to require files via globbing expressions and have it work on BOTH node and the browser. This project lets me do this for the browser, and "require-glob" lets me do this for node, but currently there is no complete solution for said objective.

If you would consider changing this transform to find & replace "requireglob" calls instead of "require" calls, I would be willing to make the "requireglob" package that provides a server-side runtime implementing the same interface as your current "require". And bingo! Anyone can require globs of files without even caring whether the code will be run on node, the browser, or both.

call-a3 commented 9 years ago

I've thought long and hard about this, and I'm not entirely sure I completely agree with your reasoning. However, I do agree it would be beneficial if there was a "unified" way to do a globbed require that works out of the box on node and is transformable into something that works in a browser. However...

This would really be trying to do two different things in the same package:

The difference with your provided example being that fs.readFile[Sync] is already an established and well-known API, whereas requireGlob would be a browserify fix for an API that doesn't even exist yet. Since we're already "browserifying" something that doesn't exist, I figured we might as well fake the API we would want from require().

zenflow commented 9 years ago

The problem is that (given that we want maximum portability) we want to use the existing require() syntax. We can easily fake a new requireglob() function rather than override the very well-defined and important existing require() function.

I think the complete solution would require those 2 things, but not in the same package. There would be the transform, "require-globify", and then the runtime package, "requireglob", which would be used on node but stripped out by the transform.

call-a3 commented 9 years ago

Fair enough. I'm going to start work on this in a couple of hours.

There is one thing that still (slightly) bothers me though. I really believe globbed requires is something that should be baked into the require functionality. That is why the transform highjacks the official require() call. It adds a bit of authority/legitimacy to the functionality. I do understand your concern for interoperability with the "real" require function, so I'll implement the functionality as a separate function. However, I'd like the name to be require2 instead of requireGlob. I believe it will add the same kind of authority to the functionality (as if globbed requireing was really the next-gen brother of require). I realize the package name require2 is already taken on NPM, but it looks like a dead project so I'll try to negotiate to have the name freed to us.

zenflow commented 9 years ago

Exciting! :D Does that mean this repo/package/module/transform is renamed to require2ify?

The other thing I think require() is missing is the ability to require different file types (other than js and .json) as a String or Buffer. I am working on this now. Maybe I should put this in a separate issue, but its probably something im doing wrong. Im trying to provide my own mode plugin function but its not happenin...

window.html = require('../../../shared/Site/pages/*.js', {
    mode: function(base, files, config){
        console.log('mode plugin', base, files, config);
        return 'require("lodash");';
    }
});

gives me

Unknown mode: function (base, files, config){
        console.log('mode plugin', base, files, config);
        return 'require("lodash");';
    }
events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: Cannot find module '../../../shared/Site/pages/*.js' from 'c:\Users\Matthew\Documents\dev\modules\ractive-isomorphic\sandbox\client\src\scripts'
    at c:\Users\Matthew\Documents\dev\modules\ractive-isomorphic\node_modules\browserify\node_modules\resolve\lib\async.js:55:21
    at load (c:\Users\Matthew\Documents\dev\modules\ractive-isomorphic\node_modules\browserify\node_modules\resolve\lib\async.js:69:43)
    at onex (c:\Users\Matthew\Documents\dev\modules\ractive-isomorphic\node_modules\browserify\node_modules\resolve\lib\async.js:92:31)
    at c:\Users\Matthew\Documents\dev\modules\ractive-isomorphic\node_modules\browserify\node_modules\resolve\lib\async.js:22:47
    at FSReqWrap.oncomplete (fs.js:99:15)

Process finished with exit code 1

Help?

EDIT by @call-a3: Moved this to issue #14

call-a3 commented 9 years ago

I suppose the name of this package could/would be changed to require2ify or something similar, but we'll see about that once require2 (or whatever the name will be if we can't get that name) is published.

indigostar-kr commented 9 years ago

The donated "require2" npm package name.

zenflow commented 9 years ago

Hot diggity!

zenflow commented 9 years ago

I have some more ideas to share ... Do either of you guys/gals think it is worth starting a require2 organisation here on github? The name is currently available and I would definitely like to be a member & contributor.

call-a3 commented 9 years ago

An update on this: I finally got around to get some more work done on this. I started a git repo and am currently in the process of drafting the spec of how require2 could/should work.

You @zenflow or anyone else is very welcome to make suggestions or edits before I continue work on an implementation.

zenflow commented 9 years ago

@call-a3

require2 package on npm is available. Might want to publish your repo even in this early phase, to avoid possibly having to rename the whole package to 'require3' later on.

Did you give any thought to starting a 'require2' organisation here on gh? https://github.com/require2 is available

I'd really love to have some brainstorming sessions with you (and hopefully others) but I feel like any github issue is the wrong place to get into it. (I really wish there was some messaging on github) I've taken the liberty of setting up a require2 slack team which could help us collaborate. It supports offline messaging (among other neat features)

call-a3 commented 9 years ago

You are very right. An organisation was created for this project, along with the migration of the require2 repository.

All further discussion should be continued there or on the slack domain.

Speaking of which, @zenflow could you send me an invite to that at adriaan.callaerts@gmail.com?

zenflow commented 9 years ago

Anyone wanting to join us on slack can invite themselves now.

@call-a3 want to try it and see if it works? Also added the slackin badge and link to README.md

zenflow commented 9 years ago

ping @call-a3 I wrote you a letter on require2.slack.com

call-a3 commented 9 years ago

Read it, will respond in a few hours...