├── .npmignore ├── .travis.yml ├── README.md ├── package.json ├── postinstall.js └── test.js /.npmignore: -------------------------------------------------------------------------------- 1 | test.js 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | - "0.12" 5 | - '1' 6 | - '2' 7 | - '3' 8 | - '4' 9 | - '5' 10 | - '6' 11 | - '7' 12 | install: echo 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wavy 2 | use ~ in require and import calls 3 | 4 | [![NPM version][npm-image]][npm-url] 5 | [![Build status][travis-image]][travis-url] 6 | [![Downloads][downloads-image]][downloads-url] 7 | 8 | ### install 9 | 10 | ```bash 11 | npm install --save wavy 12 | ``` 13 | 14 | This module lets you turn things like `require('../../../../foo')` into something like 15 | `require('~/foo')`. The way it works is that on postinstall it creates a symlink in `app/node_modules/~` to point to `app/` 16 | 17 | Tested on Mac, Linux, and Windows 18 | Tested with `npm`, [`pnpm`](https://www.npmjs.com/package/pnpm), 19 | and [`ied`](https://www.npmjs.com/package/ied) 20 | 21 | [npm-image]: https://img.shields.io/npm/v/wavy.svg?style=flat-square 22 | [npm-url]: https://npmjs.org/package/wavy 23 | [travis-image]: https://img.shields.io/travis/kolodny/wavy.svg?style=flat-square 24 | [travis-url]: https://travis-ci.org/kolodny/wavy 25 | [downloads-image]: http://img.shields.io/npm/dm/wavy.svg?style=flat-square 26 | [downloads-url]: https://npmjs.org/package/wavy 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wavy", 3 | "version": "1.0.4", 4 | "description": "use `~` in require and import calls", 5 | "main": "index.js", 6 | "scripts": { 7 | "postinstall": "node postinstall", 8 | "test": "node test" 9 | }, 10 | "keywords": [ 11 | "~", 12 | "require", 13 | "symlink" 14 | ], 15 | "author": "Moshe Kolodny", 16 | "license": "MIT", 17 | "repository": { 18 | "type": "git", 19 | "url": "git+https://github.com/kolodny/wavy.git" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/kolodny/wavy/issues" 23 | }, 24 | "homepage": "https://github.com/kolodny/wavy#readme" 25 | } 26 | -------------------------------------------------------------------------------- /postinstall.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | 4 | var dirname = __dirname.replace(/\\/g, '/'); 5 | var root = path.resolve(dirname.slice(0, dirname.lastIndexOf('/node_modules/'))); 6 | var link = root + '/node_modules/~'; 7 | try { 8 | var existingReal = path.resolve(fs.realpathSync(link)); 9 | } catch (e) { 10 | fs.symlinkSync(root, link, 'junction'); 11 | process.exit(0); 12 | } 13 | if (existingReal && existingReal !== root) { 14 | throw new Error(link + ' is already being used') 15 | } 16 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var exec = require('child_process').exec; 3 | var path = require('path'); 4 | 5 | var testDir = path.resolve(__dirname + '/test-dir'); 6 | 7 | if (fs.existsSync(testDir)) { 8 | deleteFolderRecursive(testDir); 9 | } 10 | 11 | fs.mkdirSync(testDir); 12 | fs.writeFileSync(testDir + '/package.json', '{}'); 13 | fs.writeFileSync(testDir + '/index.js', 'console.log(require("~/foo"))'); 14 | fs.writeFileSync(testDir + '/foo.js', 'module.exports = "foo";'); 15 | 16 | console.log('wavy'); 17 | exec('node --version', function(err, out) { 18 | var isgnoreNpmInstallDotDot = Number(out.match(/v(\d+)/)[1]) >= 5; 19 | exec('npm install -S ..', { cwd: testDir }, function(err) { 20 | handleError(err); 21 | console.log('√ installs without errors'); 22 | exec('node index', { cwd: testDir }, function(err, stdout) { 23 | handleError(err); 24 | if (stdout.trim() !== 'foo') { 25 | handleError(new Error('expected output to be "foo" got ' + stdout.trim())); 26 | } 27 | console.log('√ works after install'); 28 | exec('npm install ..', { cwd: testDir }, function(err) { 29 | if (!isgnoreNpmInstallDotDot) handleError(err); 30 | console.log('√ can handle multiple installs'); 31 | deleteFolderRecursive(testDir + '/node_modules'); 32 | fs.mkdirSync(testDir + '/node_modules/'); 33 | fs.writeFileSync(testDir + '/node_modules/~', '123'); 34 | exec('npm install ..', { cwd: testDir }, function(err) { 35 | var regex = /^Error: .*[\/\\]node_modules[\/\\]~ is already being used$/m; 36 | if (!regex.test(err.message)) { 37 | handleError(new Error('did not handle improper existing ~')) 38 | } 39 | console.log('√ handles `~` already being used by something else'); 40 | console.log(''); 41 | console.log('all tests passed!'); 42 | deleteFolderRecursive(testDir); 43 | }); 44 | }); 45 | }); 46 | }); 47 | }); 48 | 49 | function handleError(err) { 50 | if (err) { 51 | deleteFolderRecursive(testDir); 52 | console.error(err.stack); 53 | process.exit(1); 54 | } 55 | } 56 | 57 | // http://stackoverflow.com/a/12761924 58 | function deleteFolderRecursive(path) { 59 | var files = []; 60 | if (fs.existsSync(path)) { 61 | files = fs.readdirSync(path); 62 | files.forEach(function(file,index){ 63 | var curPath = path + "/" + file; 64 | if (fs.lstatSync(curPath).isDirectory()) { 65 | deleteFolderRecursive(curPath); 66 | } else { 67 | fs.unlinkSync(curPath); 68 | } 69 | }); 70 | fs.rmdirSync(path); 71 | } 72 | }; 73 | --------------------------------------------------------------------------------