Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Commit

Permalink
FIX #2
Browse files Browse the repository at this point in the history
Use resolve.modulesDirectories, when resolving bower modules
  • Loading branch information
lpiepiora committed Oct 30, 2014
1 parent 715fd90 commit 5dcd53f
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 20 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ module.exports = {

The plugin takes options object as its single argument.

* `modulesDirectories` {`string[]` or `string`} - the array of extra module directories, the plugin will look for bower components in. The plugin searches also for modules in directories defined at [`resolve.modulesDirectories`](http://webpack.github.io/docs/configuration.html#resolve-modulesdirectories).

* `manifestFiles` {`string[]` or `string`} - the names of the bower manifest files. The plugin
will try them in the order they are mentioned. The first matching will be used.

Expand All @@ -43,9 +45,10 @@ Using the plugin, without specifying the configuration is equivalent to followin
```javascript
plugins: [
new BowerWebpackPlugin({
manifestFiles: "bower.json",
includes: /.*/
excludes: []
modulesDirectories: ["bower_components"],
manifestFiles: "bower.json",
includes: /.*/
excludes: []
})
]
```
Expand Down
26 changes: 13 additions & 13 deletions lib/bower-plugin-manifest-resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ var Q = require('q');
/**
* Resolves a bower manifest file, in the given loop paths, using specified manifest file names
* @param webpackPlugin - the webpack plugin instance
* @param {string[]} lookupPaths - an array of paths, which are used to lookup the manifest file.
* The paths are tried in order, as specified in the array.
* @param {string[]} moduleDirectories - an array of directories, which are used to lookup a manifest file.
* The paths are tried in order, as specified in the array.
* @param {string[]} manifestFiles - an array of possible names of manifest files.
* The files are tried in the order as they are specified in the array.
* @returns {ManifestResolver}
* @constructor
*/
function ManifestResolver(webpackPlugin, lookupPaths, manifestFiles) {
function ManifestResolver(webpackPlugin, moduleDirectories, manifestFiles) {
if (!(this instanceof ManifestResolver)) {
return new ManifestResolver(webpackPlugin, lookupPaths, manifestFiles);
return new ManifestResolver(webpackPlugin, moduleDirectories, manifestFiles);
}

this.webpackPlugin = webpackPlugin;
this.lookupPaths = lookupPaths;
this.modulesDirectories = moduleDirectories;
this.manifestFiles = manifestFiles;

}
Expand All @@ -60,7 +60,7 @@ ManifestResolver.prototype.resolve = function (request, logger) {
var webpackPlugin = this.webpackPlugin,
fsStat = Q.nbind(webpackPlugin.fileSystem.stat, webpackPlugin.fileSystem);

function resolveBowerManifest(startBase, lookupPaths, moduleName, manifestFiles) {
function resolveBowerManifest(startBase, modulesDirectories, moduleName, manifestFiles) {
var deferred = Q.defer();

logger.log("resolve 'bower component' " + moduleName + " manifest files using [" + manifestFiles.join(",") + "]");
Expand All @@ -69,23 +69,23 @@ ManifestResolver.prototype.resolve = function (request, logger) {
(function loopDirectoryHierarchy(base) {

// create a copy
var remainingLookupPaths = lookupPaths.slice(0);
var remainingModulesDirectories = modulesDirectories.slice(0);

(function loopLookupPaths() {
(function loopModulesDirectories() {
var newBase, lookupPath, possibleModulePath, remainingManifestFiles;

if (remainingLookupPaths.length === 0) {
if (remainingModulesDirectories.length === 0) {
newBase = webpackPlugin.normalize(base + "/..");
if (newBase === "" || newBase === base) {
return deferred.reject(new Error(
"No bower component: " + base + "/[" + lookupPaths.join(",") + "]/" + moduleName + "/[" + manifestFiles.join(",") + "]"
"No bower component: " + base + "/[" + modulesDirectories.join(",") + "]/" + moduleName + "/[" + manifestFiles.join(",") + "]"
));
}

return loopDirectoryHierarchy(newBase);
}

lookupPath = remainingLookupPaths.shift();
lookupPath = remainingModulesDirectories.shift();
possibleModulePath = webpackPlugin.join(webpackPlugin.join(base, lookupPath), moduleName);
// create a copy
remainingManifestFiles = manifestFiles.slice(0);
Expand All @@ -94,7 +94,7 @@ ManifestResolver.prototype.resolve = function (request, logger) {
var manifestFile, filePath;

if (remainingManifestFiles.length === 0) {
return loopLookupPaths();
return loopModulesDirectories();
}

manifestFile = remainingManifestFiles.shift();
Expand Down Expand Up @@ -123,7 +123,7 @@ ManifestResolver.prototype.resolve = function (request, logger) {
return deferred.promise;
}

return resolveBowerManifest(request.path, this.lookupPaths, request.request, this.manifestFiles);
return resolveBowerManifest(request.path, this.modulesDirectories, request.request, this.manifestFiles);

};

Expand Down
42 changes: 42 additions & 0 deletions lib/bower-plugin-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Lukasz Piepiora <[email protected]>
*
* 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.
*/

"use strict";

/**
* Given an array, returns new array having only unique entries.
* @param array {Object[]} the array, which may contain duplicates
* @returns {Object[]} an array containing only unique elements
*/
exports.unique = function (array) {
var u = {}, result = [], arrLen = array.length;
for (var i = 0; i < arrLen; i++) {
if (u.hasOwnProperty(array[i])) {
continue;
}
u[array[i]] = true;
result.push(array[i]);
}
return result;
};
10 changes: 6 additions & 4 deletions lib/bower-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ var path = require("path");
var Logger = require("./bower-plugin-logger");
var ManifestResolver = require("./bower-plugin-manifest-resolver.js");
var MainResolver = require("./bower-plugin-main-resolver.js");
var pluginUtils = require("./bower-plugin-utils");

/**
* Configuration for the plugin
* @typedef {Object} BowerWebpackPlugin~Options
* @property {string|string[]} [lookupPaths=["bower_components"]] - the paths, where the plugin searches for the bower components
* @property {string|string[]} [modulesDirectories=["bower_components"]] - the directories, where the plugin searches for bower components
* @property {string|string[]} [manifestFiles=["bower.json"]] - the list of bower manifest files,
* the plugin will try, when looking for a manifest file
* @property {RegExp|RegExp[]} [includes=[RegExp(".*")]] - the list of regular expressions, used to check if a file referenced
Expand All @@ -48,7 +49,7 @@ var MainResolver = require("./bower-plugin-main-resolver.js");
*/
function BowerWebpackPlugin(options) {
var opt = options || {};
this.lookupPaths = opt.lookupPaths ? [].concat(opt.lookupPaths) : ["bower_components"];
this.modulesDirectories = opt.modulesDirectories ? [].concat(opt.modulesDirectories) : ["bower_components"];
this.manifestFiles = opt.manifestFiles ? [].concat(opt.manifestFiles) : ["bower.json"];
this.includes = opt.includes ? [].concat(opt.includes) : [/.*/];
this.excludes = opt.excludes ? [].concat(opt.excludes) : [];
Expand All @@ -57,7 +58,8 @@ function BowerWebpackPlugin(options) {
module.exports = BowerWebpackPlugin;

BowerWebpackPlugin.prototype.apply = function (compiler) {
var lookupPaths = this.lookupPaths,
var configModulesDirectories = compiler.options.resolve.modulesDirectories,
modulesDirectories = pluginUtils.unique(this.modulesDirectories.concat(configModulesDirectories)),
manifestFiles = this.manifestFiles,
includes = this.includes,
excludes = this.excludes,
Expand All @@ -66,7 +68,7 @@ BowerWebpackPlugin.prototype.apply = function (compiler) {
compiler.resolvers.normal.plugin('module', function (request, finalCallback) {

var logger = new Logger(),
manifestResolver = new ManifestResolver(this, lookupPaths, manifestFiles),
manifestResolver = new ManifestResolver(this, modulesDirectories, manifestFiles),
mainResolver = new MainResolver(this, includes, excludes);

// the plugin does not support modules with slashes - no nesting here...
Expand Down
105 changes: 105 additions & 0 deletions test/custom-module-directories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Lukasz Piepiora <[email protected]>
*
* 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.
*/

var testUtils = require("./test-utils");
var BowerWebpackPlugin = require("../");

testUtils.describe("resolving components being stored in custom module directories", function () {
var config = testUtils.config,
testBowerPluginError = testUtils.testBowerPluginError,
testBowerPlugin = testUtils.testBowerPlugin;

it("should not resolve a component stored in 'custom_components' if no custom configuration is given", function (done) {
testBowerPluginError(config("custom-module-multiple-js"), done);
});

it("should resolve a component stored in 'custom_components' dir if it's specified in 'resolve.modulesDirectories'", function (done) {
var cfg = config("custom-module-multiple-js"),
expectations = {
js: ['custom-module-multiple-js-0', 'custom-module-multiple-js-1'],
css: []
};

cfg.resolve = {
modulesDirectories: ["custom_components", "bower_components"]
};

testBowerPlugin(cfg, expectations, done);
});

it("should resolve a component stored in 'custom_components' dir, if the 'cfg.resolve' is undefined", function (done) {
var cfg = config("custom-module-multiple-js"),
expectations = {
js: ['custom-module-multiple-js-0', 'custom-module-multiple-js-1'],
css: []
};

cfg.resolve = undefined;

cfg.plugins = [
new BowerWebpackPlugin({
modulesDirectories: ["custom_components", "bower_components"]
})
];

testBowerPlugin(cfg, expectations, done);
});

it("should resolve a component stored in 'custom_components' dir, if the 'cfg.resolve.moduleDirectories' is undefined", function (done) {
var cfg = config("custom-module-multiple-js"),
expectations = {
js: ['custom-module-multiple-js-0', 'custom-module-multiple-js-1'],
css: []
};

cfg.resolve = {
modulesDirectories: undefined
};

cfg.plugins = [
new BowerWebpackPlugin({
modulesDirectories: ["custom_components", "bower_components"]
})
];

testBowerPlugin(cfg, expectations, done);
});

it("should resolve a component stored in 'custom_components' dir if it's specified in 'modulesDirectories'", function (done) {
var cfg = config("custom-module-multiple-js"),
expectations = {
js: ['custom-module-multiple-js-0', 'custom-module-multiple-js-1'],
css: []
};

cfg.plugins = [
new BowerWebpackPlugin({
modulesDirectories: ["custom_components", "bower_components"]
})
];

testBowerPlugin(cfg, expectations, done);
});

});
25 changes: 25 additions & 0 deletions test/fixtures/custom-module-multiple-js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Lukasz Piepiora <[email protected]>
*
* 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.
*/

require("custom-module-multiple-js");
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "custom-module-multiple-js",
"version": "0.0.1",
"main": [
"module0.js",
"module1.js"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Lukasz Piepiora <[email protected]>
*
* 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.
*/

window.loadedModules = window.loadedModules || [];
window.loadedModules.push("custom-module-multiple-js-0");
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Lukasz Piepiora <[email protected]>
*
* 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.
*/

window.loadedModules = window.loadedModules || [];
window.loadedModules.push("custom-module-multiple-js-1");
Loading

0 comments on commit 5dcd53f

Please sign in to comment.