Symptom
When using dmd module as a component, as a part of other projects (e.g.: gulp-jsdoc-to-markdown), when specifying own plugins, the moduleSearch() function in dmd.js cannot properly resolve the path of given moduleName.
Use Case
Using gulp-jsdoc-to-markdown:
// using gulp
const gulp = require("gulp"),
doc = require("gulp-jsdoc-to-markdown"),
gulp.task("doc::generate", function() {
return gulp.src("/vagrant/src/*.js")
.pipe(doc({
plugin : ["/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js"]
}))
.pipe(gulp.dest("/vagrant/doc"));
});
gulp-jsdoc-to-markdown passes the options Object _untouched_ regarding the .plugin property to dmd via jsdoc-to-markdown.
Check the call chain:
- gulp-jsdoc-to-markdown.js
- jsdoc-to-markdown.js
- dmd.js
During the gulp.task run, dmd tries to resolve the given plugin paths via the moduleSearch() function.
This function tries to resolve the given plugin path by splitting the given plugin path into chunks separated by DS, and then joins them with "node_modules" embedding between the chunks iteratively.
If dmd is used outside of its directory structure (e.g.: as a component), this method will fail, when the specified plugin is not in "node_modules".
console.log() output in Vagrant VM, when moduleSearch() tries to resolve the given plugin path
// NOTE: the given plugin path is "/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js"
// as can be seen in the previous gulp example
modulePath: /vagrant/tasks/gulp/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /vagrant/tasks/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /vagrant/node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
modulePath: /node_modules/vagrant/tasks/gulp/tasks/doc/lib/dmd-plugin-example.js
You can see, that the moduleSearch() function tries to resolve the plugin's path, but upon resolving the path, it embeds "node_modules" into the path, that it checks iteratively.
The plugin is not in a node_modules folder or folder structure, as it is a custom one, a modified one for own purposes and also it is not recommended to put other code into node's node_modules folder by other means, than node modifying its contents (e.g.: npm install) as the content of node_modules can often change, also it is generally ignored by git.
Reproduction
Use Vagrant via this gist:
- start the vm via
vagrant up
- after the provision, install gulp-jsdoc-to-markdown and dmd-plugin-example via npm
(if you encounter any npm-related issue, check the gist mentioned above as it may contain the solution)
- create a small .js file with valid jsdoc tags,
like those can be found here
- create a gulp task similar to that above mentioned before and use your previously created .js file with valid jsdoc tags
- copy dmd-plugin-example from node_modules into your project,
for example YourProjectPath/doc/dmd-plugin-example/
- run the gulp task with the specified full path to
your dmd-plugin-example (e.g.: YourProjectPath/doc/dmd-plugin-example/lib/dmd-plugin-example.js)
as can be seen in the previously mentioned gulp example above
- you will get an error, like:
Error: Cannot find plugin: YourProjectPath/doc/dmd-plugin-example/lib/dmd-plugin-example.js
although the plugin exists under the path specified before running the gulp task
Resolution
This pull request fixes this issue through a minor patch.
This fix resolves this unintended behaviour, by relying the full, normalized, unfiltered path testing and using only, when the general plugin path testing method mentioned above failed, so old code, libraries and other dependents will work without any modifications.