Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewire alias from outside of root folder? #3

Closed
Elyx0 opened this issue May 11, 2020 · 11 comments
Closed

Rewire alias from outside of root folder? #3

Elyx0 opened this issue May 11, 2020 · 11 comments

Comments

@Elyx0
Copy link

Elyx0 commented May 11, 2020

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@libcommon/*": ["../../shared/common/*"]
    }
  }
}

Is there a way of making it work for imports outside of the current folder? It works on the node side with ts-nodebut in cra not yet..

@oklas
Copy link
Owner

oklas commented May 12, 2020

Thanks for clarification that it is not works by default (it will be cool otherwise as that was with alias inside src). Seems, as far as I remember there additional restrictions to imports outside of project root in react scripts, but I did not analyze that carefully due to it was not necessary that time. I definitely interesting in this question and I would like to see. But currently there is no time for that absolutely. I hope this week make it possible to see.

@JollyGoodHolly
Copy link
Contributor

JollyGoodHolly commented May 26, 2020

@Elyx0 Is your project written in TypeScript? I had the same issue that ESLint could not process my files in an outside directory. I believe the root cause is CRA's ESLint configuration, which has the this override for TypeScript files: ['**/*.ts?(x)']. Because this matches only sub-files of the compiling project, TypeScript files from the other project are interpreted with the standard JavaScript linter, which fails (and is then cached, leading to pollution).

To solve this issue, I tried overriding this override, but ESLint does not support external files and gives this error: Invalid override pattern (expected relative path not containing '..')

Instead, I excluded the external library from the ESLint rule altogether by changing expandRulesInclude like this:

function expandRulesInclude(rules, include, ignoreForEslint) {
  rules.forEach(function (rule) {
    if (rule.include === paths.appSrc && !ignoreForEslint)
      rule.include = include.concat(rule.include)
    if (rule.oneOf)
      expandRulesInclude(rule.oneOf, include, false)
  })
}

My project now works, the only downside is that the external project is now excluded from lint-checking, which probably cannot be fixed.

@oklas Do you think you can implement these changes? To not break the existing behaviour, I also altered the alias function like this:

function alias(aliasMap, ignoreForEslint = false) {
  const aliasLocal = Object.keys(aliasMap).reduce((a, i) => {
    a[i] = path.resolve(paths.appPath, aliasMap[i])
    return a
  }, {})
  return function (config) {
    expandResolveAlias(config.resolve, aliasLocal)
    expandRulesInclude(config.module.rules, Object.values(aliasLocal), ignoreForEslint)
    expandPluginsScope(config.resolve.plugins, Object.values(aliasLocal))
    return config
  }
}

I then called the function in my config-overrides.js with true as the second parameter to fix my problem.

@oklas
Copy link
Owner

oklas commented Jun 3, 2020

@JollyGoodHolly, Some how I can not reproduce the problem with ts source outside of project root dir. Try to use aliasDangerous instead of alias from 0.1.5.

const {aliasDangerous} = require('react-app-rewire-alias/lib/aliasDangerous')

Let me know if the problem is solved or create repo with minimal reproducible example otherwise so I can see with details.

@JollyGoodHolly
Copy link
Contributor

JollyGoodHolly commented Jun 4, 2020

@oklas This almost works, but there is one bug:

- if(rule.use && 0 < rule.use.filter(isRuleOfEslint)) return true
+ if(rule.use && 0 < rule.use.filter(isRuleOfEslint).length) return true

Otherwise, this function always returns false. You can easily test it like this:

module.exports = function override(config) {
    const configCopy = JSON.parse(JSON.stringify(config));

    aliasDangerous({
        ...configPaths('tsconfig.paths.json')
    })(config);

    console.log("These should be equivalent:")
    console.log(configCopy.module.rules[1].include);
    console.log(config.module.rules[1].include);

    return config;
}

Also note that you might have cache pollution and need to delete the .cache folder in node_modules. I opened a new PR with the fix for the fix and some documentation.

@oklas
Copy link
Owner

oklas commented Jun 5, 2020

I suggests introduce restriction to paths outside of root for base alias due to

  • may affect confusions in different node_modules which affect problems on buildtime or runtime, problems will seems like bugs in actually not related modules (like babel or webpack etc) (however it is also possible to fire in aliases placed in the root folder too, but it is a reason anyway)
  • requires additional arrangement on upper folder which is not in responsibility of package uses alias (root project folder)
  • may become not worked due to same restrictions in another systems (like react-scripts and eslint etc) due to they are modified or added some restrictions else
  • in many cases this feature (alias to upper folder) not required

So base alias will not supports aliases from outside of project root folder. To use aliases from outside of root folder (if possible) here will be special implementation alaisDangerous

Implmentation of alaisDangerous will use code from base alias but not vice versa. The base alias must not use and must not import or require code from alaisDangerous.

@oklas oklas changed the title Rewire alias from outside of src? Rewire alias from outside of root folder? Jun 5, 2020
@tobloef
Copy link

tobloef commented Aug 13, 2020

Just for clarification, does this mean that the line "provided fully functional aliases and allows the use of Babel, JSX, etc. outside of src" in the README is false at the moment or am I misunderstanding?

For context, I'm trying to create an alias to a folder outside my React project folder in a monorepo and I can't seem to get it to work. What I would like to do is something like '@shared': '../shared/src' but my files inside shared still can't be resolved from the React app.

@edolix
Copy link

edolix commented Nov 13, 2020

@tobloef were you be able to have React resolve the '@shared': '../shared/src' package? Thanks!

@oklas
Copy link
Owner

oklas commented Nov 21, 2020

Hi, @tobloef, @edolix, if problem relevant create-react-app or react-scripts v4.0 please track or submit #9.

I rewrite and simplify docs to show what need to do for these days to make it worked (instead of which files and options are exists and its possible values). I also added an example project it works - check it 🚴‍♂️ (it uses temporary patch - read #9). Feel free to ask. Subscribe to twitter for a news.👍

@diegoaraujolima
Copy link

I try aliasDangerous, but, on require:

const {aliasDangerous} = require('react-app-rewire-alias/lib/aliasDangerous')

causes error:

function expandRulesInclude(rules, include) {
^

SyntaxError: Identifier 'expandRulesInclude' has already been declared
at wrapSafe (internal/modules/cjs/loader.js:931:16)
at Module._compile (internal/modules/cjs/loader.js:979:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
at Module.load (internal/modules/cjs/loader.js:879:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
at Module.require (internal/modules/cjs/loader.js:903:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object. (C:\Desenvolvimento\Git\JavaScript\projetos\pdvsuite\web\node_modules\react-app-rewire-alias\lib\aliasDangerous.js:1:18)
at Module._compile (internal/modules/cjs/loader.js:1015:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)

@diegoaraujolima
Copy link

diegoaraujolima commented Feb 7, 2021

Ok, i remove the duplicate method aliasDangerous.js, but now the error returns:

Module not found: You attempted to import C:\Desenvolvimento\Git\JavaScript\projetos\pdvsuite\web\framework/Componentes/Botoes/BotaoAdicionar which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.

"\framework" is a simbolic link (Windows), but if i try with the relative path de same error occour.

I use:

const {aliasDangerous} = require('react-app-rewire-alias/lib/aliasDangerous')
module.exports = function override(config) {
  return aliasDangerous({
    framework: 'framework',
  })(config)
}

The problem occour if i use a full or relative path to a outside directory of root.

@oklas
Copy link
Owner

oklas commented Sep 28, 2021

Released v1.1.0 (available for craco and react-app-rewired)


image

image

@oklas oklas closed this as completed Sep 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants