Coder Social home page Coder Social logo

webpack / enhanced-require Goto Github PK

View Code? Open in Web Editor NEW
64.0 6.0 13.0 442 KB

[CURRENTLY UNMAINTAINED] Enhance the require function in node.js with support for loaders which preprocess files. This is a standalone polyfill for features of webpack.

JavaScript 100.00%

enhanced-require's Introduction

enhanced-require

More features for node.js require.

Asynchron require functions are really async. They do not use the sync node.js require, but use a async resolving and async readFile.

Create a enhanced require function

var myRequire = require("enhanced-require")(module, {
	// options
	recursive: true // enable for all modules recursivly
	// This replaces the original require function in loaded modules
});

// startup your application
myRequire("./startup");

Usage

Than you can use them:

// use loaders
var fileContent = require("raw!"+__filename);

// use loaders automatically
var template = require("./my-template.jade");

var html = template({content: fileContent});

// use require.context
var directoryRequire = require.context("raw!./subdir");
var txtFile = directoryRequire("./aFile.txt");

// use require.ensure
require.ensure(["./someFile.js"], function(require) {
	var someFile = require("./someFile.js");
});

// use AMD define
require.define(["./aDep"], function(aDep) {
	aDep.run();
});

// use AMD require
require(["./bDep"], function(bDep) {
	bDep.doSomething();
});

Hot Code Replacement

require("enhanced-require")(module, {
	recursive: true, // enable for all modules
	hot: true, // enable hot code replacement
	watch: true // watch for changes
})("./startup");

For hot code reloading you need to follow the hot code reloading spec.

Testing/Mocking

var er = require("enhanced-require");
it("should read the config option", function(done) {
	var subject = er(module, {
		recursive: true,
		substitutions: {
			// specify the exports of a module directly
			"../lib/config.json": {
				"test-option": { value: 1234 }
			}
		},
		substitutionFactories: {
			// specify lazy generated exports of a module
			"../lib/otherConfig.json": function(require) {
				// export the same object as "config.json"
				return require("../lib/config.json");
			}
		}
	})("../lib/subject");

	var result = subject.getConfigOption("test-option");
	should.exist(result);
	result.should.be.eql({ value: 1234 });
});

Options

{
	recursive: false,
	// replace require function in required modules with enhanced require method

	resolve: {
		// ...
		// see enhanced-resolve
		// https://github.com/webpack/enhanced-resolve
	},
	
	substitutions: {},
	substitutionFactories: {},
	// See above
	// Replace modules with mocks
	// keys are resolved and have to exist

	amd: {},
	// The require.amd object

	enhanced: {},
	// The require.enhanced object

	loader: {},
	// additional stuff in the loaderContext

	hot: false,
	// enable hot code replacement

	watch: false,
	// Watch for file changes and issue hot replacement

	watchDelay: 400,
	// Time to summarize changes for watching
}

Future Plans

  • cli tool

License

Copyright (c) 2012 Tobias Koppers

MIT (http://www.opensource.org/licenses/mit-license.php)

enhanced-require's People

Contributors

sokra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

enhanced-require's Issues

Requiring relative to subtype

Hi sokra,

just a question (not an issue at all) I have been thinking about quite some time:

Following your loadTemplate() example on the webpack page I played around a bit with subclassing Backbone.View in order to achieve some tighter coupling with jade templates.

Currently I'm working with something like this

view
|__ JadeView.js
|__sub1
|  |__SpecificView1.js
|  |__template
|     |__SpecificView1.jade
|__sub2
   |__SpecificView2.js
   |__template
      |__SpecificView2.jade

That is, I have a couple of view sub types organized in sub folders, and each of those sub folders would have its own template directory in order to keep them neatly separated.
Of course I would not want to require the template of each of these specific views repeatedly but only once in JadeView.js, much like

// Somewhere in JadeView.js
require('./template/' + this.name + '.jade');

which would somehow refer to view/sub1/template/SpecificView1.jade when I create a new SpecificView1 and view/sub2/template/SpecificView2.jade when I create a SpecificView2 accordingly, and not view/template/<whatever>.jade. I could not come up with a solution so far since I think it is totally normal that the above require call would always look in the context of the file where it was defined, but is there some (automatic) workaround for that? For now I specify each subview's sub directory path manually when I declare it, so that SpecificView1 basically tells JadeView it is in the sub1 directory. Now that I am planning to move JadeView to a separate package, this would be impracticable though. Can you think of a way this could be solved?

Node fibers throw an error when used with enhanced require

Error: Cannot resolve file or directory C:\app\node_modules\fibers\bin\win32-ia32-v8-3.14\fibers in C:\app\node_modules\fibers

Starts in index.js

GLOBAL.__webpack_public_path__ = '';
var options = require('../../webpack.config');
options.recursive = true;
var myRequire = require('enhanced-require')(module, options);
var boot = myRequire('server/boot');

boot.js:

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

Which is the default fiber example.

In pure node js works fine, with enhanced require I get this error.

They seem to require a binary file:

var fs = require('fs'), path = require('path');

// Seed random numbers [gh-82]
Math.random();

// Look for binary for this platform
var v8 = 'v8-'+ /[0-9]+\.[0-9]+/.exec(process.versions.v8)[0];
var modPath = path.join(__dirname, 'bin', process.platform+ '-'+ process.arch+ '-'+ v8, 'fibers');
try {
    fs.statSync(modPath+ '.node');
} catch (ex) {
    // No binary!
    throw new Error('`'+ modPath+ '.node` is missing. Try reinstalling `node-fibers`?');
}

// Pull in fibers implementation
module.exports = require(modPath).Fiber;

modPath is a string to a binary file.

I've somewhat figured out that if you would use the original require could work and it does. The problem is the way I do it is very ugly:

options.recursive = true;
options.originalRequire = require;
var myRequire = require('enhanced-require')(module, options);

And then I use it like this:

var Fiber = require.options.originalRequire('fibers');

Any better way? Or should I make an alias and wrap it in a single module?

Mocha node testing with enhanced requires

I'm doing unit testing in node with mocha. Everything works smoothly but when I hit the code that uses require.context() I get an exception:

TypeError: Object function require(path) {
    return self.require(path);
} has no method 'context'

I've plugged in the enhanced-require to get around the problem. It works perfectly with my own code, but some modules fail to load with it. For example when I do this:

var webpackConfig = require('./webpack.config');

require = require('enhanced-require')(module, {
    recursive: true,
    resolve:   webpackConfig.resolve
});

var chalk = require('chalk');
var gutil = require('gulp-util');
var moment = require('moment');
var path = require('path');
var watch = require('gulp-watch');
var jsdom = require('jsdom');
var mocha = require('gulp-mocha');

I get this:

/project/build/node_modules/jsdom/package.json:2
  "name": "jsdom",
        ^
SyntaxError: Unexpected token :
    at NormalModuleMixin.Module._compile (/project/deps/node_modules/enhanced-require/lib/Module.js:52:24)
    at RequireContext.theRequire (/project/deps/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /project/build/node_modules/jsdom/lib/jsdom.js:4:11
    at NormalModuleMixin.Module._compile (/project/deps/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/project/deps/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at Object.<anonymous> (/project/build/gulp-test.js:21:13)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

Or if I move require('gulp-mocha') above require('jsdom'), I get this:

TypeError: Cannot call method 'push' of undefined
    at /project/build/node_modules/mocha/lib/mocha.js:27:16
    at NormalModuleMixin.Module._compile (/project/deps/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/project/deps/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /project/build/node_modules/mocha/index.js:4:5
    at NormalModuleMixin.Module._compile (/project/deps/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/project/deps/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /project/build/node_modules/gulp-mocha/index.js:5:13
    at NormalModuleMixin.Module._compile (/project/deps/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/project/deps/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at Object.<anonymous> (/project/build/gulp-test.js:21:13)

It appears that some modules either have little bugs or use not every day functionality of the require, which enhanced require cannot handle. I'm wondering if it's possible to use it as a complete replacement of the standard require() in node?

Issue loading jade templates

Hi guys,

I am currently facing an issue with enhanced-require or the jade loader built in webpack respectively. Quite frankly, I am not sure in which project to file this issue since I have difficulties figuring out which component is to blame, assuming I made no mistake in the first place.

My app is running on node 0.8.11 with webpack 0.7.8, jade 0.27.6 and enhanced-require 0.4.0-beta3. The javascript file I am trying to run in node contains the following statements only:

// project_root/src/main.js
'use strict';
require = require('enhanced-require')(module);

var template = require('./client/view/test.jade');

Unfortunately, when I try to execute it, the following error is thrown:

$ node src/main

Error: Loader throwed exeception: TypeError: Object #<Object> has no method 'apply'
    at nextLoader (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:146:40)
    at execLoaders (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:41:14)
    at Function.module.exports.sync (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:201:2)
    at Object.theRequire (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\require.js:81:17)
    at Object.<anonymous> (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\src\main.js:3:16)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at nextLoader (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:168:15)
    at execLoaders (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:41:14)
    at Function.module.exports.sync (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\execLoaders.js:201:2)
    at Object.theRequire (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\node_modules\enhanced-require\lib\require.js:81:17)
    at Object.<anonymous> (C:\Users\d053411\Documents\Aptana Studio 3 Workspace\yarse\src\main.js:3:16)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)

Can you reproduce the errors? Or might I have missed some important configuration?

Best regards,
Michael

Define loaders in options

Hi,

please can you advice me how to use loaders in options ?

I want to use Mocha testing to test modules with using webpack loaders function like jsx and css.
Without module (or bundle) compilation is mocha tests fall on error sytax on loaded modules which is not pure javascript..(ex css or jsx)
Then i realize that best solution can be use this enhanced-require to load up modules and their required dependencies and compile with existing loaders (jsx loader, css loader,..). Then i hope that Mocha test can pass without problem..

but i dont know how to specify loaders in enhanced-require options.
I am trying to solve similiar config as i have in webpack-config.. something like:

var myRequire = require("enhanced-require")(module, {
// options
recursive: true, 
loader: [
        { test: /\.css$/, loader: "style!css" },
        { test: /\.jsx$/, loader: "jsx-loader?harmony" },
        { test: /\.png/, loader: 'url?limit=100000&minetype=image/png' },
        { test: /\.jpg/, loader: 'file' }
    ]
});
var Hello = myRequire("../../src/components/Hello.jsx");

But this is not possible,, please can you tell me how exactly can i define loaders in enhanced-require options.

Thank you very much..

module.paths API is missing

Triyng to use mocha-loader. Seemed that module.paths is undefined.

root@9b1e81b9d724:/srv# enhanced-require 'mocha-loader\!./a.js'
/srv/node_modules/mocha/lib/mocha.js:28
  module.paths.push(cwd, join(cwd, 'node_modules'));
              ^
TypeError: Cannot read property 'push' of undefined
    at /srv/node_modules/mocha/lib/mocha.js:28:15
    at NormalModuleMixin.Module._compile (/usr/local/lib/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/usr/local/lib/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /srv/node_modules/mocha/index.js:3:5
    at NormalModuleMixin.Module._compile (/usr/local/lib/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/usr/local/lib/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /srv/node_modules/mocha-loader/EnhancedMocha.js:1:82
    at NormalModuleMixin.Module._compile (/usr/local/lib/node_modules/enhanced-require/lib/Module.js:53:18)
    at RequireContext.theRequire (/usr/local/lib/node_modules/enhanced-require/lib/RequireContext.js:169:10)
    at /srv/node_modules/mocha-loader/index.js!/srv/a.js:1:90

The code for "startup your application" makes very little sense.

The following code is given as part of the explanation on how to use the enhanced require:

// startup your application
myRequire("./startup");

Except there is no mention what this magical statement is supposed to do. What is the application in this case? startup.jsx? Does it need to be the same as webpack's entry? More explanation is needed, this code assumes we already know what's going on when we don't.

Updates required to get this up-to-date

  • extract loaders logic into separate module
  • add a plugin system, like webpacks
  • use up-to-date version of enhanced-resolve
  • update the HMR code to webpacks state. (HMR management spec changed a bit)

SyntaxError: Unexpected token ILLEGAL with java node_module

I'm using the webdriver-sync webdriver module which uses the java module. With the default node.js require everything works as expected. With the enhanced require the result is this:

C:\app\node_modules\webdriver-sync\node_modules\java\build\Release\nodejavabridge_bindings.node:1
nction (exports, require, define, module, __filename, __dirname) {MZ�
                                                                    ^
SyntaxError: Unexpected token ILLEGAL
  at NormalModuleMixin.Module._compile (C:\app\node_modules\enhanced-require\lib\Module.js:52:24)
  at RequireContext.theRequire (C:\app\node_modules\enhanced-require\lib\RequireContext.js:169:10)
  at C:\app\node_modules\webdriver-sync\node_modules\java\lib\nodeJavaBridge.js:7:16
  at NormalModuleMixin.Module._compile (C:\app\node_modules\enhanced-require\lib\Module.js:53:18)
  at RequireContext.theRequire (C:\app\node_modules\enhanced-require\lib\RequireContext.js:169:10)
  at C:\app\node_modules\webdriver-sync\node_modules\java\index.js:2:18
  at NormalModuleMixin.Module._compile (C:\app\node_modules\enhanced-require\lib\Module.js:53:18)
  at RequireContext.theRequire (C:\app\node_modules\enhanced-require\lib\RequireContext.js:169:10)
  at C:\app\node_modules\webdriver-sync\src\webdriver-sync.js:3:12
  at NormalModuleMixin.Module._compile (C:\app\node_modules\enhanced-require\lib\Module.js:53:18)
  at RequireContext.theRequire (C:\app\node_modules\enhanced-require\lib\RequireContext.js:169:10)
  at Object.<anonymous> (C:\app\tests\integration\support\World.js:15:10)
  at Module._compile (module.js:456:26)
  at Object.Module._extensions..js (module.js:474:10)
  at Function.Module._load (module.js:312:12)
  at Module.require (module.js:364:17)
  at require (module.js:380:17)
  at Object.module.exports (C:\app\tests\integration\steps\init.steps.js:2:18)
  at Array.forEach (native)
  at Object.<anonymous> (C:\app\tests\test.js:4:5)
  at Module._compile (module.js:456:26)
  at Object.Module._extensions..js (module.js:474:10)
  at Module.load (module.js:356:32)
  at Function.Module._load (module.js:312:12)
  at Function.Module.runMain (module.js:497:10)
  at startup (node.js:119:16)
  at node.js:906:3

I notice the MZ� and happens because is a binary.

Amd module with return doesn't get populated on node.js

A module like this will return {}

define(function(require, exports, module){

    var logic = {
        a: 3
    }
    return logic;
});

Here is the index.js

var myRequire2 = require('enhanced-require')(module);
console.log(myRequire2('./test'))

This will output {} instead of {logic: 3}. Why is this happening and how to fix it?

I can't change all the define(function(require, exports, module){ files to make them work with module.exports = logic. (The module.exports works ok)

On the client side with webpack works perfectly fine.

Thanks

Resolver plugin not working

I've been having difficulty getting the Resolver plugin working with enhanced-require using the following config:

resolve: {
    root: [
        path.join(__dirname, 'www/app'),
        path.join(__dirname, 'www/bower_components')
    ]
},
plugins: [
    new webpack.ResolverPlugin(
        new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin('bower.json', ['main'])
    )
]

I get cannot resolve module react in /Users/Rich/Projects/fitbit/www/app.

I believe the resolve.root config is working as if I modify the require string to point directly to the component, e.g. require('react') becomes require('react/react'), then it correctly finds it in bower_components (because it doesn't need to read the bower.json).

I have been able to get it to work by using npm instead of bower as it just automatically reads package.json... are plugins supported using enhanced require?

doesn't support emitFile

Trying to use file-loader with this in node.js gives me the error emitFile is required from module system.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.