notes icon indicating copy to clipboard operation
notes copied to clipboard

CRNA (create-react-native-app) module resolve & eslint rules check

Open lanlin opened this issue 7 years ago • 6 comments

环境

expo: 25.0.0 react: 16.2.0 react-natice: 0.52.0

注意本文只针对 create-react-native-app 初始化的项目。 ** #其他情况下,本文可能只能用作参考。**

场景

react-native 目前官方默认采用与 Expo 相结合的形式来构建项目。 但是关于 module resolve 这一块,一直没有找到详细的文档说明。 网上千奇百怪的文章一大堆,解决方式也是五花八门。

主要在于项目稍微复杂点的情况下,没人希望用相对路径的形式去引入其他文件。 如下面的例子,相对路径很难看出到底是从哪个目录引入的某个文件。 相比较而言,依托于项目root 目录的绝对路径就简单明了的多。

import foo from '../../../../foo.js';     // relative path
import foo from '~src/components/foo';    // absolute path

解决办法

在既保证绝对路径的引入方式的同时,还加入 eslint 进行规范性检测。

首先,用 create-react-native-app 初始化项目。

安装以下几个 package package.json

  "devDependencies": {
    "babel": "^6.23.0",
    "babel-plugin-module-resolver": "^3.0.0",
    "eslint": "^4.16.0",
    "eslint-config-airbnb-base": "^12.1.0",
    "eslint-import-resolver-babel-module": "^4.0.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-react": "^7.6.1",
    "eslint-plugin-react-native": "^3.2.1"
}

配置 .babelrc

{
  "presets": ["babel-preset-expo"],
  "env": {
    "development": {
      "plugins": ["transform-react-jsx-source"]
    }
  },
  "plugins": [
    ["module-resolver", {
      "alias": {
        "~src": "./src",               // src别名映射,根据需要自行调整
        "~test": "./test"              // test别名映射,根据需要自行调整
      },
      "extensions": [".js", ".ios.js", ".android.js"]
    }]
  ]
}

配置 .eslintrc.js

module.exports = {
  root: true,
  env: { 'react-native/react-native': true },
  extends: ['airbnb-base', 'plugin:react/recommended', 'plugin:react-native/all'],

  plugins: [
    'react',
    'react-native'
  ],

  // check if imports actually resolve
  settings: {
    'import/resolver': {
      'babel-module': {
        alias: {
          '~src': './src',       // 必须与babelrc配置对应
          '~test': './test'      // 必须与babelrc配置对应
        },
        extensions: ['.js', '.ios.js', '.android.js']
      }
    }
  },

  ecmaFeatures: { jsx: true },

  // add your custom rules here
  rules: {
 }
}

题后

以上配置,包含了省略 .js 后缀名的效果。

import foo from 'src/components/foo';

最后记得用 --reset-cache 来运行

yarn run start --reset-cache   // for yarn
npm run start --reset-cache    // for npm

lanlin avatar Feb 12 '18 07:02 lanlin

当从 CRNA detach 之后,.babelrc 有所变化

具体如下:

{
  "presets": [
    "babel-preset-react-native-stage-0/decorator-support"
  ],
  "plugins": [
    "transform-react-jsx-source",
    [
      "module-resolver",
      {
        "root": ["./"],
        "alias": {
          "src": "./src",
          "test": "./test"
        },
        "extensions": [
          ".js",
          ".ios.js",
          ".android.js"
        ]
      }
    ]
  ]
}

.eslintrc.js 的配置保持原来的不变。

注意

.babelrc 里面 detach 之后,可能会保留 env 的情况,那是惹祸的根源。 经常导致 resolve 失败,必须把里面的 transform-react-jsx-source 直接放到外面的 plugins 里面来。 就像上面的配置一样。

lanlin avatar Mar 12 '18 07:03 lanlin

expo 貌似现在都还没增加对wechat的快速集成吧。

meyer-net avatar Mar 29 '18 01:03 meyer-net

@meyer-net expo 感觉就是个试验品,用来引导入门的。但是对于真实项目,感觉没什么卵用。我完全放弃那个东西了,还是需要 detach。不要很多东西都没有。比如 expo 官网好像自己都说不支持蓝牙什么的。

lanlin avatar Mar 29 '18 03:03 lanlin

我也感觉如此,国内的奇葩需求多。要接入各种包,expo不灵活的话,很多事就不好做了。不过他也带来了很多便捷性。小程序原理类似。。。

你们目前对rn的需求如何?现有从业人员转,还是社招。

meyer-net avatar Mar 29 '18 06:03 meyer-net

Maybe this is the solution, but I don't understand a bit :)

hendrul avatar May 14 '18 15:05 hendrul

me neither :)

yesitsfebreeze avatar May 25 '18 08:05 yesitsfebreeze