Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions lib/helpers/create-fixer.js

This file was deleted.

74 changes: 41 additions & 33 deletions lib/rules/use-alias.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const babel = require('@babel/core')
const path = require('path')
const fs = require('fs')
const { resolvePath } = require('babel-plugin-module-resolver')

const checkIgnoreDepth = require('../helpers/check-ignore-depth')
const findProjectRoot = require('../helpers/find-project-root')
const getProperties = require('../helpers/get-properties')
const createFixer = require('../helpers/create-fixer')

const values = Object.values || ((obj) => Object.keys(obj).map((e) => obj[e]))
const checkPath = (path, ext) => fs.existsSync(`${path}${ext}`) || fs.existsSync(`${path}/index${ext}`)

module.exports = {
Expand Down Expand Up @@ -72,7 +71,7 @@ module.exports = {
return plugin
}
})
alias = moduleResolver.options.alias || {}
alias = moduleResolver.options.alias
} catch (error) {
const message = 'Unable to find config for babel-plugin-module-resolver'
return {
Expand All @@ -85,11 +84,14 @@ module.exports = {
}
}

// Build array of alias paths.
// Resolve alias paths.
const cwd = projectRootAbsolutePath || process.cwd()
const aliasPaths = values(alias).map((a) => path.join(cwd, a))
const resolvedAlias = Object.fromEntries(
Object.entries(alias).map(([aliasName, aliasPath]) => [aliasName, path.join(cwd, aliasPath)]),
)

const hasError = (val) => {
const run = ({ node, source }) => {
const val = source.value
if (!val) return false // template literals will have undefined val

const { ignoreDepth, projectRoot, extensions, allowDepthMoreOrLessThanEquality } = options
Expand All @@ -99,58 +101,64 @@ module.exports = {

// Error if projectRoot option specified but cannot be resolved.
if (projectRoot && !projectRootAbsolutePath) {
return {
suggestFix: false,
return context.report({
node,
message: 'Invalid project root specified',
}
loc: source.loc,
})
}

const resolvedPath = path.resolve(filePath, val)
const containedAlias = Object.keys(resolvedAlias).find((name) => val.startsWith(name)) //new Regex(`^${alias}(\\/|$)`).test(val))
const resolvedPath = containedAlias
? val.replace(containedAlias, resolvedAlias[containedAlias])
: path.resolve(filePath, val)
const [insideAlias] =
Object.entries(resolvedAlias).find(([aliasName, aliasPath]) => resolvedPath.startsWith(aliasPath)) || []
const resolvedExt = path.extname(val) ? '' : '.js'
const isSubpath = resolvedPath.startsWith(filePath)

let pathExists = checkPath(resolvedPath, resolvedExt)

if (extensions && !pathExists) {
pathExists = extensions.filter((ext) => checkPath(resolvedPath, ext)).length
}

const isAliased = aliasPaths.some((aliasPath) => resolvedPath.includes(aliasPath))

const error = isAliased && pathExists && val.match(/\.\.\//) // matches, exists, and starts with ../,
return error && { suggestFix: true, message: 'Do not use relative path for aliased modules' }
}

const reportError = ({ node, source, error }) => {
context.report({
node,
message: error.message,
loc: source.loc,
fix: error.suggestFix && createFixer({ alias, filePath, cwd, node }),
})
if (insideAlias && pathExists && val.match(/\.\.\//)) {
// matches, exists, and starts with ../,
const newPath = resolvedPath.replace(resolvedAlias[insideAlias], '')
const replacement = path.join(insideAlias, newPath).replace(/\\/g, '/')
context.report({
node,
message: 'Do not use relative path for aliased modules',
loc: source.loc,
fix: (fixer) => fixer.replaceTextRange([source.range[0] + 1, source.range[1] - 1], replacement),
})
} else if (containedAlias && isSubpath) {
const replacement = resolvePath(val, filename, { alias })
context.report({
node,
message: 'Do not use aliased path for subpath import',
loc: source.loc,
fix: (fixer) => fixer.replaceTextRange([source.range[0] + 1, source.range[1] - 1], replacement),
})
}
}

return {
ImportDeclaration(node) {
const error = hasError(node.source.value)
if (error) {
reportError({ node, source: node.source, error })
}
run({ node, source: node.source })
},
CallExpression(node) {
const val = node.callee.name || node.callee.type
if (val === 'Import' || val === 'require') {
const error = hasError(node.arguments[0].value)
error && reportError({ node, source: node.arguments[0], error })
run({ node, source: node.arguments[0] })
}
},
ImportExpression(node) {
// dynamic import was erroneously using visitorKey for
// call expressions https://github.com/babel/babel/pull/10828
// adding ImportExpression for new versions of @babel/eslint-parser
const error = hasError(node.source.value)
if (error) {
reportError({ node, source: node.source, error })
}
run({ node, source: node.source })
},
}
},
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
"regenerator-runtime": "^0.13.3",
"rimraf": "^3.0.0"
},
"license": "MIT"
"license": "MIT",
"dependencies": {
"babel-plugin-module-resolver": "^4.1.0"
}
}
11 changes: 0 additions & 11 deletions tests/helpers/create-fixer.test.js

This file was deleted.

54 changes: 40 additions & 14 deletions tests/lib/rules/use-alias.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,17 @@ describe('with babel config', () => {

ruleTester.run('module-resolver', rule, {
valid: [
"require('actions/api')",
"require('reducers/api')",
"require('ClientMain/api')",
"const { api } = require('actions/api')",
"const { api } = require('reducers/api')",
"import('actions/api')",
"import('reducers/api')",
{ code: "require('actions/api')", filename: `${projectRoot}/src/index.js` },
{ code: "require('reducers/api')", filename: `${projectRoot}/src/index.js` },
{ code: "const { api } = require('actions/api')", filename: `${projectRoot}/src/index.js` },
{ code: "const { api } = require('reducers/api')", filename: `${projectRoot}/src/index.js` },
{ code: "import('actions/api')", filename: `${projectRoot}/src/index.js` },
{ code: "import('reducers/api')", filename: `${projectRoot}/src/index.js` },
'import(`${buildPath}/dist`)',
"import { api } from 'actions/api'",
"import { api } from 'reducers/api'",
"const { api } = dynamic(import('actions/api'))",
"const { api } = dynamic(import('reducers/api'))",
{ code: "import { api } from 'actions/api'", filename: `${projectRoot}/src/index.js` },
{ code: "import { api } from 'reducers/api'", filename: `${projectRoot}/src/index.js` },
{ code: "const { api } = dynamic(import('actions/api'))", filename: `${projectRoot}/src/index.js` },
{ code: "const { api } = dynamic(import('reducers/api'))", filename: `${projectRoot}/src/index.js` },
'const { server } = require(`${buildPath}/dist`)',
"const { api } = require('./actions/api')",
"const { api } = require('./reducers/api')",
Expand All @@ -101,12 +100,20 @@ describe('with babel config', () => {
],

invalid: [
createInvalid({ code: "require('../actions/api')", type: 'CallExpression', output: "require('actions/api')" }),
createInvalid({ code: "require('../reducers/api')", type: 'CallExpression', output: "require('reducers/api')" }),
createInvalid({
code: "require('../actions/api')",
type: 'CallExpression',
output: "require('actions/api')",
}),
createInvalid({
code: "require('../reducers/api')",
type: 'CallExpression',
output: "require('reducers/api')",
}),
createInvalid({
code: "import('../../actions/api')",
type: 'ImportExpression',
filename: `${projectRoot}/src/client/index.js`,
type: 'ImportExpression',
output: "import('actions/api')",
}),
createInvalid({
Expand All @@ -115,6 +122,25 @@ describe('with babel config', () => {
filename: `${projectRoot}/src/client/index.js`,
output: "import('reducers/api')",
}),
createInvalid({
code: "import('./../actions/api')",
type: 'ImportExpression',
output: "import('actions/api')",
}),
createInvalid({
code: "import 'actions/api'",
filename: `${projectRoot}/index.js`,
type: 'ImportDeclaration',
output: "import './actions/api'",
errorMessage: 'Do not use aliased path for subpath import',
}),
createInvalid({
code: "import 'actions/api'",
filename: `${projectRoot}/actions/index.js`,
type: 'ImportDeclaration',
output: "import './api'",
errorMessage: 'Do not use aliased path for subpath import',
}),
createInvalid({
code: "const { api } = dynamic(import('../actions/api'))",
type: 'ImportExpression',
Expand Down
57 changes: 55 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1533,6 +1533,17 @@ babel-plugin-jest-hoist@^26.6.2:
"@types/babel__core" "^7.0.0"
"@types/babel__traverse" "^7.0.6"

babel-plugin-module-resolver@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz#22a4f32f7441727ec1fbf4967b863e1e3e9f33e2"
integrity sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==
dependencies:
find-babel-config "^1.2.0"
glob "^7.1.6"
pkg-up "^3.1.0"
reselect "^4.0.0"
resolve "^1.13.1"

babel-preset-current-node-syntax@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
Expand Down Expand Up @@ -2632,13 +2643,28 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"

find-babel-config@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2"
integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==
dependencies:
json5 "^0.5.1"
path-exists "^3.0.0"

find-up@^2.0.0, find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
dependencies:
locate-path "^2.0.0"

find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
dependencies:
locate-path "^3.0.0"

find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
Expand Down Expand Up @@ -2798,7 +2824,7 @@ glob-parent@^5.0.0, glob-parent@~5.1.0:
dependencies:
is-glob "^4.0.1"

glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
Expand Down Expand Up @@ -3968,6 +3994,14 @@ locate-path@^2.0.0:
p-locate "^2.0.0"
path-exists "^3.0.0"

locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
dependencies:
p-locate "^3.0.0"
path-exists "^3.0.0"

locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
Expand Down Expand Up @@ -4364,7 +4398,7 @@ p-limit@^1.1.0:
dependencies:
p-try "^1.0.0"

p-limit@^2.2.0:
p-limit@^2.0.0, p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
Expand All @@ -4378,6 +4412,13 @@ p-locate@^2.0.0:
dependencies:
p-limit "^1.1.0"

p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
dependencies:
p-limit "^2.0.0"

p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
Expand Down Expand Up @@ -4524,6 +4565,13 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"

pkg-up@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5"
integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==
dependencies:
find-up "^3.0.0"

please-upgrade-node@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
Expand Down Expand Up @@ -4817,6 +4865,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==

reselect@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7"
integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==

resolve-cwd@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d"
Expand Down