├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── include.js ├── lib ├── example.js ├── includes │ ├── foo.js │ └── modules │ │ ├── bar.js │ │ ├── lib │ │ └── baz.js │ │ └── package.json └── package.json ├── package.json └── test └── includeSpec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | root = true 4 | [*.js] 5 | end_of_line = lf 6 | insert_final-newline = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 Anthony Nichols 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-include 2 | 3 | Require local files relative to the path provided at require. 4 | 5 | # install 6 | 7 | npm install include 8 | 9 | # usage 10 | 11 | ```js 12 | var include = require('include')(__dirname); 13 | ``` 14 | 15 | #### without include 16 | 17 | ```js 18 | var foo = require('../../../path/to/foo'); 19 | ``` 20 | 21 | #### with include 22 | 23 | ```js 24 | var foo = include('path/to/foo'); 25 | ``` 26 | 27 | # license 28 | MIT 29 | -------------------------------------------------------------------------------- /include.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Node 4 | var lstatSync = require('fs').lstatSync; 5 | var path = require('path'); 6 | 7 | /** 8 | * Attempts to find the project root by finding the nearest package.json file. 9 | * @private 10 | * @param {String} currentPath - Path of the file doing the including. 11 | * @return {String?} 12 | */ 13 | function findProjectRoot(currentPath) { 14 | var result = undefined; 15 | 16 | try { 17 | var packageStats = lstatSync(path.join(currentPath, 'package.json')); 18 | 19 | if (packageStats.isFile()) { 20 | result = currentPath; 21 | } 22 | } catch (error) { 23 | if (currentPath !== path.resolve('/')) { 24 | result = findProjectRoot(path.join(currentPath, '..')); 25 | } 26 | } 27 | 28 | return result; 29 | } 30 | 31 | /** 32 | * Creates the include function wrapper around require based on the path of the calling file and not the 33 | * install location of the module. 34 | * @param {String} callerPath - Path of the calling file. 35 | * @return {Function} 36 | * @example 37 | * 38 | * var include = require('include')(__dirname); 39 | * 40 | * var projectFn = include('src/method'); 41 | */ 42 | function createInclude(callerPath) { 43 | return function (target) { 44 | var projectRoot = findProjectRoot(callerPath); 45 | 46 | return projectRoot ? 47 | require(path.join(projectRoot, target)) : 48 | require(target); 49 | }; 50 | } 51 | 52 | module.exports = createInclude; 53 | -------------------------------------------------------------------------------- /lib/example.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var include = require('../include')(__dirname); 3 | 4 | var fooPath = 'includes/foo'; 5 | var foo = include(fooPath); 6 | 7 | var values = { 8 | path: path.resolve(__dirname, path.basename(__filename, '.js')), 9 | name: path.basename(__filename, '.js'), 10 | includedPath: fooPath, 11 | included: foo 12 | }; 13 | 14 | module.exports = values; -------------------------------------------------------------------------------- /lib/includes/foo.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var include = require('../../include')(__dirname); 3 | 4 | var barPath = 'includes/modules/bar'; 5 | var bazPath = 'includes/modules/lib/baz'; 6 | 7 | var bar = include(barPath); 8 | var baz = include(bazPath); 9 | 10 | var values = { 11 | path: path.resolve(__dirname, path.basename(__filename, '.js')), 12 | name: path.basename(__filename, '.js'), 13 | includedPath: [barPath, bazPath], 14 | included: [bar, baz] 15 | }; 16 | 17 | module.exports = values; -------------------------------------------------------------------------------- /lib/includes/modules/bar.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var include = require('../../../include')(__dirname); 3 | 4 | var bazPath = 'lib/baz'; 5 | var baz = include(bazPath); 6 | 7 | var values = { 8 | path: path.resolve(__dirname, path.basename(__filename, '.js')), 9 | name: path.basename(__filename, '.js'), 10 | includedPath: bazPath, 11 | included: baz 12 | }; 13 | 14 | module.exports = values; -------------------------------------------------------------------------------- /lib/includes/modules/lib/baz.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var values = { 4 | path: path.resolve(__dirname, path.basename(__filename, '.js')), 5 | name: path.basename(__filename, '.js'), 6 | }; 7 | 8 | module.exports = values; -------------------------------------------------------------------------------- /lib/includes/modules/package.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /lib/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "include", 3 | "version": "1.1.0", 4 | "description": "Require local files relative to the root of your node project.", 5 | "keywords": [ 6 | "include", 7 | "require" 8 | ], 9 | "author": { 10 | "name": "Anthony Nichols", 11 | "email": "hi@anthonynichols.me", 12 | "url": "https://github.com/anthonynichols" 13 | }, 14 | "homepage": "https://github.com/anthonynichols/node-include", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/anthonynichols/node-include.git" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/anthonynichols/node-include/issues" 21 | }, 22 | "main": "include.js", 23 | "scripts": { 24 | "test": "mocha" 25 | }, 26 | "readmeFile": "README.md", 27 | "license": "MIT", 28 | "devDependencies": { 29 | "chai": "^3.4.1", 30 | "mocha": "^2.3.4" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/includeSpec.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var expect = require('chai').expect; 3 | var include = require('../include')(__dirname); 4 | 5 | describe('include', function () { 6 | var example = include('lib/example'); 7 | var foo = undefined; 8 | var bar = undefined; 9 | var baz = undefined; 10 | 11 | it('should return a module given a path relative to the package root.', function () { 12 | expect(example).to.be.a('object'); 13 | expect(example.name).to.equal('example'); 14 | }); 15 | 16 | it('should allow installed modules to include a module given a path relative to the installed module\'s package root.', function () { 17 | foo = example.included; 18 | 19 | expect(foo).to.be.a('object'); 20 | expect(foo.path).to.equal(path.resolve('.', 'lib', example.includedPath)) 21 | }); 22 | 23 | it('should allow installed modules within modules to include a module given a path relative to the module\'s package root, not the parent\'s root.', function () { 24 | bar = foo.included[0]; 25 | baz = foo.included[1]; 26 | 27 | expect(bar).to.be.a('object'); 28 | expect(bar.path).to.equal(path.resolve('.', 'lib', foo.includedPath[0])); 29 | expect(baz).to.be.a('object'); 30 | expect(baz.path).to.equal(path.resolve('.', 'lib/includes/modules', bar.includedPath)); 31 | }); 32 | }); --------------------------------------------------------------------------------