-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: Refactor normalizeOptions and the resolver pipeline (#159)
* Extract normalizeOptions from index.js * Use the same signature for the resolvers and simplify the pipeline * Add types to the state instead of passing it around * Move visitors out of the exported function * Add more tests documenting the current aliasing behavior
- Loading branch information
Showing
7 changed files
with
175 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,116 +1,26 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
|
||
import findBabelConfig from 'find-babel-config'; | ||
import glob from 'glob'; | ||
import normalizeOptions from './normalizeOptions'; | ||
import transformCall from './transformers/call'; | ||
import transformImport from './transformers/import'; | ||
|
||
|
||
const defaultExtensions = ['.js', '.jsx', '.es', '.es6']; | ||
|
||
function isRegExp(string) { | ||
return string.startsWith('^') || string.endsWith('$'); | ||
} | ||
|
||
function normalizeCwd(file) { | ||
const { opts } = this; | ||
|
||
if (opts.cwd === 'babelrc') { | ||
const startPath = (file.opts.filename === 'unknown') | ||
? './' | ||
: file.opts.filename; | ||
|
||
const { file: babelPath } = findBabelConfig.sync(startPath); | ||
|
||
opts.cwd = babelPath | ||
? path.dirname(babelPath) | ||
: null; | ||
} | ||
|
||
if (!opts.cwd) { | ||
opts.cwd = process.cwd(); | ||
} | ||
} | ||
|
||
function normalizeOptions(file) { | ||
const { opts } = this; | ||
|
||
normalizeCwd.call(this, file); | ||
|
||
if (opts.root) { | ||
if (!Array.isArray(opts.root)) { | ||
opts.root = [opts.root]; | ||
} | ||
opts.root = opts.root | ||
.map(dirPath => path.resolve(opts.cwd, dirPath)) | ||
.reduce((resolvedDirs, absDirPath) => { | ||
if (glob.hasMagic(absDirPath)) { | ||
const roots = glob.sync(absDirPath) | ||
.filter(resolvedPath => fs.lstatSync(resolvedPath).isDirectory()); | ||
|
||
return [...resolvedDirs, ...roots]; | ||
} | ||
|
||
return [...resolvedDirs, absDirPath]; | ||
}, []); | ||
} else { | ||
opts.root = []; | ||
} | ||
|
||
opts.regExps = []; | ||
|
||
if (opts.alias) { | ||
Object.keys(opts.alias) | ||
.filter(isRegExp) | ||
.forEach((key) => { | ||
const parts = opts.alias[key].split('\\\\'); | ||
|
||
function substitute(execResult) { | ||
return parts | ||
.map(part => | ||
part.replace(/\\\d+/g, number => execResult[number.slice(1)] || ''), | ||
) | ||
.join('\\'); | ||
} | ||
|
||
opts.regExps.push([new RegExp(key), substitute]); | ||
|
||
delete opts.alias[key]; | ||
}); | ||
} else { | ||
opts.alias = {}; | ||
} | ||
|
||
if (!opts.extensions) { | ||
opts.extensions = defaultExtensions; | ||
} | ||
|
||
return opts; | ||
} | ||
const importVisitors = { | ||
CallExpression: transformCall, | ||
'ImportDeclaration|ExportDeclaration': transformImport, | ||
}; | ||
|
||
export default ({ types }) => { | ||
const importVisitors = { | ||
CallExpression(nodePath, state) { | ||
transformCall(types, nodePath, state); | ||
}, | ||
ImportDeclaration(nodePath, state) { | ||
transformImport(types, nodePath, state); | ||
}, | ||
ExportDeclaration(nodePath, state) { | ||
transformImport(types, nodePath, state); | ||
const visitor = { | ||
Program: { | ||
exit(programPath, state) { | ||
programPath.traverse(importVisitors, state); | ||
}, | ||
}; | ||
}, | ||
}; | ||
|
||
return { | ||
pre: normalizeOptions, | ||
export default ({ types }) => ({ | ||
pre(file) { | ||
this.types = types; | ||
normalizeOptions(this.opts, file); | ||
}, | ||
|
||
visitor: { | ||
Program: { | ||
exit(programPath, state) { | ||
programPath.traverse(importVisitors, state); | ||
}, | ||
}, | ||
}, | ||
}; | ||
}; | ||
visitor, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
|
||
import findBabelConfig from 'find-babel-config'; | ||
import glob from 'glob'; | ||
|
||
|
||
const defaultExtensions = ['.js', '.jsx', '.es', '.es6']; | ||
|
||
function isRegExp(string) { | ||
return string.startsWith('^') || string.endsWith('$'); | ||
} | ||
|
||
function normalizeCwd(opts, file) { | ||
if (opts.cwd === 'babelrc') { | ||
const startPath = (file.opts.filename === 'unknown') | ||
? './' | ||
: file.opts.filename; | ||
|
||
const { file: babelPath } = findBabelConfig.sync(startPath); | ||
|
||
opts.cwd = babelPath | ||
? path.dirname(babelPath) | ||
: null; | ||
} | ||
|
||
if (!opts.cwd) { | ||
opts.cwd = process.cwd(); | ||
} | ||
} | ||
|
||
function normalizeRoot(opts) { | ||
if (opts.root) { | ||
if (!Array.isArray(opts.root)) { | ||
opts.root = [opts.root]; | ||
} | ||
opts.root = opts.root | ||
.map(dirPath => path.resolve(opts.cwd, dirPath)) | ||
.reduce((resolvedDirs, absDirPath) => { | ||
if (glob.hasMagic(absDirPath)) { | ||
const roots = glob.sync(absDirPath) | ||
.filter(resolvedPath => fs.lstatSync(resolvedPath).isDirectory()); | ||
|
||
return [...resolvedDirs, ...roots]; | ||
} | ||
|
||
return [...resolvedDirs, absDirPath]; | ||
}, []); | ||
} else { | ||
opts.root = []; | ||
} | ||
} | ||
|
||
function normalizeAlias(opts) { | ||
opts.regExps = []; | ||
|
||
if (opts.alias) { | ||
Object.keys(opts.alias) | ||
.filter(isRegExp) | ||
.forEach((key) => { | ||
const parts = opts.alias[key].split('\\\\'); | ||
|
||
function substitute(execResult) { | ||
return parts | ||
.map(part => | ||
part.replace(/\\\d+/g, number => execResult[number.slice(1)] || ''), | ||
) | ||
.join('\\'); | ||
} | ||
|
||
opts.regExps.push([new RegExp(key), substitute]); | ||
|
||
delete opts.alias[key]; | ||
}); | ||
} else { | ||
opts.alias = {}; | ||
} | ||
} | ||
|
||
export default function normalizeOptions(opts, file) { | ||
normalizeCwd(opts, file); // This has to go first because other options rely on cwd | ||
normalizeRoot(opts); | ||
normalizeAlias(opts); | ||
|
||
if (!opts.extensions) { | ||
opts.extensions = defaultExtensions; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { mapPathString } from '../utils'; | ||
|
||
|
||
export default function transformImport(types, nodePath, state) { | ||
mapPathString(types, nodePath.get('source'), state); | ||
export default function transformImport(nodePath, state) { | ||
mapPathString(nodePath.get('source'), state); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.