├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── component-loader.js ├── index.js └── package.json /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright JS Foundation and other contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | 'Software'), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # component for webpack 2 | 3 | **UNMAINTAINED!** 4 | 5 | ## Usage 6 | 7 | ``` javascript 8 | var ComponentPlugin = require("component-webpack-plugin"); 9 | module.exports = { 10 | plugins: [ 11 | new ComponentPlugin(); 12 | ] 13 | } 14 | ``` 15 | 16 | ## Advanced usage 17 | 18 | ``` javascript 19 | var ComponentPlugin = require("component-webpack-plugin"); 20 | module.exports = { 21 | plugins: [ 22 | new ComponentPlugin({ 23 | // Load xyz field in component.json 24 | xyz: true, 25 | // This is equal to: xyz: "[file]" 26 | 27 | // Load xyz field with the xyz-loader 28 | xyz: "!xyz-loader![file]", 29 | 30 | // This is default: 31 | // styles: "!style-loader!css-loader![file]" 32 | }, [ 33 | // Lookup paths 34 | "component" 35 | ]); 36 | ] 37 | } 38 | ``` 39 | 40 | 41 | ## License 42 | 43 | MIT (http://www.opensource.org/licenses/mit-license.php) 44 | -------------------------------------------------------------------------------- /component-loader.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License http://www.opensource.org/licenses/mit-license.php 3 | Author Tobias Koppers @sokra 4 | */ 5 | module.exports = function(source) { 6 | this.cacheable(); 7 | var content = JSON.parse(source); 8 | var main = content.main || "index.js"; 9 | var fieldBindings = JSON.parse(this.query.substr(1)); 10 | var result = []; 11 | Object.keys(fieldBindings).forEach(function(fieldBinding) { 12 | var binding = fieldBindings[fieldBinding]; 13 | if(Array.isArray(content[fieldBinding])) { 14 | content[fieldBinding].forEach(function(item) { 15 | if(typeof binding === "string") 16 | result.push("require(" + JSON.stringify(binding.replace(/\[file\]/g, "./" + item)) + ");"); 17 | else if(binding === true) 18 | result.push("require(" + JSON.stringify("./" + item) + ");"); 19 | }); 20 | } 21 | }); 22 | result.push("module.exports = require(" + JSON.stringify("./" + main) + ");"); 23 | return result.join("\n"); 24 | }; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | MIT License http://www.opensource.org/licenses/mit-license.php 3 | Author Tobias Koppers @sokra 4 | */ 5 | var path = require("path"); 6 | 7 | function ComponentPlugin(fieldBindings, lookupPaths, componentFile) { 8 | this.fieldBindings = fieldBindings || {}; 9 | this.lookupPaths = lookupPaths || ["components"]; 10 | this.componentFile = componentFile || "component.json"; 11 | if(typeof this.fieldBindings.styles === "undefined") { 12 | this.fieldBindings.styles = "!" + require.resolve("style-loader") + "!" + require.resolve("css-loader") + "![file]"; 13 | } 14 | } 15 | module.exports = ComponentPlugin; 16 | 17 | ComponentPlugin.prototype.apply = function(compiler) { 18 | var fieldBindings = this.fieldBindings; 19 | var lookupPaths = this.lookupPaths; 20 | var componentFile = this.componentFile; 21 | compiler.resolvers.normal.plugin("module", function(request, finalCallback) { 22 | if(request.request.indexOf("/") >= 0) return finalCallback(); 23 | 24 | function callback() { 25 | if(finalCallback.log) { 26 | finalCallback.log("resolve component " + request.request + " in " + request.path); 27 | logData.forEach(finalCallback.log, finalCallback); 28 | } 29 | finalCallback.apply(this, arguments); 30 | } 31 | var logData = []; 32 | function log(msg) { 33 | logData.push(" " + msg); 34 | } 35 | 36 | var fs = this.fileSystem; 37 | 38 | // 1. Find next component.json file and read it 39 | var componentPath = request.path + "/"; 40 | var componentFileContent, componentFilePath; 41 | (function next() { 42 | var idx = componentPath.lastIndexOf("/"); 43 | if(idx < 0) idx = componentPath.lastIndexOf("\\"); 44 | if(idx < 0) return callback(); 45 | componentFilePath = componentPath.substr(0, idx + 1) + componentFile; 46 | componentPath = componentPath.substr(0, idx); 47 | fs.readFile(componentFilePath, function(err, content) { 48 | if(err) return next.call(this); 49 | try { 50 | componentFileContent = JSON.parse(content); 51 | } catch(e) { 52 | return callback(componentFilePath + " parsing failed: " + e); 53 | } 54 | findModule.call(this); 55 | }.bind(this)); 56 | }.call(this)); 57 | 58 | // 2. get the full name for the module 59 | // i. e. "emitter" -> "sokra/emitter" 60 | function findModule() { 61 | var modules = componentFileContent.local ? componentFileContent.local : []; 62 | if(componentFileContent.dependencies) { 63 | modules = modules.concat(Object.keys(componentFileContent.dependencies)); 64 | } 65 | if(componentFileContent.development) { 66 | modules = modules.concat(Object.keys(componentFileContent.development)); 67 | } 68 | var fullName, requestName = request.request; 69 | for(var i = 0; i < modules.length; i++) { 70 | var name = modules[i]; 71 | if(name.replace("/", "-") === requestName) { 72 | fullName = modules[i]; 73 | break; 74 | } 75 | var idx = name.indexOf("/"); 76 | if(idx >= 0) name = name.substr(idx+1); 77 | if(requestName === name) { 78 | fullName = modules[i]; 79 | break; 80 | } 81 | } 82 | if(!fullName) { 83 | log(componentFilePath + " doesn't contain a dependency matching " + requestName); 84 | return callback(); 85 | } 86 | log(componentFilePath + " contains a dependency " + fullName); 87 | findInDirectories.call(this, fullName); 88 | } 89 | 90 | // 3. find all lookup directories and check if the module is there 91 | function findInDirectories(fullName) { 92 | componentPath += "/"; 93 | (function next() { 94 | var idx = componentPath.lastIndexOf("/"); 95 | if(idx < 0) idx = componentPath.lastIndexOf("\\"); 96 | if(idx < 0) return callback(); 97 | var componentFilePath = componentPath.substr(0, idx + 1) + componentFile; 98 | componentPath = componentPath.substr(0, idx); 99 | fs.readFile(componentFilePath, function(err, content) { 100 | if(err) return next.call(this); 101 | try { 102 | componentFileContent = JSON.parse(content); 103 | } catch(e) { 104 | return callback(componentFilePath + " parsing failed: " + e); 105 | } 106 | var paths = componentFileContent.paths ? componentFileContent.paths : []; 107 | paths = paths.concat(lookupPaths); 108 | this.forEachBail(paths, function(path, callback) { 109 | var modulesFolderPath = this.join(componentPath, path); 110 | var modulePath = this.join(modulesFolderPath, fullName.replace(/\//g, "-")); 111 | fs.stat(modulePath, function(err, stat) { 112 | if(err || !stat) { 113 | log(modulePath + " doesn't exist"); 114 | return callback(); 115 | } 116 | if(!stat.isDirectory()) { 117 | log(modulePath + " is not a directory"); 118 | return callback(); 119 | } 120 | return callback(null, { 121 | path: this.join(modulePath, componentFile), 122 | query: request.query, 123 | resolved: true 124 | }); 125 | }.bind(this)); 126 | }.bind(this), function(err, result) { 127 | if(err) return callback(err); 128 | if(result) return callback(null, result); 129 | return next.call(this); 130 | }.bind(this)); 131 | }.bind(this)); 132 | }.call(this)); 133 | } 134 | }); 135 | compiler.plugin("normal-module-factory", function(nmf) { 136 | nmf.plugin("after-resolve", function(data, callback) { 137 | if(data.userRequest.indexOf("!") >= 0) return callback(null, data); 138 | if(!new RegExp("[\\\\\\/]" + escapeRegExpString(componentFile) + "$").test(data.userRequest)) return callback(null, data); 139 | data.loaders = [path.join(__dirname, "component-loader.js") + "?" + JSON.stringify(fieldBindings)]; 140 | var componentName = data.resource.substr(0, data.resource.length - componentFile.length - 1); 141 | data.request = componentName + " component"; 142 | data.userRequest = componentName + " (component)"; 143 | callback(null, data); 144 | }); 145 | }); 146 | }; 147 | function escapeRegExpString(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); } 148 | function pathToRegExp(p) { return new RegExp("^" + escapeRegExpString(p)); } 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "component-webpack-plugin", 3 | "version": "0.2.1", 4 | "author": "Tobias Koppers @sokra", 5 | "description": "Use components with webpack", 6 | "dependencies": { 7 | "css-loader": "0.6.x", 8 | "style-loader": "0.5.x" 9 | }, 10 | "peerDependencies": { 11 | "webpack": ">=0.9.2" 12 | }, 13 | "licenses": [ 14 | { 15 | "type": "MIT", 16 | "url": "http://www.opensource.org/licenses/mit-license.php" 17 | } 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url" : "https://github.com/webpack/component-webpack-plugin.git" 22 | } 23 | } 24 | --------------------------------------------------------------------------------