mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
JSDoc has a few requirements that are somewhat unusual for a Node.js app:
1. We need `require('jsdoc/foo')` to work from any module.
2. We need `require('jsdoc/foo')` to work from external code, such as templates and plugins.
Prior to this commit, JSDoc did two separate things to meet these requirements:
1. Use an npm post-install script to create a symlink from `lib/jsdoc` to `node_modules/jsdoc`.
2. When a user runs JSDoc, copy templates and plugins into the JSDoc directory.
These fixes worked, sort of. But they also caused numerous issues with file permissions, especially on Windows.
We now use the Requizzle module, which hacks the Node.js module system to support JSDoc's use cases. There's no longer a post-install script, and there's no need for a symlink in `node_modules`.
This commit is contained in:
parent
9555f6c43f
commit
fd5ca944d2
10
LICENSE.md
10
LICENSE.md
@ -274,6 +274,16 @@ node-browserify is distributed under the MIT license, which is reproduced above.
|
||||
The source code for node-browserify is available at:
|
||||
https://github.com/substack/node-browserify
|
||||
|
||||
## Requizzle ##
|
||||
|
||||
Requizzle is distributed under the MIT license, which is reproduced above.
|
||||
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
Copyright (c) 2012-2013 Johannes Ewald.
|
||||
|
||||
The source code for Requizzle is available at:
|
||||
https://github.com/hegemonic/requizzle
|
||||
|
||||
## Rhino ##
|
||||
|
||||
Rhino is distributed under the following licenses:
|
||||
|
||||
83
cli.js
83
cli.js
@ -247,78 +247,6 @@ function getRandomId() {
|
||||
return Math.floor(Math.random() * (MAX - MIN + 1) + MIN);
|
||||
}
|
||||
|
||||
// TODO: docs
|
||||
function createTempDir() {
|
||||
var fs = require('jsdoc/fs');
|
||||
var path = require('jsdoc/path');
|
||||
var wrench = require('wrench');
|
||||
|
||||
var isRhino;
|
||||
var tempDirname;
|
||||
var tempPath;
|
||||
|
||||
// We only need one temp directory
|
||||
if (props.tmpdir) {
|
||||
return props.tmpdir;
|
||||
}
|
||||
|
||||
isRhino = require('jsdoc/util/runtime').isRhino();
|
||||
tempDirname = 'tmp-' + Date.now() + '-' + getRandomId();
|
||||
tempPath = path.join(env.dirname, tempDirname);
|
||||
|
||||
try {
|
||||
fs.mkdirSync(tempPath);
|
||||
props.tmpdir = tempPath;
|
||||
}
|
||||
catch (e) {
|
||||
logger.fatal('Unable to create the temp directory %s: %s', tempPath, e.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Delete the temp directory on exit
|
||||
if (isRhino) {
|
||||
( new java.io.File(tempPath) ).deleteOnExit();
|
||||
}
|
||||
else {
|
||||
process.on('exit', function() {
|
||||
wrench.rmdirSyncRecursive(tempPath);
|
||||
});
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
catch (e) {
|
||||
logger.error('Cannot automatically delete the temp directory %s on exit: %s', tempPath,
|
||||
e.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: docs
|
||||
function copyResourceDir(filepath) {
|
||||
var fs = require('jsdoc/fs');
|
||||
var path = require('jsdoc/path');
|
||||
var wrench = require('wrench');
|
||||
|
||||
var resourceDir;
|
||||
var tmpDir;
|
||||
|
||||
try {
|
||||
tmpDir = createTempDir();
|
||||
resourceDir = path.join( tmpDir, path.basename(filepath) + '-' + getRandomId() );
|
||||
fs.mkdirSync(resourceDir);
|
||||
|
||||
wrench.copyDirSyncRecursive(filepath, resourceDir);
|
||||
return resourceDir;
|
||||
}
|
||||
catch (e) {
|
||||
logger.fatal('Unable to copy %s to the temp directory %s: %s', filepath, resourceDir,
|
||||
e.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: docs
|
||||
cli.scanFiles = function() {
|
||||
var Filter = require('jsdoc/src/filter').Filter;
|
||||
@ -373,10 +301,6 @@ function resolvePluginPaths(paths) {
|
||||
logger.error('Unable to find the plugin "%s"', plugin);
|
||||
return;
|
||||
}
|
||||
// On Node.js, the plugin needs to be inside the JSDoc directory
|
||||
else if ( isNode && (pluginPath.indexOf(global.env.dirname) !== 0) ) {
|
||||
pluginPath = copyResourceDir(pluginPath);
|
||||
}
|
||||
|
||||
pluginPaths.push( path.join(pluginPath, basename) );
|
||||
});
|
||||
@ -468,13 +392,6 @@ cli.generateDocs = function() {
|
||||
var publish = env.opts.template || 'templates/default';
|
||||
var templatePath = path.getResourcePath(publish);
|
||||
|
||||
if (templatePath && isNode) {
|
||||
// On Node.js, the template needs to be inside the JSDoc folder
|
||||
if (templatePath.indexOf(env.dirname) !== 0) {
|
||||
templatePath = copyResourceDir(templatePath);
|
||||
}
|
||||
}
|
||||
|
||||
// if we didn't find the template, keep the user-specified value so the error message is
|
||||
// useful
|
||||
return templatePath || env.opts.template;
|
||||
|
||||
39
jsdoc.js
39
jsdoc.js
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
/*global arguments */
|
||||
/*global arguments, require: true */
|
||||
/**
|
||||
* @project jsdoc
|
||||
* @author Michael Mathews <micmath@gmail.com>
|
||||
@ -86,12 +86,23 @@ global.env = {
|
||||
(function(args) {
|
||||
'use strict';
|
||||
|
||||
var path;
|
||||
|
||||
if (args[0] && typeof args[0] === 'object') {
|
||||
// we should be on Node.js
|
||||
args = [__dirname, process.cwd()];
|
||||
path = require('path');
|
||||
|
||||
// Create a custom require method that adds `lib/jsdoc` to the module lookup path.
|
||||
// This makes it possible to `require('jsdoc/foo')` from external templates and plugins,
|
||||
// and within JSDoc itself.
|
||||
require = require('requizzle')({
|
||||
requirePaths: [path.join(__dirname, 'lib')],
|
||||
infect: true
|
||||
});
|
||||
}
|
||||
|
||||
require('jsdoc/util/runtime').initialize(args);
|
||||
require('./lib/jsdoc/util/runtime').initialize(args);
|
||||
})( Array.prototype.slice.call(arguments, 0) );
|
||||
|
||||
/**
|
||||
@ -102,9 +113,9 @@ global.env = {
|
||||
*/
|
||||
global.app = {
|
||||
jsdoc: {
|
||||
scanner: new (require('jsdoc/src/scanner').Scanner)(),
|
||||
name: require('./lib/jsdoc/name'),
|
||||
parser: null,
|
||||
name: require('jsdoc/name')
|
||||
scanner: new (require('./lib/jsdoc/src/scanner').Scanner)()
|
||||
}
|
||||
};
|
||||
|
||||
@ -121,8 +132,8 @@ global.app = {
|
||||
global.dump = function() {
|
||||
'use strict';
|
||||
|
||||
var doop = require('jsdoc/util/doop').doop;
|
||||
var _dump = require('jsdoc/util/dumper').dump;
|
||||
var doop = require('./lib/jsdoc/util/doop').doop;
|
||||
var _dump = require('./lib/jsdoc/util/dumper').dump;
|
||||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||||
console.log( _dump(doop(arguments[i])) );
|
||||
}
|
||||
@ -131,11 +142,14 @@ global.dump = function() {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var logger = require('jsdoc/util/logger');
|
||||
var path = require('jsdoc/path');
|
||||
var runtime = require('jsdoc/util/runtime');
|
||||
var logger = require('./lib/jsdoc/util/logger');
|
||||
var runtime = require('./lib/jsdoc/util/runtime');
|
||||
var cli = require('./cli');
|
||||
|
||||
var cli = require( path.join(global.env.dirname, 'cli') );
|
||||
function cb(errorCode) {
|
||||
cli.logFinish();
|
||||
cli.exit(errorCode || 0);
|
||||
}
|
||||
|
||||
cli.setVersionInfo()
|
||||
.loadConfig();
|
||||
@ -146,11 +160,6 @@ global.dump = function() {
|
||||
|
||||
cli.logStart();
|
||||
|
||||
function cb(errorCode) {
|
||||
cli.logFinish();
|
||||
cli.exit(errorCode || 0);
|
||||
}
|
||||
|
||||
// On Rhino, we use a try/catch block so we can log the Java exception (if available)
|
||||
if ( runtime.isRhino() ) {
|
||||
try {
|
||||
|
||||
@ -1,72 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var jsdocPath = path.resolve( path.join(__dirname, '..') );
|
||||
var symlinkSrc = path.join( jsdocPath, 'lib', 'jsdoc' );
|
||||
var symlinkDest = path.join( jsdocPath, 'node_modules', 'jsdoc' );
|
||||
|
||||
function createJunction(symlinkErr) {
|
||||
fs.symlink(symlinkSrc, symlinkDest, 'junction', function(junctionErr) {
|
||||
if (junctionErr) {
|
||||
console.error('Unable to create a symbolic link or junction from %s to %s.\n' +
|
||||
'Symbolic link result: %s\nJunction result: %s\n' +
|
||||
'Make sure you have write privileges in the target directory. ' +
|
||||
'You may need to run the Windows shell as an administrator.',
|
||||
symlinkSrc, symlinkDest, symlinkErr, junctionErr);
|
||||
process.exit(1);
|
||||
}
|
||||
else {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function checkLink() {
|
||||
fs.readlink(symlinkDest, function(readlinkErr, linkString) {
|
||||
if (!readlinkErr) {
|
||||
linkString = path.resolve(path.dirname(symlinkDest), linkString);
|
||||
if (linkString === symlinkSrc) {
|
||||
// the existing symlink points to the right place
|
||||
process.exit(0);
|
||||
}
|
||||
else {
|
||||
console.error('The symlink at %s points to %s, but it should point to %s. ' +
|
||||
'Please remove the symlink and try again.', symlinkDest, linkString,
|
||||
symlinkSrc);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error('Unable to read the symlink at %s. Please remove the symlink and try ' +
|
||||
'again', symlinkDest);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fs.symlink(symlinkSrc, symlinkDest, 'dir', function(symlinkErr) {
|
||||
if (symlinkErr) {
|
||||
// Does the symlink already exist? If so, does it point to the right place?
|
||||
fs.lstat(symlinkDest, function(lstatErr, stats) {
|
||||
if ( stats && stats.isSymbolicLink() ) {
|
||||
checkLink();
|
||||
}
|
||||
// On Windows, try to create a junction instead
|
||||
else if (process.platform.indexOf('win') === 0) {
|
||||
createJunction(symlinkErr);
|
||||
}
|
||||
else {
|
||||
console.error('Unable to create a symbolic link from %s to %s. %s\n', symlinkSrc,
|
||||
symlinkDest, symlinkErr);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
1
node_modules/jsdoc
generated
vendored
1
node_modules/jsdoc
generated
vendored
@ -1 +0,0 @@
|
||||
../lib/jsdoc
|
||||
22
node_modules/requizzle/LICENSE
generated
vendored
Normal file
22
node_modules/requizzle/LICENSE
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Google Inc.
|
||||
Copyright (c) 2012-2013 Johannes Ewald
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
151
node_modules/requizzle/README.md
generated
vendored
Normal file
151
node_modules/requizzle/README.md
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
# Requizzle #
|
||||
|
||||
Swizzle a little something into your Node.js modules.
|
||||
|
||||
|
||||
## What's Requizzle? ##
|
||||
|
||||
Requizzle provides a drop-in replacement for Node.js's `require()` function. This replacement
|
||||
allows you to change a module's source code at runtime.
|
||||
|
||||
You can use Requizzle in your test cases, or in production code if you like to live dangerously.
|
||||
Requizzle has been tested with Node.js 0.10 and 0.11.
|
||||
|
||||
Here's what Requizzle can do:
|
||||
|
||||
### Look for modules in new places ###
|
||||
|
||||
With Requizzle, you can add directories to the module lookup path, which forces Node.js to search
|
||||
those directories for modules. This can be useful if:
|
||||
|
||||
+ You're tired of writing code like `require('../../../../../lib/foo')`.
|
||||
+ You want to expose your app's modules to external plugins. (Without Requizzle, it can be tough to
|
||||
do this if the plugin is located outside of your app directory.)
|
||||
|
||||
### Add code before or after the module's source code ###
|
||||
|
||||
Tamper with modules to your heart's delight by adding arbitrary code before or after the module's
|
||||
own source code.
|
||||
|
||||
### Mess with child modules ###
|
||||
|
||||
When you use Requizzle to require a module, you can force each child module's `require` method to
|
||||
inherit your changes to the parent module. (By default, only the parent module is changed.)
|
||||
|
||||
### Preserve strict-mode declarations ###
|
||||
|
||||
If a module starts with a strict-mode declaration, Requizzle keeps it in place. Your changes will
|
||||
appear after the strict-mode declaration.
|
||||
|
||||
### Leave native modules alone ###
|
||||
|
||||
If you use one of Node.js's built-in modules, such as `fs` or `path`, Requizzle won't mess with it.
|
||||
|
||||
|
||||
## Installation ##
|
||||
|
||||
With npm:
|
||||
|
||||
npm install requizzle
|
||||
|
||||
With git:
|
||||
|
||||
git clone git://github.com/hegemonic/requizzle.git
|
||||
cd requizzle
|
||||
npm install
|
||||
|
||||
|
||||
## Usage ##
|
||||
|
||||
The Requizzle module exports a single function, which returns a drop-in replacement for
|
||||
`require()`.
|
||||
|
||||
When you call the function, you must pass in an `options` object, which can include any of these
|
||||
properties:
|
||||
|
||||
+ `extras`: A pair of functions that return text to insert before or after the module's source code.
|
||||
Each function accepts two parameters: `targetPath`, the path to the required module, and
|
||||
`parentModule`, the `Module` object for the module's parent. Each function must return a string.
|
||||
+ `extras.before`: A function that returns text to insert before the module's source code.
|
||||
+ `extras.after`: A function that returns text to insert after the module's source code.
|
||||
+ `infect`: Determines whether child modules are infected with the same changes as the parent
|
||||
module. Set to `true` to force child modules to inherit your changes. Defaults to `false`.
|
||||
+ `requirePaths`: An array of additional paths to search for required modules. For example, if
|
||||
`requirePaths` is set to `['/usr/lib/junk/modules']`, and you save a JavaScript module at
|
||||
`/usr/lib/junk/modules/mymodule.js`, you can require the module as `mymodule`. By default, the
|
||||
require path is not changed.
|
||||
|
||||
|
||||
## Examples ##
|
||||
|
||||
```js
|
||||
var requizzle = require('requizzle');
|
||||
|
||||
// Say hello and goodbye to each module.
|
||||
var logRequire = requizzle({
|
||||
extras: {
|
||||
before: function(targetPath, parentModule) {
|
||||
return 'console.log("Hello %s!", ' + targetPath + ');\n';
|
||||
},
|
||||
after: function(targetPath, parentModule) {
|
||||
return 'console.log("Goodbye %s!", ' + targetPath + ');\n';
|
||||
}
|
||||
}
|
||||
});
|
||||
// Prints "Hello /path/to/mymodule.js!" and "Goodbye /path/to/mymodule.js!"
|
||||
var myModule = logRequire('mymodule');
|
||||
|
||||
// Look for modules in the current module's `lib` directory, and force child
|
||||
// modules to do the same.
|
||||
var path = require('path');
|
||||
var extraPathRequire = requizzle({
|
||||
infect: true,
|
||||
requirePaths: [path.join(__dirname, 'lib')]
|
||||
});
|
||||
// If `foo` needs to require a module in `./lib`, it can use `require('bar')`
|
||||
// instead of `require('./lib/bar')`.
|
||||
var foo = extraPathRequire('./foo');
|
||||
```
|
||||
|
||||
|
||||
## Troubleshooting ##
|
||||
|
||||
Here are some problems you may run into when you use Requizzle, along with solutions to each
|
||||
problem. If you run into any problems that aren't addressed here, please file a new issue!
|
||||
|
||||
### Requizzle slowed down my code! A lot! ###
|
||||
|
||||
Requizzle adds minimal overhead to the module-loading process. In some cases, it may even be faster
|
||||
than Node.js's built-in `require()` function.
|
||||
|
||||
However, your code will run _much_ slower than usual if you do both of the following:
|
||||
|
||||
+ Use Requizzle's `infect` option.
|
||||
+ Require modules that have a lot of `require()` calls within the scope of individual functions.
|
||||
|
||||
To fix this issue, find the module calls that are within function scope, and move them to each
|
||||
module's top-level scope. You can find the biggest offenders by using Node.js's built-in `--prof`
|
||||
option to profile your app, then running [node-tick](https://github.com/sidorares/node-tick) to
|
||||
create a report that shows the number of ticks per function.
|
||||
|
||||
### Requizzle made my module do something weird! ###
|
||||
|
||||
Do you have any [circular dependencies](http://nodejs.org/api/modules.html#modules_cycles) in the
|
||||
modules that aren't working? Circular dependencies can cause unusual behavior with Requizzle, just
|
||||
as they can without Requizzle. Try breaking the circular dependency.
|
||||
|
||||
### Requizzle violates the sacred Law of Demeter! It's an unnatural abomination! ###
|
||||
|
||||
Fair enough.
|
||||
|
||||
|
||||
## Acknowledgements ##
|
||||
|
||||
Requizzle is very loosely adapted from Johannes Ewald's [rewire](https://github.com/jhnns/rewire)
|
||||
module, which is designed to modify a module's behavior for unit testing. If Requizzle doesn't meet
|
||||
your needs, please take a look at rewire!
|
||||
|
||||
|
||||
## License ##
|
||||
|
||||
[MIT license](LICENSE).
|
||||
29
node_modules/requizzle/index.js
generated
vendored
Normal file
29
node_modules/requizzle/index.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var _ = require('underscore');
|
||||
var Requizzle = require('./lib/requizzle');
|
||||
|
||||
module.exports = function requizzle(options) {
|
||||
var instance;
|
||||
|
||||
if (!options || typeof options !== 'object') {
|
||||
throw new TypeError('Requizzle\'s options parameter must be a non-null object.');
|
||||
}
|
||||
options = _.clone(options);
|
||||
options.parent = module.parent;
|
||||
|
||||
return function(filepath) {
|
||||
instance = instance || new Requizzle(options);
|
||||
return instance.requizzle(filepath);
|
||||
};
|
||||
};
|
||||
module.exports.Requizzle = Requizzle;
|
||||
|
||||
// force Node.js to reload this module each time it's required, so module.parent is always correct
|
||||
delete require.cache[__filename];
|
||||
167
node_modules/requizzle/lib/loader.js
generated
vendored
Normal file
167
node_modules/requizzle/lib/loader.js
generated
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
Copyright (c) 2012-2013 Johannes Ewald.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var _ = require('underscore');
|
||||
var path = require('path');
|
||||
var Module = require('module');
|
||||
|
||||
var originalWrapper = Module.wrapper.slice(0);
|
||||
|
||||
function wrap(wrappers, script) {
|
||||
return wrappers[0] + script + wrappers[1];
|
||||
}
|
||||
|
||||
function replaceWrapper(wrapperObj) {
|
||||
var joiner = '\n';
|
||||
var before = wrapperObj.before.join(joiner);
|
||||
var after = wrapperObj.after.join(joiner);
|
||||
var wrappers = [
|
||||
originalWrapper[0] + before,
|
||||
after + originalWrapper[1]
|
||||
];
|
||||
|
||||
Module.wrap = wrap.bind(null, wrappers);
|
||||
}
|
||||
|
||||
function restoreWrapper() {
|
||||
Module.wrap = wrap.bind(null, originalWrapper);
|
||||
}
|
||||
|
||||
function createModule(targetPath, parentModule, moduleCache) {
|
||||
moduleCache[targetPath] = moduleCache[targetPath] || new Module(targetPath, parentModule);
|
||||
|
||||
return moduleCache[targetPath];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for `require()` to prevent the target module's dependencies from being swizzled.
|
||||
*
|
||||
* @param {!Module} targetModule - The module that is being swizzled.
|
||||
* @param {!function} nodeRequire - The original `require()` method for the target module.
|
||||
* @param {!string} filepath - The value passed to `require()`.
|
||||
* @return {!Module} The requested module dependency.
|
||||
*/
|
||||
function requireProxy(targetModule, nodeRequire, filepath) {
|
||||
restoreWrapper();
|
||||
targetModule.require = nodeRequire;
|
||||
|
||||
return nodeRequire.call(targetModule, filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for `require()` to swizzle the target module's dependencies, using the same settings as
|
||||
* the target module.
|
||||
*
|
||||
* @param {!Module} targetModule - The module that is being swizzled.
|
||||
* @param {!Object} opts - The Requizzle options object.
|
||||
* @param {!string} filepath - The value passed to `require()`.
|
||||
* @return {!Module} The requested module dependency.
|
||||
*/
|
||||
function infectProxy(targetModule, cache, opts, filepath) {
|
||||
var moduleExports;
|
||||
var Requizzle = require('./requizzle');
|
||||
var requizzle;
|
||||
|
||||
opts = _.clone(opts);
|
||||
opts.parent = targetModule;
|
||||
requizzle = new Requizzle(opts, cache);
|
||||
|
||||
moduleExports = requizzle.requizzle(filepath);
|
||||
|
||||
return moduleExports;
|
||||
}
|
||||
|
||||
var load = exports.load = function load(targetPath, parentModule, wrapper, cache, options) {
|
||||
var nodeRequire;
|
||||
var targetModule;
|
||||
|
||||
// Handle circular requires, and avoid reloading modules unnecessarily
|
||||
if (cache.module[targetPath]) {
|
||||
return cache.module[targetPath];
|
||||
}
|
||||
|
||||
targetModule = createModule(targetPath, parentModule, cache.module);
|
||||
nodeRequire = targetModule.require;
|
||||
|
||||
if (options.infect) {
|
||||
targetModule.require = function(filepath) {
|
||||
return infectProxy(targetModule, cache, options, filepath);
|
||||
};
|
||||
} else {
|
||||
targetModule.require = function(filepath) {
|
||||
return requireProxy(targetModule, nodeRequire, filepath);
|
||||
};
|
||||
}
|
||||
|
||||
// update the wrapper before we load the target module
|
||||
replaceWrapper(wrapper);
|
||||
|
||||
targetModule.load(targetModule.id);
|
||||
|
||||
// make sure the wrapper is restored even if the target module doesn't load any dependencies
|
||||
restoreWrapper();
|
||||
|
||||
return targetModule;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the entire module includes a `'use strict'` declaration.
|
||||
*
|
||||
* @param {string} src - The source file to check.
|
||||
* @return {boolean} Set to `true` if the module includes a `use strict` declaration.
|
||||
*/
|
||||
function detectStrictMode(src) {
|
||||
return (/^\s*(?:["']use strict["'])[ \t]*(?:[\r\n]|;)/g).test(src);
|
||||
}
|
||||
|
||||
function loadSource(targetPath, sourceCache) {
|
||||
var fs = require('fs');
|
||||
|
||||
if (sourceCache[targetPath] === undefined) {
|
||||
sourceCache[targetPath] = fs.readFileSync(targetPath, 'utf8');
|
||||
}
|
||||
|
||||
return sourceCache[targetPath];
|
||||
}
|
||||
|
||||
exports.createWrapper = function createWrapper(targetPath, parentModule, cache, options) {
|
||||
var src;
|
||||
var wrapperObject = {
|
||||
before: [],
|
||||
after: []
|
||||
};
|
||||
|
||||
function add(wrapperFunctions, opts) {
|
||||
var params = [targetPath, parentModule, opts];
|
||||
|
||||
['before', 'after'].forEach(function(item) {
|
||||
var result = wrapperFunctions[item].apply(null, params);
|
||||
|
||||
if (result) {
|
||||
wrapperObject[item].push(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Preserve the module's `use strict` declaration if present
|
||||
src = loadSource(targetPath, cache.source);
|
||||
if (detectStrictMode(src) === true) {
|
||||
add(require('./wrappers/strict'));
|
||||
}
|
||||
|
||||
if (options.requirePaths) {
|
||||
add(require('./wrappers/requirepaths'), options.requirePaths);
|
||||
}
|
||||
|
||||
if (options.extras) {
|
||||
add(require('./wrappers/extras'), options.extras);
|
||||
}
|
||||
|
||||
return wrapperObject;
|
||||
};
|
||||
95
node_modules/requizzle/lib/requizzle.js
generated
vendored
Normal file
95
node_modules/requizzle/lib/requizzle.js
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
Copyright (c) 2012-2013 Johannes Ewald.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/** @module lib/requizzle */
|
||||
|
||||
var _ = require('underscore');
|
||||
var loader = require('./loader');
|
||||
var Module = require('module');
|
||||
var path = require('path');
|
||||
|
||||
/**
|
||||
* Function that returns text to swizzle into the module.
|
||||
*
|
||||
* @typedef module:lib/requizzle~wrapperFunction
|
||||
* @type {function}
|
||||
* @param {string} targetPath - The path to the target module.
|
||||
* @param {string} parentModulePath - The path to the module that is requiring the target module.
|
||||
* @return {string} The text to insert before or after the module's source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for the wrappers that will be swizzled into the target module.
|
||||
*
|
||||
* @typedef module:lib/requizzle~options
|
||||
* @type {Object}
|
||||
* @property {Object=} options.extras - Functions that generate text to swizzle into the target
|
||||
* module.
|
||||
* @property {module:lib/requizzle~wrapperFunction} options.extras.after - Function that returns
|
||||
* text to insert after the module's source code.
|
||||
* @property {module:lib/requizzle~wrapperFunction} options.extras.before - Function that returns
|
||||
* text to insert before the module's source code.
|
||||
* @property {(Array.<string>|string)} options.requirePaths - Additional paths to search when
|
||||
* resolving module paths in the target module.
|
||||
*/
|
||||
|
||||
function isNativeModule(targetPath, parentModule) {
|
||||
var lookupPaths = Module._resolveLookupPaths(targetPath, parentModule);
|
||||
|
||||
if (lookupPaths[0] === targetPath && lookupPaths[1].length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a `Requizzle` instance. If you provide options, Requizzle will default to those options
|
||||
* when you call {@link Requizzle#requizzle}.
|
||||
*
|
||||
* @class
|
||||
* @param {!module:lib/requizzle~options} options - Options for the wrappers that will be swizzled
|
||||
* into the target module.
|
||||
* @param {Object=} cache - For internal use.
|
||||
*/
|
||||
function Requizzle(options, cache) {
|
||||
this._options = options;
|
||||
this._cache = cache || {
|
||||
module: {},
|
||||
source: {}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the module, swizzling in the requested changes.
|
||||
*
|
||||
* @param {!string} targetPath - The path to the module that will be loaded.
|
||||
* @return {Module} The swizzled module.
|
||||
*/
|
||||
Requizzle.prototype.requizzle = function requizzle(targetPath) {
|
||||
var options = this._options;
|
||||
var parentModule = options.parent;
|
||||
var targetModule;
|
||||
var wrapper;
|
||||
|
||||
// Don't interfere with native modules
|
||||
if (isNativeModule(targetPath, parentModule)) {
|
||||
return require(targetPath);
|
||||
}
|
||||
|
||||
// Resolve the filename relative to the parent module
|
||||
targetPath = Module._resolveFilename(targetPath, parentModule);
|
||||
|
||||
wrapper = loader.createWrapper(targetPath, parentModule, this._cache, this._options);
|
||||
targetModule = loader.load(targetPath, parentModule, wrapper, this._cache, this._options);
|
||||
|
||||
return targetModule.exports;
|
||||
};
|
||||
|
||||
module.exports = Requizzle;
|
||||
23
node_modules/requizzle/lib/wrappers/extras.js
generated
vendored
Normal file
23
node_modules/requizzle/lib/wrappers/extras.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function callFunction(targetPath, parentModule, func) {
|
||||
if (!func) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return func(targetPath, parentModule);
|
||||
}
|
||||
|
||||
exports.before = function before(targetPath, parentModule, options) {
|
||||
return callFunction(targetPath, parentModule, options.before);
|
||||
};
|
||||
|
||||
exports.after = function after(targetPath, parentModule, options) {
|
||||
return callFunction(targetPath, parentModule, options.after);
|
||||
};
|
||||
28
node_modules/requizzle/lib/wrappers/requirepaths.js
generated
vendored
Normal file
28
node_modules/requizzle/lib/wrappers/requirepaths.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
function requirePaths(parentModule, paths) {
|
||||
if (!parentModule) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
return paths.slice(0).map(function(p) {
|
||||
return path.resolve(parentModule.filepath, p);
|
||||
});
|
||||
}
|
||||
|
||||
exports.before = function before(targetPath, parentModule, opts) {
|
||||
var resolvedPaths = requirePaths(parentModule, opts);
|
||||
return 'module.paths = module.paths.concat(' + JSON.stringify(resolvedPaths) + ');\n';
|
||||
};
|
||||
|
||||
exports.after = function after(targetPath, parentModule, opts) {
|
||||
return '';
|
||||
};
|
||||
15
node_modules/requizzle/lib/wrappers/strict.js
generated
vendored
Normal file
15
node_modules/requizzle/lib/wrappers/strict.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
Copyright (c) 2014 Google Inc. All rights reserved.
|
||||
|
||||
Use of this source code is governed by the MIT License, available in this package's LICENSE file
|
||||
or at http://opensource.org/licenses/MIT.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
exports.before = function before() {
|
||||
return '"use strict";';
|
||||
};
|
||||
|
||||
exports.after = function after() {
|
||||
return '';
|
||||
};
|
||||
46
node_modules/requizzle/package.json
generated
vendored
Normal file
46
node_modules/requizzle/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jsdoc",
|
||||
"version": "3.3.0-dev",
|
||||
"revision": "1401234887184",
|
||||
"revision": "1402359726912",
|
||||
"description": "An API documentation generator for JavaScript.",
|
||||
"keywords": [
|
||||
"documentation",
|
||||
@ -23,6 +23,7 @@
|
||||
"esprima": "https://github.com/ariya/esprima/tarball/49a2eccb243f29bd653b11e9419241a9d726af7c",
|
||||
"js2xmlparser": "~0.1.0",
|
||||
"marked": "~0.3.1",
|
||||
"requizzle": "~0.1.0",
|
||||
"taffydb": "https://github.com/hegemonic/taffydb/tarball/master",
|
||||
"underscore": "~1.6.0",
|
||||
"wrench": "~1.3.9"
|
||||
@ -38,7 +39,6 @@
|
||||
"node": ">=0.10"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./node/postinstall.js",
|
||||
"test": "gulp test"
|
||||
},
|
||||
"bin": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user