Giter VIP home page Giter VIP logo

react-app-alias's Introduction

Alias solution for craco or rewired create-react-app

This is more than simple alias. This is also a multi-project src directory. Currently, create-react-app (CRA) does not support more than one src directory in the project. Monorepo, multi-repo and library projects with examples require more than one directory like src.

This is merely an alias and multi-source solution for CRA and this is not a replacement for multi-package management tools like Lerna.

This requires to modify the CRA webpack configuration in runtime (without ejecting) and works with one of:

Npm package Npm downloads Dependency Status Dependency Status Dependency Status

This allows:

  • quality and secure exports from outside src
  • absolute imports
  • any ./directory at root outside of src with Babel/Typescript and all CRA features

This is designed for:

  • monorepo projects
  • multi-repo projects
  • library projects with examples

Advantages over other solutions:

  • provided fully functional aliases and allows the use of Babel, JSX, etc. outside of src (outside of project root may be enbled with special way see the section below)

  • provided fully secure aliases and uses the same module scope plugin from the original create-react-app package for modules (instead of removing it), to minimize the probability of including unwanted code

Installation

yarn add --dev react-app-alias

or

npm install --save-dev react-app-alias

Usage

By default folders for alias may be near to src folder or in it. Outside of project root is implemented in react-app-alias-ex (suffix -ex).

Usage steps:

  • enumerate aliases in jsconfig.paths.json or tsconfig.paths.json
  • include it in jsconfig.json or tsconfig.json
  • enable your favorite any of react-app-rewired or craco
  • apply react-app-alias in config

Enumerate aliases in jsconfig.paths.json or tsconfig.paths.json

Create a separate file jsconfig.paths.json or tsconfig.paths.json, like this:

// jsconfig.paths.json or tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "example/*": ["example/src/*"],
      "@library/*": ["library/src/*"]
    }
  }
}

Add extends section to jsconfig.json or tsconfig.json

The paths section must not be configured directly in jsconfig.json or tsconfig.json, but in a separate extends file mentioned above. Now include this file in extends section, like this:

// jsconfig.json or tsconfig.json
{
  "extends": "./jsconfig.paths.json", // or "./tsconfig.paths.json"
  "compilerOptions": {
    // ...
  }
}

Configure plugin for craco or react-app-rewired

  • react-app-rewired
// config-overrides.js
const {aliasWebpack, aliasJest} = require('react-app-alias')

const options = {} // default is empty for most cases

module.exports = aliasWebpack(options)
module.exports.jest = aliasJest(options)
  • craco
// craco.config.js

const {CracoAliasPlugin} = require('react-app-alias')

const options = {} // default is empty for most cases

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {}
    }
  ]
}

Enable craco or react-app-rewired

  • react-app-rewired

Integrating react-app-rewired into your project is simple (see its documentation): Create config-overrides.js mentioned above, in the project's root directory (the same including the package.json and src directory). Install react-app-rewired

yarn add --dev react-app-rewired
- or -
npm install --save-dev react-app-rewired

and rewrite the package.json like this:

  "scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
+   ... // same way
  }
  • craco

According to craco docs install craco:

yarn add --dev craco
- or -
npm install --save-dev craco

and replace react-scripts in package.json:

  "scripts": {
-   "start": "react-scripts start",
+   "start": "craco start",
+   ... // same way
  }

Using baseUrl

  • baseUrl = '.'

    • able to create alias outside of src (near src)
    • for each directory in src alias does not created automatically (must be declared manually)
  • baseUrl = 'src'

    • alias outside of src is not possible, only in directory specified in baseUrl
    • for each folder in src alias created automatically with same name as folder

See also experimental autoscan feature

Using SWC etc

Alias plugin must be aplied after SWC plugin.

Plugin SWC must be declared in plugin section before alias plugn. This is because SWC plugn recreate SWC configuration instead of babel configuration. Both babel and swc configurations originally without alias configuration. So to configure alias, alias plugin must be aplied after SWC plugin:

const { CracoAliasPlugin } = require('react-app-alias');
const CracoSwcPlugin = require('craco-swc');

module.exports = {
  plugins: [
    { plugin: CracoSwcPlugin },
    { plugin: CracoAliasPlugin },
  ],
}

API

  • options
  Options {
    alias?: { [alias: string]: string }; // optional alias map
    tsconfig?: string, // optional tsconfig.json path
    jsconfig?: string, // optional jsconfig.json path
    baseUrl?: string, // optional by default from config
  }

// optional alias map has following form:
const alias = { example: 'example/src', '@library': 'library/src', }

  • aliasWebpack(options)(webpackConfig)

The function aliasWebpack() accepts aliases declared in form:

const aliasMap = {
  example: 'example/src',
  '@library': 'library/src',
}

const options = {
  alias: aliasMap,
}

module.exports = aliasWebpack(options)
module.exports.jest = aliasJest(options)

To make all things worked, aliases must be declared in jsconfig.json or tsconfig.json. However, it must be declared in a separate extends file (see section Workaround for "aliased imports are not supported" below)

The result is a function which will modify Wepack config

  • configPaths()

The function configPaths() loads paths from file compatible with jsconfig.json or tsconfig.json and returns path in form acceptable for aliasWebpack() function. The tsconfig.json is prioritized over the jsconfig.json in the loading sequence.

const aliasMap = configPaths('./tsconfig.paths.json')

const options = {
  alias: aliasMap,
}

module.exports = aliasWebpack(aliasMap)
  • extendability

As any react-app-rewire or customize-cra rewire extension this can be integrated with another:

module.exports = function override(config) {
  const modifiedConfig = aliasWebpack(...)(config)
  ...
  return someElse(modifiedConfig)
}
module.exports.jest = function override(config) {
  const modifiedConfig = aliasJest(...)(config)
  ...
  return modifiedConfig
}

Workaround for "aliased imports are not supported"

CRA overwrites your tsconfig.json at runtime and removes paths from the tsconfig.json, which is not officially supported, with this message:

The following changes are being made to your tsconfig.json file:
  - compilerOptions.paths must not be set (aliased imports are not supported)

The suggested workaround is to move the paths to a different .json file, e.g. tsconfig.paths.json, like this:

/* tsconfig.paths.json */
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "example/*": ["example/src/*"],
      "@library/*": ["library/src/*"]
    }
  }
}

with that file's subsequent inclusion in the tsconfig.json using extends:

/* tsconfig.json */
{
  "extends": "./tsconfig.paths.json"
}

Outside of root

Alias folders outside of the root of the project currently fully functional and works fine but are not recommended. It may bring hard-to-detect errors.

Alias with support of Outside of root is implemented in separated library:

react-app-alias-ex

with identical API, just install and add suffix -ex in import statement:

- const {aliasWebpack, CracoAliasPlugin} = require('react-app-alias')
+ const {aliasWebpack, CracoAliasPlugin} = require('react-app-alias-ex')

Tips

  • keep only one node_modules directory

Confusions in deps versions may bring unclear errors or problems. For example, an application is not working without any error. Or another example is error in react-router - <Route> component do not see <Router> when actually code is correct and it falls with:

should not use Route or withRouter() outside a Router

This may be a result of some confusion in node_modules folders for multi-repo projects. Same take place in plain create-react-app if somehow one or more additional node_modulest directories appear in src.

To avoid this problem use only one main project node_modules directory.

  • keep away from working with nested project

Default bundler configuration doesn't assume your configuration and may mix deps from node_modules from different projects (top project and nested project) so this may bring mentioned above confusions with deps versions. To avoid problems: do not install and run within nested project directly when it is nested or integrated in another one - but only independent top level configuration Or consider to eject or configure Webpack manually.

  • do not relay to deps versions synchronization

Some libraries use instanceof and other type comparisions. For example , two objects created with the same params in the same code of the same library version but installed in different node_modules and bundled separately - will mostly have the same data and same behaviour but different instance type. Such libraries will be unable to recognize their own objects and will lead to unpredictable behaviour. So use only one main project node_modules directory.

react-app-alias's People

Contributors

alanblanchetneovision avatar andrewgies17 avatar axelboc avatar bryanculver avatar dependabot[bot] avatar jafin avatar jollygoodholly avatar lonerifle avatar mryhchan avatar oklas avatar rajrajhans avatar samdemaeyer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-app-alias's Issues

Error on Mac and Linux when using classes, while on Windows everything is working fine.

config-overrides.js

const { aliasWebpack } = require('react-app-alias-ex')
const path = require('path');

module.exports = function override(config) {
	aliasWebpack({
		alias: {
			'@commonTypes': path.resolve(__dirname, '../../../some-common-types/')
		}
	})(config);

	return config;
}

some-common-types/firstFile.ts

import { ExampleClass } from '@commonTypes/anotherFile'

export class ExportedClass {
  static create() {
    return new ExampleClass();
  }
}

some-common-types/secondFile.ts

export class ExampleClass {
    name: string;
  }

Let's call it inside a React component.

import { ExportedClass } from '@commonTypes/firstFile'

const SomeComponent = (): JSX.Element => {
ExportedClass.create();
...
}

Error

/home/user/Desktop/project/public/dash/node_modules/react-dev-utils/ModuleScopePlugin.js:32
request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
^

TypeError: Cannot read properties of undefined (reading 'indexOf')
at /home/user/Desktop/project/public/dash/node_modules/react-dev-utils/ModuleScopePlugin.js:32:39
at Hook.eval [as callAsync] (eval at create (/home/user/Desktop/project/public/dash/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:52:1)
at Resolver.doResolve (/home/user/Desktop/project/public/dash/node_modules/enhanced-resolve/lib/Resolver.js:432:16)
at /home/user/Desktop/project/public/dash/node_modules/enhanced-resolve/lib/TryNextPlugin.js:32:14
at _next0 (eval at create (/home/user/Desktop/project/public/dash/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:173:1)
at eval (eval at create (/home/user/Desktop/project/public/dash/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:195:1)
at /home/user/Desktop/project/public/dash/node_modules/enhanced-resolve/lib/ConditionalPlugin.js:40:47
at Hook.eval [as callAsync] (eval at create (/home/user/Desktop/project/public/dash/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:187:1)
at Resolver.doResolve (/home/user/Desktop/project/public/dash/node_modules/enhanced-resolve/lib/Resolver.js:432:16)
at /home/user/Desktop/project/public/dash/node_modules/enhanced-resolve/lib/ConditionalPlugin.js:42:14

Cannot resolve `eslint-loader`

Description

When I use the aliasDangerous method I am getting the following error:

internal/modules/cjs/loader.js:883
  throw err;
  ^

Error: Cannot find module 'eslint-loader'
Require stack:

Scenario

I've created a new create-react-app and am using react-app-rewired.
I'm working in a mono-repo style repository that looks like this:

root
    backend
        src
    shared
        src
    web
        src

The reason I am using the dangerous option is that I need the /web codebase to import from shared which contains some utility javascript files.

When I commented out these 2 lines inside of the aliasDangerous file the code worked
image

I was wondering what the purpose of importing eslint-loader is?
If the aliasDangerous.js file has this, why doesnt the non dangerous version code have it ?

Trouble with aliases

I'm having some trouble with aliases after migrating to CRA5 and Craco 7 and using your plugin since the one I was using before has been deprecated. I was wondering if you might help understanding what I've set up wrong since I followed your example and I still having some issues both when running dev and also when running tests.

This is my tsconfig.paths.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "api/*": ["src/api/*"],
      "app/*": ["src/app/*"],
      "assets/*": ["src/assets/*"],
      "components/*": ["src/components/*"],
      "env": ["src/env"],
      "options/*": ["src/options/*"],
      "services": ["src/services"],
      "test/*": ["src/test/*"],
      "utils": ["src/utils"],
      "utils/*": ["src/utils/*"],
      "globalStyle": ["src/globalStyle.ts"],
      "types": ["src/types"],
      "logging": ["src/utils/logging"],
      "directFlow/*": ["src/direct-flow/*"]
    }
  }
}

This is my craco config

const path = require('path')
const { CracoAliasPlugin } = require('react-app-alias')
const SentryPlugin = require('@sentry/webpack-plugin')

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: {},
    },
  ],
  babel: {
    plugins: [
      [
        'babel-plugin-styled-components',
        {
          ssr: false,
          displayName: process.env.REACT_APP_NODE_ENV !== 'production',
          pure: true,
        },
      ],
    ],
  },
  jest: {
    configure: {
      setupFilesAfterEnv: ['./src/test/setupTests.ts'],
      moduleDirectories: [
        'node_modules',
        path.join(__dirname, 'src'),
        path.join(__dirname, 'utils'),
        '!src/utils/**/*.{ts,tsx}',
        '!src/env/*.ts',
      ],
      collectCoverage: true,
      coverageDirectory: 'coverage',
      collectCoverageFrom: [
        'src/**/*.{ts,tsx}',

        // Ignore test coverage for the following files:
        '!src/utils/**/*.{ts,tsx}',
        '!src/env/*.ts',
      ],
      resetMocks: true,
      testURL: 'http://localhost/,
    },
  },
  webpack: {
    plugins: {
      add:
        process.env.REACT_APP_NODE_ENV !== 'local'
          ? [
              new SentryPlugin({
                release: process.env.REACT_APP_VERSION,
                dist: process.env.REACT_APP_VERSION,
                include: './build/static/js',
                ignore: ['node_modules'],
              }),
            ]
          : [],
    },
  },
  eslint: {
    enable: process.env.REACT_APP_NODE_ENV !== 'local',
  },
}

And I've also added like in your example a config-overrides.js like the following

const { aliasWebpack, aliasJest } = require('react-app-alias')

const options = {
  autoscan: 'src',
}

module.exports = aliasWebpack(options)
module.exports = aliasJest(options)

But I'm still having trouble around some imports, any idea?
seems like these 2 are clashing and Webpack is not able to resolve the correct one but only in certain instances

"utils": ["src/utils"],
"utils/*": ["src/utils/*"]

Can't define multiple paths alias in typescript ?

I'm moving my codebase javascript to typescript. It was working with javascript code but not working with typescript code and I want to use multiple alias. This is my code

const {alias} = require('react-app-rewire-alias')
module.exports = function override(config) {
alias({
"Components": './src/ui/components',
"Pages": './src/ui/pages',
"Theme": './src/ui/theme.js',
"Api": './src/core/api',
"Hooks": './src/core/hooks',
"Utils": './src/core/utils',
})(config)
return config
}

but it's showing error
Module not found: Can't resolve 'Theme' in '/Users/abc/Documents/pro/src'

These are related versions

"react": "^16.13.1",
"react-app-rewired": "^2.1.6",
"react-app-rewire-alias": "^0.1.6",
"react-dom": "^16.13.1",
"react-scripts": "^3.4.3",
"typescript": "^4.0.2",

Please tell what I'm doing wrong

No Types found

When using alias in craco.config.ts, typescript complains for the types.

aliasJest causes my test suite to break

I'm switching an existing package that works without issue to use react-app-alias. My colleague and I were able to get the app running after setting a bunch of aliased paths correctly, however our unit test suite now fails to run.

We've not changed the tests or any of the code that they run against and have narrowed the problem down to aliasJest() or at least something in that area.

Prior to upgrading

Test suite runs without issue but the app doesn't run as our config-overrides.js is outside the project directory (it's shared across multiple apps).

Existing Jest config

This works prior to the intorduction of react-app-alias.

jest:  override(
      replaceJestIgnore('some_regex'),
      addJestAliases(aliases),
      replaceJestBabelTransform(appJestDir('babelTransform.js')),
      addJestSetupFile(appJestDir('setupRequireContext.js')),
    ),

After switching to use react-app-alias

If we don't touch config-overrides.js, our Jest overrides are not aware of the aliased paths so we get a bunch of errors like this:

Cannot find module 'components/ContentItem' from 'src/tests/components/ContentItem.spec.js

components is aliased in jsconfig.paths.json:

"components/*": ["src/components/*"],

New Jest config

This config gets me passed the 'cannot find module' errors but the tests fail as any Babel no longer transpiles any ES6 modules.

jest:  aliasJest(
   override(
      replaceJestIgnore('some_regex'),
      addJestAliases(aliases),
      replaceJestBabelTransform(appJestDir('babelTransform.js')),
      addJestSetupFile(appJestDir('setupRequireContext.js')),
    ),
),

After switching to use react-app-alias and aliasJest()

If I wrap my Jest overrides with aliasJest(), then the aliases work but Jest fails to transpile any ES6 modules e.g:

<project_path>/redesign/Avatar/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import Avatar from './Avatar';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      2 | import React, { useEffect } from 'react';
      3 | import PropTypes from 'prop-types';
    > 4 | import Avatar from '<project_path>/redesign/Avatar';
    

autoscan

Warn: Experimental feature. It is not documented and may be subject to remove.

Please ask a questions, share opinions and suggestions. Share your experience if you tried to use autoscan.

const options = {
  autoscan: 'src',
}
const options = {
  autoscan: {
    path: 'src',
    prefix: '@', // optional
    suffix: '_', // optional
  }
}
const options = {
  autoscan: [
    'lib',
    {
      path: 'src',
    },
  ]
}

Aliases do not resolve for tests

Following the docs, the tests will not resolve the aliases.
In my project, but also in the example version of the codebase.

When pulling the latest version, and trying to run the tests, the aliases are not resolved, unfortunately.

Screenshot 2021-02-09 at 10 16 56

alias Doesn't send files into expandPluginsScope

When my paths are something like:

"paths": {
      "@myorg/mylib": [
        "libs/mylib/src/index.ts"
      ]
    }

That file never gets sent into the new ModuleScopePlugin constructor, because you only send in the values of the aliasLocal map into the dirs argument of expandPluginsScope.

Then you set dirs to filter out any elements that aren't directories, so it also doesn't get concatenated in files.

The result is that you'll still get errors complaining that any imports of @myorg/mylib is outside of the src/ directory because they're not exceptions in the ModuleScopePlugin:
Module not found: You attempted to import /home/myrepo/myorg/libs/mylib/src/index.ts which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.

To fix this, either pass the values of aliasLocal into the last 2 args of expandPluginsScope, or don't overwrite the dirs variable when filtering out directories.

BREAKING CHANGE: rename `alias()` to `aliasWebpack()`

Rewire interface is typically uses two alias functions:

module.exports = alias(aliasMap)
module.exports.jest = aliasJest(aliasMap)

Switch to another name of library is a good time to increase readability of rewire API, and make more correct to understand, so:

- module.exports = alias(aliasMap)
+ module.exports = aliasWebpack(aliasMap)
  module.exports.jest = aliasJest(aliasMap)

aliasDangerous crashing on Mac

Hi,

Thanks for the great plugin, we are getting the following error on a Mac when trying to use aliasDangerous for having a common shared project:

request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
                                      ^

TypeError: Cannot read property 'indexOf' of undefined

Printing the request object we get the following:

{"context":{"issuer":"/Users/NothingButOne/develop/GophOR/packages/common/redux/actions/index.ts"},"path":"/Users/NothingButOne/develop/GophOR/packages/common/redux/actions/pushActions","query":"","module":false,"file":false}

Our project structure is:

  • packages
    -- common
    -- web

Inside web we are referencing common, this is our config:

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

const aliasMap = {
  '@common': path.resolve(__dirname, '../common'),
}

module.exports = aliasDangerous(aliasMap)
module.exports.jest = aliasJest(aliasMap)

An error in the code. The code removes plugin next to the modified one

Hi, guys. When you do modifications in ForkTsCheckerWebpackPlugin (and ModuleScopePlugin) you are doing it wrong.
There is the code:

    plugins.splice(pluginPos, 1)
    const paths = {
      ...packagePaths,
      ...((opts.compilerOptions || {}).paths || {}),
      ...tsjsPaths,
    }
    const compilerOptions = {
      ...(opts.compilerOptions || {}),
      paths,
    }
    const options = {...opts, compilerOptions}
    plugins[pluginPos] = new Consructor(options)

Here in line one you delete the current plugin from the list and on the last line you add the new (modified one). It works only if your modified plugin is the last one in the list. I have (for example) ESLintWebpackPlugin that goes after ForkTsCheckerWebpackPlugin and it's cut of when I use aliasDangerous

Option to specify pathname of config file

Hi @oklas, use any path that deviates from the pattern ^[jt]sconfig(\.paths)?.json, and the plugin cannot resolve the aliases correctly. This is problematic for two reasons

  1. The documentation doesn't make it explicitly clear, that the only supported file names are those specified by the previous pattern. As a result, individuals may experience compilation failures without any possible reason as to why.
  2. There's no need to restrict the file names. There's no benefit in doing so, and causes more hassle then needed.

For these reasons, I think we should allow users to use different names. We don't have "guess" the name, but rather grab the file path from "extends". What do you think?3

Originally posted by @urmzd in #42 (comment)

jest moduleNameMapper issue for file aliases

hi, in use case like below

"paths": {
      "@app-utils": ["src/utility.js"]
 }

such a config occurs;

{
  '^@app-utils/(.*)$': '<rootDir>/src/utility.js/$1'
}

this config is not working correctly for jest. it has to be like this for it to work correctly

{
  '^@app-utils$': '<rootDir>/src/utility.js'
}

typo in eslint filter apply

@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.

Originally posted by @JollyGoodHolly in oklas/react-app-rewire-alias#3 (comment)

Error: Cannot find module 'react-scripts/config/paths'

Hello and thank you so much for this great lib.
I have troubled using it with craco, after following the craco config, and launching the app with craco start I get:

yarn run v1.22.10
$ /home/user/app/node_modules/.bin/craco start
(node:18131) UnhandledPromiseRejectionWarning: Error: Cannot find module 'react-scripts/config/paths'
Require stack:
- /home/user/app/node_modules/react-app-rewire-alias/src/index.js
- /home/user/app/packages/files-ui/craco.config.js
- /home/user/app/node_modules/@craco/craco/lib/config.js
- /home/user/app/node_modules/@craco/craco/scripts/start.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
    at Function.Module._load (internal/modules/cjs/loader.js:667:27)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object.<anonymous> (/home/user/app/node_modules/react-app-rewire-alias/src/index.js:4:15)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
(node:18131) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:18131) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 0.18s.

Any idea? Thanks a lot.

tsconfig.json was overwrote by react-scripts

I add the paths config in tsconfig.json, it looks like:

"paths": {
    "@library/*": ["library/*"]
}

But when I start up("start": "react-app-rewired start), it shows up this log, my tsconfig.json would be overwrote. (paths disappears)

The following changes are being made to your tsconfig.json file: 
  - compilerOptions.paths must not be set (aliased imports are not supported)

Solution
Refer this extends
Use tsconfig.paths.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@library/*": ["library/*"]
    }
  }
}

then add this line in tsconfig.json
"extends": "./tsconfig.paths.json"

my config-overrides.js

const { alias, configPaths } = require('react-app-rewire-alias')

module.exports = function override(config) {

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

cheers ๐Ÿบ

Craco plugin + aliasDangerous

Hi there,

Thanks for maintaining this package! ๐Ÿ™‡

We use the craco plugin, but we also need to make use of "aliasDangerous" following the recent updates. Is that currently possible (couldn't find anything in the docs)?

Thanks!

'extends' is not a compiler option

In the documentation, it states to add "extends": "./tsconfig.paths.json" to the "compilerOptions". This should be on the root level.
If you follow the docs, there will be errors.

error TS5023: Unknown compiler option 'extends'.

error Command failed with exit code 1.

Invalid ForkTsCheckerWebpackPlugin configuration object

I'm using

  • "react-scripts": "5.0.0"
  • "react-app-rewire-alias": "1.1.5",
  • "react-app-rewired": "2.1.8"

and encountering this error:

Invalid configuration object. ForkTsCheckerWebpackPlugin has been initialized using a configuration object that does not match the API schema.
 - configuration has an unknown property 'compilerOptions'. These properties are valid:
   object { async?, typescript?, eslint?, formatter?, issue?, logger? }

I believe the problem is at aliasDangerous.js#L98 where the invalid property compilerOptions is added.

const options = {...opts, compilerOptions}

I tried modifying the source code locally and this version works:

const options = {
   ...opts,
   typescript: {
      ...opts.typescript,
      configOverwrite: compilerOptions,
   }
}

If you think this fix is reasonable, please apply it.

Error in monorepo setup: react-app-rewire-alias:configPaths: array expected for paths

I'm using

  • "react-scripts": "5.0.0"
  • "react-app-rewire-alias": "1.1.5",
  • "react-app-rewired": "2.1.8"

with a monorepo setup with Yarn Workspace and encountering this error:

react-app-rewire-alias:configPaths: array expected for paths, specify ../../../tsconfig.json instead of G:\my-project\packages\apps\react-web\tsconfig.json for configPaths()

This is my root tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    // truncated for brevity
    "paths": {
      "@myway/moduleOne/*": ["./packages/libs/moduleOne/src/*"],
      "@myway/moduleTwo/*": ["./packages/libs/moduleTwo/src/*"]
    }
  },
  "include": [
    "packages"
  ]
}

This is my module tsconfig.json

{
   "extends": "../../../tsconfig.json",
   "compilerOptions": {
       "isolatedModules": true
    }
}

My config-overrides.js

const tsPaths = configPaths('../../../tsconfig.json');

Object.entries(tsPaths).forEach(([key, value]) => {
   tsPaths[key] = path.resolve(__dirname, `../../../${value}`);
});

module.exports = aliasDangerous(tsPaths);
// truncated for brevity

This setup worked with "react-app-rewire-alias@~1.0" but now it has the mentioned error.

I think it's because of the check at index.js#L116
I trying this fix locally and it works:

if(conf.compilerOptions.paths && typeof conf.compilerOptions.paths !== 'object')
    throw Error(`
      react-app-rewire-alias:configPaths: array expected for paths${extmsg}`)

IMO it's OK for module tsconfig.ts not to have paths declare explicitly because it can inherit from the root one.

Cannot set properties of undefined (setting 'exports')

I have a monorepo setup (using TurboRepo) with my CRA app with Craco, inside apps/* folder and a design system inside packages/* folder. The paths to the design system are setup in tsconfig.json.

Previously, I was using the the old plugin craco-alias. I have replaced it with react-app-alias-ex.

However it sometimes does not work with hot reloading i.e when a change is made inside packages/*, I see Cannot set properties of undefined (setting 'exports') as an error on the browser while the craco process shows Files successfully emitted, waiting for typecheck results.... I have to shutdown the server and restart.

Any solutions ?

Aliases not resolved during react-scripts' typecheck

TL;DR version:
I'm having some trouble with a project that uses react-app-rewired in combination with the provided instructions. The React app compiles, but during react-script's internal type check, typescript throws an error. My own ESLint and VSCode lookups are also fine, though.


So, I have this project I'm working on, and I was already using react-app-rewired for including a WebAssembly module, specifically one for Argon2. It worked great, as I could use WebAssembly without having to eject the CRA app, which is the entire purpose of react-app-rewired. During refactoring my project, I wanted to use path aliases, which led me to this repository.

I basically followed the instructions to use tsconfig.paths.json and extending the regular tsconfig.json, so that react-scripts would not remove the paths (smart one) and then used react-app-rewire-alias so that it alters the webpack config on-the-fly.

When doing yarn start (== yarn react-app-rewired start src) the app compiles, then performs a type check and fails at that point. What are the possible causes? And what about my config-overrides.js โ€” have I written it the right way?


The console error

./src/App.tsx
Module not found: Your application tried to access @components/SomeComponent, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.

Package versions

      "react-app-rewire-alias": "^1.0.3",
      "react-app-rewired": "^2.1.8",
      "react-scripts": "^4.0.3",
      "typescript": "^4.4.3",

tsconfig.paths.json

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@core/*": ["src/core/*"],
            "@components/*": ["src/components/*"],
            "@hook/*": ["src/hook/*"],
            "@models/*": ["src/models/*"]
        }
    }
}

tsconfig.json

{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "downlevelIteration": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": [
    "src"
  ]
}

config-overrides.js

const { alias, configPaths } = require('react-app-rewire-alias');

module.exports = {
    webpack(config, env) {
        config.module.rules.push({
            test: /\.wasm$/,
            loader: 'base64-loader',
            type: 'javascript/auto',
        });

        config.module.rules.forEach((rule) => {
            (rule.oneOf || []).forEach((oneOf) => {
                if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
                    oneOf.exclude.push(/\.wasm$/);
                }
            });
        });
        const aliasMap = configPaths('./tsconfig.paths.json');
        alias(aliasMap)(config);
        return config;
    },
};

Rewire alias from outside of root folder?

{
  "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..

BREAKING CHANGE: Migrate rewire interface from alias map to options

Alias functions aliasWebpack and aliasJest alway wants alias map - that is not flexible and may be simplified. So if alias map may be loaded from tsconfig/jsconfig it may be omited.

Another problem is impossibility to specify path of tsconfig/jsconfig file, described in #57 which actually is required.

Another problem is #10 where we need to specify baseUrl also as config option.

Therefore API need to be changed. Both functions aliasWebpack and aliasJest will receive options - object with named options.

Options {
  alias: { [alias: string]: string };
  tsconfig: string;
  jsconfig: string;
  ...
}

`react-app-alias-ex` is not a drop-in replacement for `react-app-alias`

When using react-app-alias-ex to allow outside of root packages (a unique aspect of our setup) Jest throws resolver errors:

 FAIL  src/views/__tests__/BSListViewTemplate.test.js
  โ— Test suite failed to run

    Cannot find module 'semver' from 'node_modules/jest-snapshot/build/InlineSnapshots.js'

    Require stack:
      node_modules/jest-snapshot/build/InlineSnapshots.js
      node_modules/jest-snapshot/build/State.js
      node_modules/jest-snapshot/build/index.js
      node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js

      at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)

But switching back to react-app-alias and temporarily commenting out our external packages works as expected.

Config files:

// jsconfig.paths.js
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@utils/*": ["src/utils/*"],
            "@constants/*": ["src/constants/*"],
            "@views/*": ["src/views/*"],
            "@components/*": ["src/components/*"],
            "@layouts/*": ["src/components/layouts/*"],
            "@common/*": ["src/components/common/*"],
            "@core/*": ["src/components/core/*"],
            "@example_plugin/*": [
                "../../examples/example_plugin/example_plugin/ui/*"
            ]
        }
    }
}
// jsconfig.js
{
    "extends": "./jsconfig.paths.json",
    "compilerOptions": {}
}
// craco.config.js

const { CracoAliasPlugin } = require("react-app-alias");

module.exports = {
    plugins: [
        {
            plugin: CracoAliasPlugin,
        },
    ],

    webpack: {
        configure: (webpackConfig, { env, paths }) => {
        
            webpackConfig.output.filename = "static/js/[name].js"; 
            webpackConfig.output.assetModuleFilename = "static/media/[name].[ext]";
            webpackConfig.output.chunkFilename = "static/js/[id]-[chunkhash].js";

            webpackConfig.devtool = "eval-cheap-module-source-map";

            webpackConfig.plugins[5].options.filename = "static/css/[name].css";
            return webpackConfig;
        },
    },
};

Jest could not locate aliased module

Hello @oklas,

I have trouble running react tests with dangerous aliased imports .
Already saw related issues in the repo. I doubt we share the same context.

Here is the error:

$ yarn test
yarn run v1.22.10
$ react-app-rewired test -- --config=jest.config.ts
The following changes are being made to your tsconfig.json file:
  - compilerOptions.paths must not be set (aliased imports are not supported)


 FAIL  test/App.test.tsx
  โ— Test suite failed to run

    Configuration error:

    Could not locate module @/shared/components/Toaster mapped as:
    ../../shared/$1.

    Please check your configuration for these entries:
    {
      "moduleNameMapper": {
        "/^@\/shared\/(.*)/": "../../shared/$1"
      },
      "resolver": undefined
    }




Below, my config files:

// jest.config.json

const jestConfig = {
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      tsconfig: '<rootDir>/tsconfig.spec.json',
    },
  },
  verbose: true,
  // see https://github.com/facebook/jest/issues/7914#issuecomment-464352069
  //   testMatch: ['<rootDir>/test/**/+(*.)+(test).+(tsx)'],
  testMatch: ['<rootDir>/test/**/*(*.)+(test).+(tsx)'],

  setupFilesAfterEnv: ['<rootDir>/test/setupTests.ts'],
  moduleFileExtensions: ['js', 'ts', 'tsx'],
  collectCoverage: true,
  coverageDirectory: 'target/coverage',
  collectCoverageFrom: [
    'src/**/*.tsx',
  ],
  moduleNameMapper: {
    '^.+\\.(css)$': 'identity-obj-proxy',
    '^.+\\.(png|svg|pdf|jpg|jpeg)$': 'jest-transform-stub',
    '^@/admin/(.*)': '<rootDir>/src/$1',
    '^@/shared/(.*)': '../../shared/$1',

  },
};

export default jestConfig;
// tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/shared/*": ["../../shared/*"],
      "@/admin/*": ["src/*"]
    }
  }
}

// confg.overrides.json
const {aliasDangerous, aliasJest, configPaths} = require('react-app-rewire-alias/lib/aliasDangerous')

const aliasPaths = configPaths('./tsconfig.paths.json')

module.exports = aliasDangerous(aliasPaths)
module.exports.jest = aliasJest(aliasPaths)
//tsconfig.json

{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src",
    "../../shared"
  ]
}

dependencies

 "react-app-rewire-alias": "^1.0.1",
    "react-app-rewired": "^2.1.8"

CRA 4.0 support?

Hi there, not entirely sure what's happening, I tried to upgrade to CRA 4.0, but I got this error:

node_modules/react-scripts/scripts/utils/verifyTypeScriptSetup.js:241
      appTsConfig.compilerOptions[option] = value;
                                          ^

TypeError: Cannot add property paths, object is not extensible

alias(configPath()) is not working with baseUrl = src

Originally posted by @MassMessage in oklas/react-app-rewire-alias#2

this is not working for me:

module.exports = function override(config)
{
    return alias(configPaths('./tsconfig.paths.json'))(config);
}

I get the error:

[0] Module not found: Can't resolve '@Shared/ChannelName' in 'C:\Users\jckj33\Desktop\merge\Newton\src\components'

but this is working:

module.exports = function override(config)
{
    config.resolve = config.resolve || {};
    config.resolve.alias = config.resolve.alias || {};

    Object.assign(config.resolve.alias, {
        '@Shared': path.resolve(__dirname, 'src/shared')
    });

    return config
};

tsconfig.paths.json is defined like this:

{
    "compilerOptions":
    {
        "baseUrl": "src",
        "paths": {
            "@Shared/*": ["shared/*"]
        }
    }
}

What am I missing?

I just found out alias(configPaths()) isn't considering the baseUrl in tsconfig.paths.jsona file when generating the paths so give the paths in the orginal poster, it is generating:

    alias: {
      'react-native': 'react-native-web',
       '@Shared': 'C:\\Users\\jckj33\\Desktop\\merge\\Newton\\shared'
     }

instead of:

    alias: {
       'react-native': 'react-native-web',
       '@Shared': 'C:\\Users\\jckj33\\Desktop\\merge\\Newton\\src\\shared'
     }

note it's missing the src folder as defined in the baseUrl in the tsconfig.paths.json file. Any workaround for this to keep using alias(configPaths())

Originally posted by @MassMessage in oklas/react-app-rewire-alias#2

warning : compilerOptions.paths must not be set (aliased imports are not supported)

I am still getting this weird warning although it is supposed to have been fixed. Am I missing something in my config?

$ yarn test
yarn run v1.22.10
$ react-app-rewired test -- --config=jest.config.ts
The following changes are being made to your tsconfig.json file:
  - compilerOptions.paths must not be set (aliased imports are not supported)

// package.json

  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test -- --config=jest.config.ts",
    "eject": "react-scripts eject"
  },
// tsconfig.json

{
  "extends": "./tsconfig.paths.json",
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src",
    "../../shared"
  ]
}

// tsconfig.paths.json

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@shared/*": ["../../shared/*"],
      "@app/*": ["src/*"]
    }
  }
}

// config-overrides.js

const { alias, configPaths } = require('react-app-rewire-alias');

module.exports = function override(config) {
  alias(configPaths('./tsconfig.paths.json'))(config);

  return config;
};

dependencies

[email protected]
[email protected]
[email protected]
[email protected]

System:

OS: Windows 10 10.0.19042
CPU: (8) x64 Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
Memory: 2.16 GB / 15.85 GB

alias is not defined

When the change was made for v2.0.0 of this library, alias was renamed to aliasWebpack. However the previous alias call was not changed and the library is failing.

EDIT: forgot to attach the error I get:

/Users/gonzofish/Projects/my-project/node_modules/react-app-alias/src/index.js:175
    return alias(pluginOptions.alias||configPaths())(webpackConfig)
    ^

ReferenceError: alias is not defined
    at Object.overrideWebpackConfig (/Users/gonzofish/Projects/my-project/node_modules/react-app-alias/src/index.js:175:5)
    at overrideWebpack (/Users/gonzofish/Projects/my-project/node_modules/@craco/craco/lib/features/plugins.js:42:40)
    at /Users/gonzofish/Projects/my-project/node_modules/@craco/craco/lib/features/plugins.js:64:29
    at Array.forEach (<anonymous>)
    at applyWebpackConfigPlugins (/Users/gonzofish/Projects/my-project/node_modules/@craco/craco/lib/features/plugins.js:63:29)
    at mergeWebpackConfig (/Users/gonzofish/Projects/my-project/node_modules/@craco/craco/lib/features/webpack/merge-webpack-config.js:110:30)
    at overrideWebpackDev (/Users/gonzofish/Projects/my-project/node_modules/@craco/craco/lib/features/webpack/override.js:11:36)
    at /Users/gonzofish/Projects/my-project/node_modules/@craco/craco/scripts/start.js:27:5

Identifier 'expandRulesInclude' has already been declared

Hello @oklas,

I am facing this error while running my react tests with some aliased files.
Is it related to your library? I saw related previous issues in this repo in vain.

$ react-app-rewired test -- --config=jest.config.ts
C:\Users\project\node_modules\react-app-rewire-alias\src\aliasDangerous.js:30
function expandRulesInclude(rules, include) {
^

SyntaxError: Identifier 'expandRulesInclude' has already been declared
    at wrapSafe (internal/modules/cjs/loader.js:1172:16)
    at Module._compile (internal/modules/cjs/loader.js:1220:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
    at Module.load (internal/modules/cjs/loader.js:1105:32)
    at Function.Module._load (internal/modules/cjs/loader.js:967:14)
    at Module.require (internal/modules/cjs/loader.js:1145:19)
    at require (internal/modules/cjs/helpers.js:75:18)
    at Object.<anonymous> (C:\Users\Utilisateur\Documents\gamma\gamma-ui\gamma-web-client\node_modules\react-app-rewire-alias\lib\aliasDangerous.js:1
:18)
    at Module._compile (internal/modules/cjs/loader.js:1256:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

When I change aliasDangerous to alias, I face this other error:

module.exports.jest = aliasJest(aliasMap)
                      ^

TypeError: aliasJest is not a function
    at Object.<anonymous> (C:\Users\Utilisateur\Documents\gamma\gamma-ui\gamma-web-client\apps\administration-service\config-overrides.js:6:23)
    at Module._compile (internal/modules/cjs/loader.js:1256:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
    at Module.load (internal/modules/cjs/loader.js:1105:32)
    at Function.Module._load (internal/modules/cjs/loader.js:967:14)
    at Module.require (internal/modules/cjs/loader.js:1145:19)
    at require (internal/modules/cjs/helpers.js:75:18)
    at Object.<anonymous> (C:\Users\Utilisateur\Documents\gamma\gamma-ui\gamma-web-client\node_modules\react-app-rewired\config-overrides.js:5:18)
    at Module._compile (internal/modules/cjs/loader.js:1256:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.



Here is my config.ovverrides

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

const aliasPaths = configPaths('./tsconfig.paths.json')

module.exports = aliasDangerous(aliasPaths)
module.exports.jest = aliasJest(aliasPaths)

Package does not match release

In the latest release (2.2.1) as listed on GitHub, configFilePath is defined and exported. However, the published npm package does not contain nor export this function. This function is required by react-app-alias-ex, meaning that react-app-alias-ex is currently broken when using react-app-alias in version 2.2.1:

yarn run v1.22.17
$ react-app-rewired start
configFilePath is not a function
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Dangerous mode with js cra crashes with: array expected for paths, specify

Hello, I'm having the same issue. Updating the import path seems to break the plugins:

const {
  CracoAliasPlugin,
  configPaths,
} = require("react-app-rewire-alias/lib/aliasDangerous");

const aliasMap = configPaths("./jsconfig.paths.json");

module.exports = {
  plugins: [
    {
      plugin: CracoAliasPlugin,
      options: { alias: aliasMap },
    },
  ],
};

Result in:

Error:
      react-app-rewire-alias:configPaths: array expected for paths, specify ./jsconfig.paths.json instead of D:\Administration\administration-ui\jsconfig.json for configPaths()
    at configPathsRaw (D:\Administration\administration-ui\node_modules\react-app-rewire-alias\src\index.js:110:11)
    at expandPluginsTsChecker (D:\Administration\administration-ui\node_modules\react-app-rewire-alias\src\aliasDangerous.js:81:21)
    at D:\Administration\administration-ui\node_modules\react-app-rewire-alias\src\aliasDangerous.js:126:5
    at Object.overrideWebpackConfig (D:\Administration\administration-ui\node_modules\react-app-rewire-alias\src\aliasDangerous.js:133:62)
    at overrideWebpack (D:\Administration\administration-ui\node_modules\@craco\craco\lib\features\plugins.js:42:40)
    at D:\Administration\administration-ui\node_modules\@craco\craco\lib\features\plugins.js:64:29
    at Array.forEach (<anonymous>)
    at applyWebpackConfigPlugins (D:\Administration\administration-ui\node_modules\@craco\craco\lib\features\plugins.js:63:29)
    at mergeWebpackConfig (D:\Administration\administration-ui\node_modules\@craco\craco\lib\features\webpack\merge-webpack-config.js:110:30)
    at overrideWebpackDev (D:\Administration\administration-ui\node_modules\@craco\craco\lib\features\webpack\override.js:11:36)
error Command failed with exit code 1.

Using require("react-app-rewire-alias"); does give me the aliasDangerous warning as expected:

$ craco start
alias 'GameConfigs' is outside of root - supported only by aliasDangerous
https://github.com/oklas/react-app-rewire-alias#outside-of-root

Originally posted by @AVAVT in https://github.com/oklas/react-app-rewire-alias/issues/25#issuecomment-956122063

Alias is not resolved based on baseUrl setting on tsconfig.paths.json

For some background, in my company we use aliases to import shared folders outside of the app folder (imports outside of src/). We did this by using symlinks of the outside folders and placed them inside the src/ folder of each app that consumed the alias.

This library helped the need to create symlinks as well as made adding a new folder slightly easier to do by changing fewer configs.

However, an issue we found was that we were using baseUrl: 'src' (the default in create-react-app). This library apparently requires to use baseUrl: '.', so we had to change our aliases in the tsconfig.paths.json respectively.

This is a small change for smaller codebases that weren't using imports like import X from 'components/X';, since the change of baseUrl broke those imports.

I believe that supporting baseUrl should be an easy enough change, but wanted to know if this was intentional.

In summary: compilerOptions.baseUrl is being ignored by the library, and requires it to be '.' or otherwise the compiler will fail to resolve aliases.

Using the following config causes an error when importing the alias.

// tsconfig.paths.json
{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "above-root-ts/*": [ "../../above-root-ts/src/*" ],
      "above-root-js/*": [ "../../above-root-js/src/*" ],
      "near-src/*": [ "../near-src/src/*" ]
    }
  }
}
Module not found: Can't resolve 'above-root-js/AboveRootJs' in '~/Projects/apps/main/src'

`expandPluginsScope()` should preserve `ModuleScopePlugin.allowedFiles`

react-scripts@5 introduces webpack@5, which no longer has built-in shims. Thus, react-scripts explicitly supplies the shims via ModuleScopePlugin, which expandPluginsScope() manipulates.

This function should hence preserve the shim entries so that compilation can continue.

Footnotes

Setup:

This issue was investigated using the following config files:
https://github.com/opengovsg/askgovsg/blob/dependabot/npm_and_yarn/client/react-scripts-5.0.0/client/config-overrides.js
https://github.com/opengovsg/askgovsg/blob/dependabot/npm_and_yarn/client/react-scripts-5.0.0/client/tsconfig.paths.json

The build fails with webpack (via react-scripts) complaining that it no longer can find packages in the project's node_modules:
https://github.com/opengovsg/askgovsg/runs/4577986959?check_suite_focus=true#step:11:14

Array of sources for an alias

Some of my path aliases are an array of sources, which is supported by typescript and webpack but unfortunately not by this package. Only the first source is used and the rest are ignored which breaks my build.

It would be great if this package supported an array of sources. It seems like this should be an easy fix since I was able to get it working by making a couple of changes:

function configPaths(configPath = '', confUndoc) {
    ...
    const targets = Array.isArray(value) ? value : [value]
    a[path.replace(/\/\*$/,'')] = targets.map(t => t.replace(/\/\*$/,''))
    ...
}
function aliasWebpack(options) {
  const aliasMap = defaultOptions(options).aliasMap
  const aliasLocal = Object.keys(aliasMap).reduce( (a,i) => {
    a[i] = (Array.isArray(aliasMap[i]) ? aliasMap[i] : [aliasMap[i]]).map(p => path.resolve(paths.appPath, p))
    return a
  }, {})
  ...
}
function expandPluginsScope(plugins, dirs, files) {
    ...
    plugins[pluginPos] = new ModuleScopePlugin(dirs.flat(), files.flat())
  }
}
function aliasMapForJest(baseUrl, aliasMap) {
  return Object.keys(aliasMap).reduce((a, i) => {
    const restr = i.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
    const alias = `^${restr}/(.*)$`

    const targets = Array.isArray(aliasMap[i]) ? aliasMap[i] : [aliasMap[i]]

    return {
      ...a,
      [alias]: targets.map(t =>
        isOutsideOfRoot(t) ? path.resolve(baseUrl, t) + '/$1' : `<rootDir>/${t}/$1`,
      ),
    }
  }, {})
}

baseUrl doesn't work in `react-app-alias-ex`.

@oklas It doesn't work in react-app-alias-ex.

When I log the output of aliasWebpack(options)(config) I can see the baseUrl is completely ignored.
When I switch back to react-app-alias, and comment out the checkOutside(aliasMap) line, it does log the correct paths.

Originally posted by @thany in #72 (comment)

Cannot convert undefined or null to object if there are no dependencies

I have a monorepository where some child package.json is missing dependencies.

{
  "name": "@project/client",
  "version": "1.0.9",
  "private": true,
  "scripts": {
    "start": "cross-env BROWSER=none PORT=3200 craco start",
    "build": "cross-env craco build",
  }
}

I get this error:

E:\project\node_modules\react-app-alias-ex\src\index.js:58
  const list = [].concat(...depsSections.map(s => Object.keys(pack[s])))

TypeError: Cannot convert undefined or null to object

Cannot read property 'baseUrl' of undefined

node_modules/react-app-alias/src/index.js:199
    baseUrl: conf.compilerOptions.baseUrl || '.',
                                  ^

The config fully extends from another, there is no compilerOptions when using console.log to see:

{
  extends: {
    compilerOptions: {
      module: 'esnext',
      target: 'es5',
      lib: [Array],
      allowJs: false,
      checkJs: false,
      resolveJsonModule: true,
      jsx: 'react-jsx',
      declaration: false,
      declarationMap: false,
      sourceMap: false,
      noEmit: true,
      isolatedModules: true,
      skipLibCheck: true,
      strict: true,
      noImplicitAny: false,
      strictNullChecks: true,
      strictFunctionTypes: true,
      strictPropertyInitialization: false,
      noImplicitThis: true,
      alwaysStrict: true,
      forceConsistentCasingInFileNames: true,
      noImplicitReturns: true,
      noFallthroughCasesInSwitch: true,
      moduleResolution: 'node',
      paths: [Object],
      allowSyntheticDefaultImports: true,
      esModuleInterop: true,
      experimentalDecorators: false,
      emitDecoratorMetadata: false
    },
    include: [ './**/*' ]
  }
}

This can be fixed by using a condition?

let compilerOptions = conf.compilerOptions
if (!compilerOptions && conf.extends) {
  compilerOptions = conf.extends.compilerOptions
}
let baseUrl
if (compilerOptions) {
  baseUrl = compilerOptions.baseUrl
}
if (!baseUrl) {
  baseUrl = '.'
}

TypeError: aliasJest is not a function

Runing a react test - with typescript enabled - as stated in your example, I face this error:

module.exports.jest = aliasJest(aliasMap)
                      ^

TypeError: aliasJest is not a function
    at Object.<anonymous> (C:\Users\Utilisateur\Documents\gamma\gamma-ui\gamma-web-client\apps\administration-service\config-overrides.js:6:23)
    at Module._compile (internal/modules/cjs/loader.js:1256:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
    at Module.load (internal/modules/cjs/loader.js:1105:32)
    at Function.Module._load (internal/modules/cjs/loader.js:967:14)
    at Module.require (internal/modules/cjs/loader.js:1145:19)
    at require (internal/modules/cjs/helpers.js:75:18)
    at Object.<anonymous> (C:\Users\Utilisateur\Documents\gamma\gamma-ui\gamma-web-client\node_modules\react-app-rewired\config-overrides.js:5:18)
    at Module._compile (internal/modules/cjs/loader.js:1256:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

 "react-app-rewire-alias": "^0.2.0",
    "react-app-rewired": "^2.1.8",
    "typescript": "^4.1.3",
  "react": "^17.0.1",

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.