UNPKG

eslint-import-resolver-babel-root-import-fixed

Version:

babel-plugin-root-import resolver for eslint-plugin-import

129 lines (108 loc) 4.41 kB
const path = require('path'); const fs = require('fs'); const JSON5 = require('json5'); const nodeResolve = require('eslint-import-resolver-node').resolve; /* eslint-disable no-console */ const babelRootImport = require('babel-root-import/build/helper.js'); // newer version of babel root import exports the 2 functions // but older versions exported a class /* eslint-disable new-cap */ const babelRootImportObj = babelRootImport.default ? new babelRootImport.default() : babelRootImport; const defaultConfig = { rootPathSuffix: '', rootPathPrefix: '~' }; let { hasRootPathPrefixInString, transformRelativeToRootPath } = babelRootImportObj; if (babelRootImport.default) { /* eslint-disable no-console */ hasRootPathPrefixInString = hasRootPathPrefixInString.bind(babelRootImportObj); transformRelativeToRootPath = transformRelativeToRootPath.bind(babelRootImportObj); } function loadBabelConfig(config = {}) { const pluginConfig = (config.plugins || []).find(p => { if (Array.isArray(p)) { return p[0] === 'babel-plugin-root-import'; } return p === 'babel-plugin-root-import'; }); if (Array.isArray(pluginConfig)) { const paths = Array.isArray(pluginConfig[1]) ? pluginConfig[1] : (pluginConfig[1].paths || pluginConfig[1]); if (Array.isArray(paths)) { return paths.map(conf => Object.assign({}, defaultConfig, conf)); } return [Object.assign({}, defaultConfig, paths)]; } return [defaultConfig]; } // returns the root import config as an object function getConfigFromBabel(start, babelrc = '.babelrc') { if (start === '/') return []; const packageJSONPath = path.join(start, 'package.json'); const packageJSON = require(packageJSONPath); // eslint-disable-line global-require const babelConfig = packageJSON.babel; if (babelConfig) { const pluginConfig = loadBabelConfig(babelConfig); process.chdir(path.dirname(packageJSONPath)); return pluginConfig; } const babelrcPath = path.join(start, babelrc); if (fs.existsSync(babelrcPath)) { const babelrcJson = JSON5.parse(fs.readFileSync(babelrcPath, 'utf8')); if (babelrcJson) { const pluginConfig = loadBabelConfig(babelrcJson); // The src path inside babelrc are from the root so we have // to change the working directory for the same directory // to make the mapping to work properly process.chdir(path.dirname(babelrcPath)); return pluginConfig; } } return getConfigFromBabel(path.dirname(start)); } exports.interfaceVersion = 2; /** * Find the full path to 'source', given 'file' as a full reference path. * * resolveImport('./foo', '/Users/ben/bar.js') => '/Users/ben/foo.js' * @param {string} source - the module to resolve; i.e './some-module' * @param {string} file - the importing file's full path; i.e. '/usr/local/bin/file.js' * @param {object} config - the resolver options * @param {string} babelrc - the name of the babelrc file * @return {object} */ exports.resolve = (source, file, config, babelrc) => { const opts = getConfigFromBabel(process.cwd(), babelrc); // [{rootPathPrefix: rootPathSuffix}] const rootPathConfig = []; if (Array.isArray(opts)) { opts.forEach((option) => { let prefix = ''; if (option.rootPathPrefix && typeof option.rootPathPrefix === 'string') { prefix = option.rootPathPrefix; } let suffix = ''; if (option.rootPathSuffix && typeof option.rootPathSuffix === 'string') { suffix = `/${option.rootPathSuffix.replace(/^(\/)|(\/)$/g, '')}`; } rootPathConfig.push({ rootPathPrefix: prefix, rootPathSuffix: suffix }); }); } let transformedSource = source; for (let i = 0; i < rootPathConfig.length; i += 1) { const option = rootPathConfig[i]; const prefix = option.rootPathPrefix; const suffix = option.rootPathSuffix; if (hasRootPathPrefixInString(source, option.rootPathPrefix)) { transformedSource = transformRelativeToRootPath(source, suffix, prefix); break; } } return nodeResolve(transformedSource, file, config); };