├── .babelrc ├── .gitignore ├── .travis.yml ├── index.js ├── config └── mocha.js ├── CHANGELOG.md ├── plugin ├── helper.js └── index.js ├── README.md ├── package.json ├── test ├── plugin.spec.js └── helper.spec.js ├── LICENSE └── .eslintrc /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015","stage-1"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | build 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | global.rootPath = process.cwd(); 2 | module.exports = require('./build/index.js'); 3 | -------------------------------------------------------------------------------- /config/mocha.js: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import sinon from 'sinon'; 3 | 4 | global.chai = chai; 5 | global.expect = chai.expect; 6 | global.sinon = sinon; 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ChangeLog 2 | 3 | ### v1.1.0 4 | 5 | Add support to use inside Meteor. Basically, we turn off plugin when running inside Meteor. 6 | See: [a43785d](https://github.com/mantrajs/babel-root-slash-import/commit/90d768668fb589583657aa949683149bc6d33020) 7 | 8 | ### v1.0.0 9 | 10 | Forked use `/` instead of '~/' to define the root. 11 | This is to go with the Meteor's ES2015 module implementation. 12 | -------------------------------------------------------------------------------- /plugin/helper.js: -------------------------------------------------------------------------------- 1 | export default function(path) { 2 | class BabelRootImportHelper { 3 | 4 | root = global.rootPath || process.cwd(); 5 | 6 | transformRelativeToRootPath(path, rootPathSuffix) { 7 | if (this.hasRoot(path)) { 8 | const withoutRoot = path.substring(1, path.length); 9 | return `${this.root}${rootPathSuffix ? rootPathSuffix : ''}/${withoutRoot}`; 10 | } 11 | if (typeof path === 'string') { 12 | return path; 13 | } 14 | throw new Error('ERROR: No path passed'); 15 | } 16 | 17 | hasRoot(string) { 18 | let containsTilde = false; 19 | 20 | if (typeof string !== 'string') { 21 | return false; 22 | } 23 | 24 | const firstChar = string.substring(0, 1); 25 | return firstChar === '/'; 26 | } 27 | } 28 | 29 | return new BabelRootImportHelper(); 30 | } 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Babel Root Import 2 | Babel plugin to change the behaviour of `import` to root based paths.
3 | 4 | ## Example 5 | ```javascript 6 | // Usually 7 | import SomeExample from '../../../some/example.js'; 8 | 9 | // With Babel-Root-Importer 10 | import SomeExample from '/some/example.js'; 11 | ``` 12 | 13 | ## Install 14 | ``` 15 | npm install babel-root-slash-import --save-dev 16 | ``` 17 | 18 | ## Use 19 | Add a `.babelrc` file and write: 20 | ```javascript 21 | { 22 | "plugins": [ 23 | "babel-root-slash-import" 24 | ] 25 | } 26 | ``` 27 | or pass the plugin with the plugins-flag on CLI 28 | ``` 29 | babel-node myfile.js --plugins babel-root-slash-import 30 | ``` 31 | 32 | ## Extras 33 | If you want a custom root because for example all your files are in the src/js folder you can define this in your `.babelrc` file 34 | ```javascript 35 | { 36 | "plugins": [ 37 | ["babel-root-slash-import", { 38 | "rootPathSuffix": "src/js" 39 | }] 40 | ] 41 | } 42 | ``` 43 | 44 | ## Motivate 45 | If you like this project just give it a star :) I like stars. 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-root-slash-import", 3 | "version": "1.1.0", 4 | "description": "Babel Plugin to enable relative root-import", 5 | "author": "Arunoda Susiripala ", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "files": [ 9 | "index.js", 10 | "build" 11 | ], 12 | "repository": "mantrajs/babel-root-slash-import", 13 | "scripts": { 14 | "test": "mocha test/*.spec.js --require config/mocha.js --compilers js:babel-core/register", 15 | "test-watch": "mocha test/*.spec.js --require config/mocha.js --compilers js:babel-core/register --watch", 16 | "lint-js": "eslint plugin", 17 | "compile": "babel -d build/ plugin/" 18 | }, 19 | "dependencies": { 20 | "babel": "^6.1.18" 21 | }, 22 | "devDependencies": { 23 | "babel-core": "^6.2.1", 24 | "babel-eslint": "^4.0.6", 25 | "babel-cli": "6.x.x", 26 | "babel-preset-es2015": "^6.1.18", 27 | "babel-preset-stage-1": "^6.1.18", 28 | "chai": "^3.2.0", 29 | "eslint": "^1.1.0", 30 | "mocha": "^2.2.5", 31 | "sinon": "^1.15.4" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/plugin.spec.js: -------------------------------------------------------------------------------- 1 | import BabelRootImportPlugin from '../plugin'; 2 | import * as babel from 'babel-core'; 3 | 4 | describe('Babel Root Import - Plugin', () => { 5 | describe('Babel Plugin', () => { 6 | it('transforms the relative path into an absolute path', () => { 7 | const targetRequire = `${process.cwd()}/some/example.js`; 8 | const transformedCode = babel.transform("import SomeExample from '/some/example.js';", { 9 | plugins: [BabelRootImportPlugin] 10 | }); 11 | 12 | expect(transformedCode.code).to.contain(targetRequire); 13 | }); 14 | 15 | it('transforms the relative path into an absolute path with the configured root-path', () => { 16 | const targetRequire = `some/custom/root/some/example.js`; 17 | const transformedCode = babel.transform("import SomeExample from '/some/example.js';", { 18 | plugins: [[ 19 | BabelRootImportPlugin, { 20 | rootPathSuffix: 'some/custom/root' 21 | } 22 | ]] 23 | }); 24 | 25 | expect(transformedCode.code).to.contain(targetRequire); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Michael J. Zoidl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /plugin/index.js: -------------------------------------------------------------------------------- 1 | import BabelRootImportHelper from './helper'; 2 | 3 | export default function({ types: t }) { 4 | class BabelRootImport { 5 | constructor() { 6 | const that = this; 7 | return { 8 | visitor: { 9 | ImportDeclaration(path, state) { 10 | const givenPath = path.node.source.value; 11 | 12 | var rootPathSuffix = state && state.opts && typeof state.opts.rootPathSuffix === 'string' ? 13 | '/' + state.opts.rootPathSuffix.replace(/^(\/)|(\/)$/g, '') : 14 | ''; 15 | 16 | if(BabelRootImportHelper().hasRoot(givenPath)) { 17 | path.node.source.value = BabelRootImportHelper().transformRelativeToRootPath(givenPath, rootPathSuffix); 18 | } 19 | } 20 | } 21 | }; 22 | } 23 | } 24 | 25 | // Here's we detect the use of Meteor and send a dummy plugin. 26 | // That's because, Meteor already do this for us. 27 | // global.meteorBabelHelpers is something we can see when 28 | // running inside Meteor. 29 | if (global.meteorBabelHelpers) { 30 | return { 31 | visitor: {} 32 | }; 33 | } 34 | 35 | return new BabelRootImport(); 36 | } 37 | -------------------------------------------------------------------------------- /test/helper.spec.js: -------------------------------------------------------------------------------- 1 | import BabelRootImportHelper from '../plugin/helper'; 2 | 3 | describe('Babel Root Import - Helper', () => { 4 | 5 | describe('transformRelativeToRootPath', () => { 6 | it('returns a string', () => { 7 | console.log(BabelRootImportHelper().transformRelativeToRootPath('')); 8 | const func = BabelRootImportHelper().transformRelativeToRootPath(''); 9 | expect(func).to.be.a('string'); 10 | }); 11 | 12 | it('transforms given path relative root-path', () => { 13 | const rootPath = `${process.cwd()}/some/path`; 14 | const result = BabelRootImportHelper().transformRelativeToRootPath('/some/path'); 15 | expect(result).to.equal(rootPath); 16 | }); 17 | 18 | it('throws error if no string is passed', () => { 19 | expect(() => { 20 | BabelRootImportHelper().transformRelativeToRootPath(); 21 | }).to.throw(Error); 22 | }); 23 | }); 24 | 25 | describe('Class', () => { 26 | it('returns the root path', () => { 27 | const rootByProcess = process.cwd(); 28 | expect(BabelRootImportHelper().root).to.equal(rootByProcess); 29 | }); 30 | }); 31 | 32 | describe('transformRelativeToRootPath', () => { 33 | it('returns a string', () => { 34 | const func = BabelRootImportHelper().transformRelativeToRootPath(''); 35 | expect(func).to.be.a('string'); 36 | }); 37 | 38 | it('transforms given path relative root-path', () => { 39 | const rootPath = `${process.cwd()}/some/path`; 40 | const result = BabelRootImportHelper().transformRelativeToRootPath('/some/path'); 41 | expect(result).to.equal(rootPath); 42 | }); 43 | 44 | it('throws error if no string is passed', () => { 45 | expect(() => { 46 | BabelRootImportHelper().transformRelativeToRootPath(); 47 | }).to.throw(Error); 48 | }); 49 | }); 50 | 51 | 52 | describe('hasRoot', () => { 53 | it('returns a boolean', () => { 54 | const func = BabelRootImportHelper().hasRoot(); 55 | expect(func).to.be.a('boolean'); 56 | }); 57 | 58 | it('check if the string has "/" at the beginning', () => { 59 | const withRoot = BabelRootImportHelper().hasRoot('/path'); 60 | const withoutRoot = BabelRootImportHelper().hasRoot('./some/path'); 61 | expect(withoutRoot).to.be.false; 62 | expect(withRoot).to.be.true; 63 | }); 64 | 65 | it('returns false if no string passed', () => { 66 | const nothingPassed = BabelRootImportHelper().hasRoot(); 67 | const wrongTypePassed = BabelRootImportHelper().hasRoot([]); 68 | expect(nothingPassed).to.be.false; 69 | expect(wrongTypePassed).to.be.false; 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "env": { 4 | "browser": true, 5 | "node": true 6 | }, 7 | "ecmaFeatures": { 8 | "arrowFunctions": true, 9 | "blockBindings": true, 10 | "classes": true, 11 | "defaultParams": true, 12 | "destructuring": true, 13 | "forOf": true, 14 | "generators": false, 15 | "modules": true, 16 | "objectLiteralComputedProperties": true, 17 | "objectLiteralDuplicateProperties": false, 18 | "objectLiteralShorthandMethods": true, 19 | "objectLiteralShorthandProperties": true, 20 | "spread": true, 21 | "superInFunctions": true, 22 | "templateStrings": true, 23 | "jsx": true 24 | }, 25 | "rules": { 26 | /** 27 | * Strict mode 28 | */ 29 | // babel inserts "use strict"; for us 30 | // http://eslint.org/docs/rules/strict 31 | "strict": [2, "never"], 32 | 33 | /** 34 | * ES6 35 | */ 36 | "no-var": 2, // http://eslint.org/docs/rules/no-var 37 | "prefer-const": 2, // http://eslint.org/docs/rules/prefer-const 38 | 39 | /** 40 | * Variables 41 | */ 42 | "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow 43 | "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names 44 | "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars 45 | "vars": "local", 46 | "args": "after-used" 47 | }], 48 | "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define 49 | 50 | /** 51 | * Possible errors 52 | */ 53 | "comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle 54 | "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign 55 | "no-console": 1, // http://eslint.org/docs/rules/no-console 56 | "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger 57 | "no-alert": 1, // http://eslint.org/docs/rules/no-alert 58 | "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition 59 | "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys 60 | "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case 61 | "no-empty": 2, // http://eslint.org/docs/rules/no-empty 62 | "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign 63 | "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast 64 | "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi 65 | "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign 66 | "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations 67 | "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp 68 | "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace 69 | "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls 70 | "no-reserved-keys": 2, // http://eslint.org/docs/rules/no-reserved-keys 71 | "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays 72 | "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable 73 | "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan 74 | "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var 75 | 76 | /** 77 | * Best practices 78 | */ 79 | "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return 80 | "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly 81 | "default-case": 2, // http://eslint.org/docs/rules/default-case 82 | "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation 83 | "allowKeywords": true 84 | }], 85 | "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq 86 | "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in 87 | "no-caller": 2, // http://eslint.org/docs/rules/no-caller 88 | "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return 89 | "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null 90 | "no-eval": 2, // http://eslint.org/docs/rules/no-eval 91 | "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native 92 | "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind 93 | "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough 94 | "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal 95 | "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval 96 | "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks 97 | "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func 98 | "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str 99 | "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign 100 | "no-new": 2, // http://eslint.org/docs/rules/no-new 101 | "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func 102 | "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers 103 | "no-octal": 2, // http://eslint.org/docs/rules/no-octal 104 | "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape 105 | "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign 106 | "no-proto": 2, // http://eslint.org/docs/rules/no-proto 107 | "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare 108 | "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign 109 | "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url 110 | "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare 111 | "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences 112 | "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal 113 | "no-with": 2, // http://eslint.org/docs/rules/no-with 114 | "radix": 2, // http://eslint.org/docs/rules/radix 115 | "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top 116 | "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife 117 | "yoda": 2, // http://eslint.org/docs/rules/yoda 118 | 119 | /** 120 | * Style 121 | */ 122 | "indent": [2, 2], // http://eslint.org/docs/rules/ 123 | "brace-style": [2, // http://eslint.org/docs/rules/brace-style 124 | "1tbs", { 125 | "allowSingleLine": true 126 | }], 127 | "quotes": [ 128 | 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes 129 | ], 130 | "camelcase": [2, { // http://eslint.org/docs/rules/camelcase 131 | "properties": "never" 132 | }], 133 | "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing 134 | "before": false, 135 | "after": true 136 | }], 137 | "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style 138 | "eol-last": 2, // http://eslint.org/docs/rules/eol-last 139 | "func-names": 1, // http://eslint.org/docs/rules/func-names 140 | "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing 141 | "beforeColon": false, 142 | "afterColon": true 143 | }], 144 | "new-cap": [2, { // http://eslint.org/docs/rules/new-cap 145 | "newIsCap": true 146 | }], 147 | "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines 148 | "max": 2 149 | }], 150 | "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary 151 | "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object 152 | "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func 153 | "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces 154 | "no-wrap-func": 2, // http://eslint.org/docs/rules/no-wrap-func 155 | "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle 156 | "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var 157 | "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks 158 | "semi": [2, "always"], // http://eslint.org/docs/rules/semi 159 | "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing 160 | "before": false, 161 | "after": true 162 | }], 163 | "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords 164 | "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks 165 | "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren 166 | "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops 167 | "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case 168 | "spaced-line-comment": 2, // http://eslint.org/docs/rules/spaced-line-comment 169 | } 170 | } 171 | --------------------------------------------------------------------------------