如何在CRA(create-react-app)和craco中通过webpack设置别名路径?

时间:2019-05-31 02:12:13

标签: javascript reactjs webpack

我在使用create-react-app和craco设置webpack别名路径时遇到问题,已经对其进行了谷歌搜索,但无法解决问题。每次我使用命令Module not found: Can't resolve '@app/App' in 'C:\ReactSandbox\my-project\src运行应用程序时,都会出现错误yarn start

复制步骤:

  1. create-react-app my-project
  2. cd my-project
  3. yarn add @craco/craco
  4. cat > craco.config.js (请参见下面的配置)
  5. 将package.json (craco start,craco build等)的“脚本”部分上的react-scripts替换为craco
  6. 编辑文件src/index.js (替换第4行,请参见下面的代码)
  7. yarn start

craco.config.js

const path = require("path");

module.exports = {
  webpack: {
    resolve: { 
      alias: {
        "@app": path.resolve(__dirname, "src/"),
      }
    }    
  }
};

src / index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from '@app/App'; //replace './App' into '@app/App'
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

当前结果

Module not found: Can't resolve '@app/App' in 'C:\ReactSandbox\my-project\src

预期

我避免调用相对路径,而不是像../../../../FilterComment.js这样的导入模块,编写@app/FilterComment.js

会很干净

7 个答案:

答案 0 :(得分:3)

我们需要2个步骤来添加别名

  1. 告诉IDE tsconfig.json中的别名
  2. 告诉Webpack有关别名

第一:

创建单独的文件tsconfig.path.json并添加别名:

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

将创建的tsconfig.path.json添加到主tsconfig.json

{
   "extends": "./tsconfig.paths.json",
   ... other staff ...
}

第二:

将别名添加到config-overrides.js

const {
   override,
   addWebpackAlias
} = require('customize-cra');

const path = require("path");

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

它对我有用,编码愉快;)

答案 1 :(得分:2)

我的craco.config.js如下所示,它可以正常工作:

const path = require('path');

module.exports = {
    // ...
    webpack: {
        alias: {
            '@': path.join(path.resolve(__dirname, './src')),
        }
    }
}

答案 2 :(得分:0)

只需像这样保存文件craco.config.js,就需要再添加1个名为jsconfig.json的文件

内容:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2016",
    "jsx": "preserve",
    "checkJs": true,
    "baseUrl": "./src/",
    "paths": {
      "@app/*": ["./*"]
    }
  },
  "exclude": ["node_modules", "**/node_modules/*"]
}

然后您可以从绝对路径(如@app/FilterComment.js

导入)

它也适用于VSCode(编辑器现在了解@app指向的位置)。 但是,如果您希望VSCode自动执行导入,则应为其添加更多配置,以强制其始终从绝对路径进行导入。

文件.vscode/settings.json 内容:

{
  "javascript.preferences.importModuleSpecifier": "non-relative"
}

答案 3 :(得分:0)

使用 react-app-rewire-alias

// config-overrides.js:

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

module.exports = function override(config) {
  alias({
    "@app": "src",
  })(config)
  return config
}

或将{em> jsconfig.json 与configPaths()

一起使用

typescript进行配置需要一些其他步骤,请检查docs

现在您可以导入:

   import App from '@app/App'

答案 4 :(得分:0)

解析为carco:

你需要安装craco-alias,然后写入 craco.config.js

    const CracoAlias = require('craco-alias')

    module.exports = {
      plugins: [
        {
          plugin: CracoAlias,
          options: {
            source: 'tsconfig',
            baseUrl: '.',
            tsConfigPath: './tsconfig.path.json',
          },
        },
      ],
    }

tsconfig.path.json

    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": ["src/*"],
          "@svg/*": ["src/assets/svg/*"],
          "@img/*": ["src/assets/images/*"],
          "@icons/*": ["src/assets/icons/*"],
          "@shared/*": ["src/shared/*"],
          "@components/*": ["src/components/*"],
          "@hooks/*": ["src/hooks/*"],
          "@constants/*": ["src/constants/*"],
          "@layout/*": ["src/layout/*"],
          "@services/*": ["src/services/*"]
        }
      }
    }

tsconfig.json

    {
      "extends": "./tsconfig.path.json",
      "compilerOptions": {
        "target": "es5",
        "lib": [
          "dom",
          "dom.iterable",
          "esnext"
        ],
        "allowJs": true,
        "checkJs": false,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "declaration": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react-jsx",
        "noFallthroughCasesInSwitch": true,
        "removeComments": true
      },
      "include": [
        "src",
        "src/configs",
        "react-app-env.d.ts"
      ]
    }

答案 5 :(得分:0)

也许 OP 有一个不同版本的 React / Webpack(我使用的是今天的当前版本),但是将 alias 对象直接放在 webpack 对象中(没有将它嵌套在 {{ 1}} 对象)对我有用:

resolve

答案 6 :(得分:0)

一个不使用依赖的例子(我正在使用):

//craco.config.js
const path = require('path')

const tsconfig = require('./tsconfig.base.json')

const removeAsterisk = path => path.replace('/*', '')

const aliasProps = Object.entries(tsconfig.compilerOptions.paths).map(([key, value]) => {
  const newKey = removeAsterisk(key)
  let newValue = removeAsterisk(value[0])
  newValue = path.resolve(__dirname, newValue)
  return [newKey, newValue]
})

const alias = Object.fromEntries(aliasProps)

module.exports = {
  webpack: {
    alias,
  },
}

//tsconfig.base.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./src/*"],
      //...
    }
  }
}

// tsconfig.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {/*...*/}
}