absolute path with react, react-app-rewire and typescript

放肆的年华 提交于 2020-12-21 03:55:38

问题


i'm using create-react-app + typescript, and i want to add absolute paths.

i'm trying to get to the point i can use absolute paths, like so:

instead of import x from '../../../components/shell/shell'

use import x from '@components/shell/shell';

here is tsconfig.json file:

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

I'm using extended file for paths, because from some reason npm start overrides the file. so is paths.json file:

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

i also have an .env file:

NODE_PATH=src

i installed react-app-rewire so i can config the paths, and my config-ovverrides.js file looks like this:

module.exports = {
  paths: function(paths, env) {
    // ...add your paths config
    return paths;
  }
};

im stuck with connecting all the dots, it doesn't work and i still cant see what i need to do in order to config the webpack path object;

how can i implement paths in cra, ts, and rewire?


回答1:


You can solve it using 5 simple steps withou eject:

Step 1: Adding react-app-rewired into your devDependencies.

yarn add -D react-app-rewired or npm intall react-app-rewired --save-dev

Step 2: After installation, you'll be able to change package.json default ReactsJS scripts to:

"scripts": {  
  "start": "react-app-rewired start",  
  "build": "react-app-rewired build",  
  "test": "react-app-rewired test",  
  "eject": "react-app-rewired eject" 
}

Step 3: Creates a new file called tsconfig.paths.json on root path, with content like:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "services/*": ["./src/shared/services/*"],
      "interfaces/*": ["./src/shared/interfaces/*"]
    }
  }
}

Tip 1: you can choose which path you want to use, like: @services, @interface, @src, ~, @, etc just by changing the keys inside "paths": {}

The same is applied to it's value: ["src/shared/services/"], ["src/shared/interfaces/"], ["src/*"], use the relative path here.

Step 4: Into tsconfig.json, before "compilerOptions" you need to extends the tsconfig.paths.json you just created.

Like this:

{
  "extends": "./tsconfig.paths.json",
  ...//rest of file infos compilerOptions, include... whatever
}

Step 5: Creates a new file config-overrides.js, adding your alias and relative paths on it:

const path = require('path');

module.exports = function override(config) {
  config.resolve = {
    ...config.resolve,
    alias: {
      ...config.alias,
      'services': path.resolve(__dirname, 'src/shared/services'),
      'interfaces': path.resolve(__dirname, 'src/shared/interfaces')
    },
  };

  return config;
};

Tip 2: If you're using eslint, remember to have an .eslintignore file and add config-overrides.js within it.

Restart your IDE or text editor, in my case VSCode.

It's DONE! Now just run yarn start or npm run start




回答2:


Do you need to use the @ syntax?

Are you able to use the syntax of:

import x from 'components/shell/shell'

?

If so, then see the documentation for CRA Absolute Imports.

For Typescript, your tsconfig.json becomes:

{
  "compilerOptions": {
    // ... usual options ...
    "baseUrl": "src",
  },
  // ... include, etc...
}

Out of the box, this will allow you to import for src as the base directory.

So your syntax becomes:

import x from 'components/shell/shell';

This would be the least friction option...

However...

If you absolutely need the @ syntax, then to get rewire to work correctly requires a little more jiggery-pokery. The only way that I have found to get rewire to work with that syntax is to include a webpack alias rewrite.

So the process is (please update the paths as required for your application):

  1. Create a tsconfig.paths.jsonnext to your tsconfig.json containing:
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components": ["src/components/*"],
    }
  }
}
  1. Update your tsconfig.json with an extend:
{
  "compilerOptions": {
    // ... standard options ...
  },
  "include": [
    "src"
  ],
  "extends": "./tsconfig.paths.json"
}

When running the build command (npm run build), the scripts will throw the following error:

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

The extend option mitigates against this.

  1. Add a webpack alias to config-overrides.js:
const path = require('path');
const { override, addWebpackAlias } = require('customize-cra');

module.exports = override(
  addWebpackAlias({
    '@components': path.resolve(__dirname, 'src/components'),
  })
);

This example uses the package customize-cra which has a bunch of helpful resolvers for overrides. (If you don't want to use it, then you would need to set the config.resolve.alias property on the config object passed to the override function)

Now assuming you have updated all the scripts to use react-app-rewired, you should be able to use the syntax:

import x from '@components/shell/shell';


来源:https://stackoverflow.com/questions/59544950/absolute-path-with-react-react-app-rewire-and-typescript

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!