Skip to content

Instantly share code, notes, and snippets.

@katai5plate
Last active April 17, 2020 01:38
Show Gist options
  • Save katai5plate/da502ef6d281aaa0ec1ff47346bd866d to your computer and use it in GitHub Desktop.
Save katai5plate/da502ef6d281aaa0ec1ff47346bd866d to your computer and use it in GitHub Desktop.
react-app-rewired 動作原理メモ

codes

index

  • paths に加え scriptVersion, configOverrides, customScriptsIndex を返す
1. index.js
  2. scripts/utils/path.js
    3. <prj>/package.json から config-overrides-path を取得
    4. <react-scripts>/config/paths.js から paths を取得

start

1. scripts/start.js
  - NODE_ENV = 任意 || development
  2. scripts/utils/path.js から scriptVersion を取得
  3. config-overrides.js
    4. index.js から paths を取得
    5. <react-scripts>/config/env.js から 環境変数 を取得
    6. <prj>/config-overrides.js から 上書きする設定 を取得
      - { webpack, devServer, jest, paths }
    - マージされた { webpack, devServer, jest, paths } を返す
  7. <react-scripts>/package.json から version を取得
    - react-scripts 2.1.2 以上だと RS 内の webpack.config.js のパスが変わる (WebpackFactory)
  8. <react-scripts>/config/webpack.config[isNotWebpackFactory -> .dev].js を取得
  9. <react-scripts>/config/webpackDevServer.config.js を取得
  - require.cache 中にキャッシュされている react-scripts 側の webpack, devServer 出力値とマージしてる?
  10. <react-scripts>/config/paths.js を取得
  - require.cache 中にキャッシュされている react-scripts 側の paths 出力値とマージしてる?
  11. <react-scripts>/scripts/start.js を実行

build での start との差分

1. scripts/start.js
  - NODE_ENV = production
  8. <react-scripts>/config/webpack.config[isNotWebpackFactory -> .prod].js を取得
  9. (devServer) は不要のため無し
  - require.cache 中にキャッシュされている react-scripts 側の webpack 出力値とマージしてる?
  11. <react-scripts>/scripts/build.js を実行

test

1. scripts/test.js
  - 任意 || test
  2. scripts/utils/path.js から scriptVersion, appPackageJson, appPath, appSrc, customScriptsIndex を取得
  3. config-overrides.js から paths, jest を取得
  4. scripts/utils/rewireJestConfig.js
    5. scripts/utils/path.js から appPackageJson を取得
      - それを使用して <prj>/package.json から jest を取得 ( プロジェクトの jest-config )
    - `上書き値 => マージされたconfig` のような関数を返す
    - 返り値の関数内で scripts/utils/babelTransform.js から babel-jest の設定値を取得している
  6. <react-scripts>/scripts/utils/createJestConfig.js から デフォの jest 設定を取得
  7. <react-scripts>/config/paths.js から paths を取得
  8. <prj>/package.json を取得し、キャッシュされた JSON の jest を上書き分とマージして書き換えてる?
  9. <react-scripts>/scripts/test.js を実行

paths

module.exports.path = {
  // react-scripts の位置
  scriptVersion: '<.>/node_modules/react-scripts',
  // 任意の config-overrides の位置
  configOverrides: '<.>/config-overrides',
  // --scripts-version オプション引数の値の位置
  customScriptsIndex: -1,
  
  // ここまで react-app-rewired 内での取得
  // ここから react-scripts 内での取得
  
  // ".env" ファイルの位置
  dotenv: '<.>/.env',
  // プロジェクトのパス
  appPath: '<.>',
  // プロジェクトのビルドパス
  appBuild: '<.>/build',
  // プロジェクトのパブリックパス
  appPublic: '<.>/public',
  // プロジェクトの index.html
  appHtml: '<.>/public/index.html',
  // プロジェクトの index.tsx
  appIndexJs: '<.>/src/index.tsx',
  // プロジェクトの package.json
  appPackageJson: '<.>/package.json',
  // プロジェクトのソースディレクトリ
  appSrc: '<.>/src',
  // プロジェクトの tsconfig.json
  appTsConfig: '<.>/tsconfig.json',
  // プロジェクトの jsconfig.json
  appJsConfig: '<.>/jsconfig.json',
  // プロジェクトの yarn.lock
  yarnLockFile: '<.>/yarn.lock',
  // プロジェクトの setupTests.js
  testsSetup: '<.>/src/setupTests.js',
  // プロジェクトの setupProxy.js
  proxySetup: '<.>/src/setupProxy.js',
  // プロジェクトの node_modules
  appNodeModules: '<.>/node_modules',
  // 不明
  publicUrl: undefined,
  // 不明
  servedPath: '/',
  // 
  ownPath: '<.>/node_modules/react-scripts',
  ownNodeModules: '<.>/node_modules/react-scripts/node_modules',
  appTypeDeclarations: '<.>/src/react-app-env.d.ts',
  ownTypeDeclarations: '<.>/node_modules/react-scripts/lib/react-app.d.ts',
  moduleFileExtensions: [
    'web.mjs', 'mjs',
    'web.js',  'js',
    'web.ts',  'ts',
    'web.tsx', 'tsx',
    'json',    'web.jsx',
    'jsx'
  ]
}

require.cache

{
  '実行された JS の パス': {
    id: '.',
    path: '<prj>',
    exports: {},
    parent: null,
    filename: '<prj>/<filename>.<ext>',
    loaded: false,
    children: [],
    paths: [
      '<prj>/node_modules',
      '<prj>/<..>/node_modules',
      '<prj>/<../..>/node_modules'
    ]
  }
}

考察

jest-babel エラーによって影響される範囲はおそらくテスト時。

There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.

The react-scripts package provided by Create React App requires a dependency:

  "babel-jest": "^24.9.0"

Don't try to install it manually: your package manager does it automatically.
However, a different version of babel-jest was detected higher up in the tree:

  \node_modules\babel-jest (version: 20.0.3)

Manually installing incompatible versions is known to cause hard-to-debug issues.
If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That will permanently disable this message but you might encounter other issues.
To fix the dependency tree, try following the steps below in the exact order:

  1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.
  2. Delete node_modules in your project folder.
  3. Remove "babel-jest" from dependencies and/or devDependencies in the package.json file in your project folder.
  4. Run npm install or yarn, depending on the package manager you use.

In most cases, this should be enough to fix the problem.
If this has not helped, there are a few other things you can try:

  5. If you used npm, install yarn (http://yarnpkg.com/) and repeat the above steps with it instead.
      This may help because npm has known issues with package hoisting which may get resolved in future versions.

  6. Check if D:\_git_\os-viewer-ra\node_modules\babel-jest is outside your project directory.
      For example, you might have accidentally installed something in your home folder.

  7. Try running npm ls babel-jest in your project folder.
      This will tell you which other package (apart from the expected react-scripts) installed babel-jest.

If nothing else helps, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That would permanently disable this preflight check in case you want to proceed anyway.

P.S. We know this message is long but please read the steps above :We hope you find them helpful!
  • scripts/utils/babelTransform.js の中で使用されている
  • それを scripts/utils/rewireJestConfig.js <- scripts/test.js から参照されている
const babelJest = require('babel-jest');

module.exports = babelJest.createTransformer({
  presets: [require.resolve('babel-preset-react-app')],
  plugins: [],
  babelrc: true
});
All jests internal dependencies are specified with a ^ so for a fresh install without a lock file yarn will install [email protected] for [email protected]. If you put a resolution on [email protected], it will still install [email protected].

You can put a resolution for [email protected] which do work but generates warnings when running yarn as all 2.8.0 packages has the range ^2.8.0.

This issue should be solved when #7007 is released. But as of now, create-react-app tries to verify something that neither yarn nor jest is guaranteeing.
Thanks so much for the assistance, the solution is actually a lot simpler than what I thought I was meant to be trying. It's just forcing all packages to use the same version, simple. And much more simple than the examples I could see. All I had to do was:

1. yarn remove react-aad-msal
2. add
   "resolutions": {
     "jest": "23.6.0",
     "babel-jest": "23.6.0"
   },
   to package.json
3. yarn install
4. yarn add react-aad-msal
and that's it!
  • 試しに以下のようにしたらエラーなく通った
{
  "resolutions": {
    "react-scripts/babel-jest": "20.0.3"
    // または
    "react-app-rewired/babel-jest": "20.0.3"
  }
}
  • と思ったら resolutions を消してみても、問題なく通るようになった。おや?
    • もしかして global-install された create-react-app が悪さしてたのかな?
    • と思ったら、そもそも再現しなくなっていた。もしかして、困ってる間に公式に依存解決した?
@katai5plate
Copy link
Author

katai5plate commented Nov 23, 2019

検証用

yarn init -y && yarn add katai5plate/mykit-create-react-app && node -e "require('mykit-create-react-app')(!0);" && yarn mykit-install && yarn add react-app-rewired && echo module.exports = {}>config-overrides.js && npx react-app-rewired start
create-react-app test-1
cd test-1
yarn add react-app-rewired && echo module.exports = {}>config-overrides.js && npx react-app-rewired start

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment