babel-plugin-transform-imports
Advanced tools
Comparing version 1.4.1 to 1.5.0
66
index.js
var types = require('babel-types'); | ||
var isValidPath = require('is-valid-path'); | ||
var camel = require('lodash.camelcase'); | ||
var findKey = require('lodash.findkey'); | ||
var kebab = require('lodash.kebabcase'); | ||
@@ -7,2 +9,38 @@ var snake = require('lodash.snakecase'); | ||
function findOptionFromSource(source, state) { | ||
var opts = state.opts; | ||
if (opts[source]) return source; | ||
var opt = findKey(opts, function (o, _opt) { | ||
return !isValidPath(_opt) && new RegExp(_opt).test(source); | ||
}); | ||
if (opt) return opt; | ||
var isRelativePath = source.match(/^\.{0,2}\//); | ||
// This block handles relative paths, such as ./components, ../../components, etc. | ||
if (isRelativePath) { | ||
var _source = pathLib.resolve(pathLib.join( | ||
source[0] === '/' ? '' : pathLib.dirname(state.file.opts.filename), | ||
source | ||
)); | ||
if (opts[_source]) { | ||
return _source; | ||
} | ||
} | ||
} | ||
function getMatchesFromSource(opt, source) { | ||
var regex = new RegExp(opt, 'g'); | ||
var matches = []; | ||
var m; | ||
while ((m = regex.exec(source)) !== null) { | ||
if (m.index === regex.lastIndex) regex.lastIndex++; | ||
m.forEach(function(match) { | ||
matches.push(match); | ||
}); | ||
} | ||
return matches; | ||
} | ||
function barf(msg) { | ||
@@ -12,3 +50,3 @@ throw new Error('babel-plugin-transform-imports: ' + msg); | ||
function transform(transformOption, importName) { | ||
function transform(transformOption, importName, matches) { | ||
var isFunction = typeof transformOption === 'function'; | ||
@@ -28,6 +66,9 @@ if (/\.js$/i.test(transformOption) || isFunction) { | ||
return transformFn(importName); | ||
return transformFn(importName, matches); | ||
} | ||
return transformOption.replace(/\$\{\s?member\s?\}/ig, importName); | ||
return transformOption.replace(/\$\{\s?([\w\d]*)\s?\}/ig, function(str, g1) { | ||
if (g1 === 'member') return importName; | ||
return matches[g1]; | ||
}); | ||
} | ||
@@ -47,13 +88,8 @@ | ||
// This block handles relative paths, such as ./components, ../../components, etc. | ||
if (!(source in state.opts) && source.match(/^\.{0,2}\//)) { | ||
source = pathLib.resolve(pathLib.join( | ||
source[0] === '/' ? '' : pathLib.dirname(state.file.opts.filename), | ||
source | ||
)); | ||
} | ||
var opt = findOptionFromSource(source, state); | ||
var isRegexp = opt && !isValidPath(opt); | ||
var opts = state.opts[opt]; | ||
var hasOpts = !!opts; | ||
if (source in state.opts) { | ||
var opts = state.opts[source]; | ||
if (hasOpts) { | ||
if (!opts.transform) { | ||
@@ -87,2 +123,4 @@ barf('transform option is required for module ' + source); | ||
var matches = isRegexp ? getMatchesFromSource(opt, source) : []; | ||
memberImports.forEach(function(memberImport) { | ||
@@ -105,3 +143,3 @@ // Examples of member imports: | ||
var replace = transform(opts.transform, importName); | ||
var replace = transform(opts.transform, importName, matches); | ||
@@ -108,0 +146,0 @@ var newImportSpecifier = (opts.skipDefaultConversion) |
{ | ||
"name": "babel-plugin-transform-imports", | ||
"version": "1.4.1", | ||
"version": "1.5.0", | ||
"description": "Transforms member style imports (import {x} from 'y') into default style imports (import x from 'y/lib/x')", | ||
@@ -25,3 +25,5 @@ "keywords": [ | ||
"babel-types": "^6.6.0", | ||
"is-valid-path": "^0.1.1", | ||
"lodash.camelcase": "^4.3.0", | ||
"lodash.findkey": "^4.6.0", | ||
"lodash.kebabcase": "^4.1.1", | ||
@@ -28,0 +30,0 @@ "lodash.snakecase": "^4.1.1" |
@@ -89,10 +89,10 @@ # babel-plugin-transform-imports | ||
In cases where the provided default string replacement transformation is not | ||
sufficient (for example, needing to execute a RegExp on the import name), you | ||
may instead provide a path to a .js file which exports a function to run | ||
instead. Keep in mind that the .js file will be `require`d relative from this | ||
plugin's path, likely located in `/node_modules/babel-plugin-transform-imports`. | ||
You may provide any filename, as long as it ends with `.js`. | ||
### Using regular expressions | ||
Sometimes you may enforce the same convention in all folder levels on the | ||
structure of your libraries. For achieving this dynamism, you may use regexp | ||
to cover all tranformations. | ||
.babelrc: | ||
```json | ||
@@ -102,2 +102,42 @@ { | ||
["transform-imports", { | ||
"my-library\/?(((\\w*)?\/?)*)": { | ||
"transform": "my-library/${1}/${member}", | ||
"preventFullImport": true | ||
} | ||
}] | ||
] | ||
} | ||
``` | ||
For instance, the previous configuration will solve properly the next scenarios: | ||
```javascript | ||
import { MyModule } from 'my-library'; | ||
import { App } from 'my-library/components'; | ||
import { Header, Footer } from 'my-library/components/App'; | ||
``` | ||
becomes: | ||
```javascript | ||
import MyModule from 'my-library/MyModule'; | ||
import App from 'my-library/components/App'; | ||
import Header from 'my-library/components/App/Header'; | ||
import Footer from 'my-library/components/App/Footer'; | ||
``` | ||
### Using a transformation file | ||
If you need more advanced transformation logic, you may provide a path to a .js | ||
file which exports a function to run instead. Keep in mind that the .js file | ||
will be `require`d relative from this plugin's path, likely located in | ||
`/node_modules/babel-plugin-transform-imports`. You may provide any filename, | ||
as long as it ends with `.js`. | ||
.babelrc: | ||
```json | ||
{ | ||
"plugins": [ | ||
["transform-imports", { | ||
"my-library": { | ||
@@ -113,4 +153,5 @@ "transform": "../../path/to/transform.js", | ||
/path/to/transform.js: | ||
```js | ||
module.exports = function(importName) { | ||
module.exports = function(importName, matches) { | ||
return 'my-library/etc/' + importName.toUpperCase(); | ||
@@ -133,4 +174,3 @@ }; | ||
module: { | ||
rules: [ | ||
{ | ||
rules: [{ | ||
test: /\.js$/, | ||
@@ -140,17 +180,16 @@ exclude: /(node_modules|bower_components)/, | ||
loader: 'babel-loader', | ||
query: { | ||
plugins: [ | ||
[require('babel-plugin-transform-imports'), { | ||
"my-library": { | ||
"transform": function(importName) { | ||
return 'my-library/etc/' + importName.toUpperCase(); | ||
}, | ||
preventFullImport: true | ||
} | ||
}] | ||
] | ||
} | ||
query: { | ||
plugins: [ | ||
[require('babel-plugin-transform-imports'), { | ||
"my-library": { | ||
"transform": function(importName) { | ||
return 'my-library/etc/' + importName.toUpperCase(); | ||
}, | ||
preventFullImport: true | ||
} | ||
}] | ||
] | ||
} | ||
} | ||
] | ||
}] | ||
} | ||
@@ -163,3 +202,3 @@ ``` | ||
| --- | --- | --- | --- | --- | | ||
| `transform` | `string` | yes | `undefined` | The library name to use instead of the one specified in the import statement. ${member} will be replaced with the member, aka Grid/Row/Col/etc. Alternatively, pass a path to a .js file which exports a function to process the transform (see Advanced Transformations) | | ||
| `transform` | `string` | yes | `undefined` | The library name to use instead of the one specified in the import statement. ${member} will be replaced with the import name, aka Grid/Row/Col/etc., and ${1-n} will be replaced by any matched regular expression groups. Alternatively, pass a path to a .js file which exports a function to process the transform, which is invoked with parameters: (importName, matches). (see Advanced Transformations) | | ||
| `preventFullImport` | `boolean` | no | `false` | Whether or not to throw when an import is encountered which would cause the entire module to be imported. | | ||
@@ -166,0 +205,0 @@ | `camelCase` | `boolean` | no | `false` | When set to true, runs ${member} through _.camelCase. | |
@@ -70,2 +70,20 @@ import assert from 'assert'; | ||
}); | ||
it('should handle relative files with regex expressions', function() { | ||
const libraryName = '((\.{1,2}\/?)*)\/local\/path'; | ||
const _transform = '${1}/local/path/${member}'; | ||
const options = createOptions({ libraryName, transform: _transform }) | ||
const code = transform(`import { LocalThing } from '../../local/path'`, options); | ||
assert.equal(/require\('\.\.\/\.\.\/local\/path\/LocalThing'\);$/m.test(code), true, 'regex is transformed'); | ||
}); | ||
it('should handle regex expressions', function() { | ||
const libraryName = 'package-(\\w+)\/?(((\\w*)?\/?)*)'; | ||
const _transform = 'package-${1}/${2}/${member}'; | ||
const options = createOptions({ libraryName, transform: _transform }) | ||
const code = transform(`import { LocalThing } from 'package-one/local/path'`, options); | ||
assert.equal(/require\('package-one\/local\/path\/LocalThing'\);$/m.test(code), true, 'regex is transformed'); | ||
}); | ||
}); | ||
@@ -72,0 +90,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21985
268
203
6
+ Addedis-valid-path@^0.1.1
+ Addedlodash.findkey@^4.6.0
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-invalid-path@0.1.0(transitive)
+ Addedis-valid-path@0.1.1(transitive)
+ Addedlodash.findkey@4.6.0(transitive)