code

create-react-app은 src 디렉토리 외부에서 제한을 가져옵니다.

codestyles 2020. 9. 14. 20:56
반응형

create-react-app은 src 디렉토리 외부에서 제한을 가져옵니다.


create-react-app을 사용하고 있습니다. .NET 내부 파일에서 공용 폴더의 이미지를 호출하려고합니다 src/components. 이 오류 메시지가 표시됩니다.

./src/components/website_index.js 모듈을 찾을 수 없음 : 프로젝트 src / 디렉토리 외부에있는 ../../public/images/logo/WC-BlackonWhite.jpg를 가져 오려고했습니다. src / 외부의 상대적 가져 오기는 지원되지 않습니다. src / 내부로 이동하거나 프로젝트의 node_modules /에서 심볼릭 링크를 추가 할 수 있습니다.

import logo from '../../public/images/logo_2016.png'; <img className="Header-logo" src={logo} alt="Logo" />

나는 당신이 경로로 가져올 수 있다는 많은 것을 읽었지만 여전히 나를 위해 작동하지 않습니다. 어떤 도움이라도 대단히 감사하겠습니다. 이와 같은 질문이 많이 있다는 것을 알고 있지만 모두 로고나 이미지를 가져 오도록 지시하고 있으므로 큰 그림에서 뭔가를 놓치고 있습니다.


이것은 create-react-app 개발자가 추가 한 특별한 제한 사항입니다. ModuleScopePlugin파일이에 있는지 확인하기 위해 에서 구현 됩니다 src/. 이 플러그인은 앱의 소스 디렉토리에서 상대적 가져 오기가 외부에 도달하지 않도록합니다.

이 기능을 비활성화 할 수 있지만 ejectcreate-react-app 프로젝트 작업 후에 만 가능 합니다.

대부분의 기능과 업데이트는 create-react-app 시스템의 내부에 숨겨져 있습니다. 만들면 eject더 이상 일부 기능과 업데이트가 없습니다. 따라서 웹팩 등을 구성하는 데 포함 된 응용 프로그램을 관리하고 구성 할 준비가되지 않은 경우 eject작업을 수행하지 마십시오 .

기존 규칙에 따라 재생합니다 (src로 이동). 그러나 이제 제한을 제거하는 방법을 알 수 있습니다 : 웹팩 구성 파일에서 수행 eject및 제거ModuleScopePlugin .


이후 생성이-반응 - 응용 프로그램 v0.4.0NODE_PATH 환경 변수는 절대 수입 경로를 지정할 수 있습니다.

절대 가져 오기를 사용하면 variable에 지정된 값에 상대적으로 import App from 'App'대신 사용할 수 있습니다 .import App from './App'NODE_PATH

이 기능은 특히 monorepos 또는 기타 구성 질문에 유용하지만 public폴더 에서 이미지 또는 다른 것을 가져 오는 데는 유용하지 않습니다 .

public폴더의 내용은 폴더에 배치 build되며 상대 URL로 사용 가능합니다. 또한 가져온 모든 것은 webpack에 의해 처리되고 build폴더 에도 배치됩니다 .

public폴더 에서 무언가를 가져 오면 아마도 그 내용이 폴더에 복제 build되고 두 개의 다른 URL (또는 다른로드 방법으로)에 의해 사용 가능할 것이므로 궁극적으로 패키지 다운로드 크기가 악화됩니다.

src 폴더 에서 가져 오는 것이 바람직하며 장점이 있습니다. 모든 것은 웹팩에 의해 최적의 크기최적의 로딩 효율성을 위해 번들로 포장됩니다 .


다른 사람의 답변에 조금 더 많은 정보를 제공합니다. .png 파일을 사용자에게 전달하는 방법에는 두 가지 옵션이 있습니다. 파일 구조는 선택한 방법을 따라야합니다. 두 가지 옵션은 다음과 같습니다.

  1. import x from yreact-create-app과 함께 제공된 모듈 시스템 ( )을 사용하고 JS와 함께 번들로 제공합니다. src폴더 안에 이미지를 배치 합니다.

  2. public폴더 에서 제공하고 Node가 파일을 제공하도록합니다. create-react-app은 분명히 환경 변수 (예 : <img src={process.env.PUBLIC_URL + '/img/logo.png'} />;. 즉, React 앱에서 참조 할 수 있지만 브라우저가 일반 GET 요청에서 별도로 요청하면서 Node를 통해 계속 제공 할 수 있습니다.

출처 : create-react-app


react-app-rewired 패키지를 사용하여 플러그인을 제거 할 수 있습니다. 이렇게하면 꺼내지 않아도됩니다.

npm 패키지 페이지의 단계를 따르고 (패키지를 설치하고 package.json 파일에서 호출을 뒤집습니다) 다음과 config-overrides.js유사한 파일을 사용합니다 .

const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');

module.exports = function override(config, env) {
    config.resolve.plugins = config.resolve.plugins.filter(plugin => !(plugin instanceof ModuleScopePlugin));

    return config;
};

이렇게하면 사용 된 WebPack 플러그인에서 ModuleScopePlugin이 제거되지만 나머지는 그대로두고 꺼낼 필요가 없습니다.


이미지가 공용 폴더에 있으면 다음을 사용해야합니다.

"/images/logo_2016.png"

in your <img> src instead of importing

'../../public/images/logo_2016.png'; 

This will work

<img className="Header-logo" src="/images/logo_2016.png" alt="Logo" />

You need to move WC-BlackonWhite.jpg into your src directory. The public directory is for static files that's going to be linked directly in the HTML (such as the favicon), not stuff that you're going to import directly into your bundle.


This restriction makes sure all files or modules (exports) are inside src/ directory, the implementation is in ./node_modules/react-dev-utils/ModuleScopePlugin.js, in following lines of code.

// Resolve the issuer from our appSrc and make sure it's one of our files
// Maybe an indexOf === 0 would be better?
     const relative = path.relative(appSrc, request.context.issuer);
// If it's not in src/ or a subdirectory, not our request!
     if (relative.startsWith('../') || relative.startsWith('..\\')) {
        return callback();
      }

You can remove this restriction by

  1. either changing this piece of code (not recommended)
  2. or do eject then remove ModuleScopePlugin.js from the directory.
  3. or comment/remove const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); from ./node_modules/react-scripts/config/webpack.config.dev.js

PS: beware of the consequences of eject.


You don't need to eject, you can modify the react-scripts config with the rescripts library

This would work then:

module.exports = config => {
  const scopePluginIndex = config.resolve.plugins.findIndex(
    ({ constructor }) => constructor && constructor.name === "ModuleScopePlugin"
  );

  config.resolve.plugins.splice(scopePluginIndex, 1);

  return config;
};

If you only need to import a single file, such as README.md or package.json, then this can be explicitly added to ModuleScopePlugin()

config/paths.js

const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
module.exports = {
  appPackageJson: resolveApp('package.json'),
  appReadmeMD:    resolveApp('README.md'),
};

config/webpack.config.dev.js + config/webpack.config.prod.js

module.exports = {
  resolve: {
    plugins: [
      // Prevents users from importing files from outside of src/ (or node_modules/).
      // This often causes confusion because we only process files within src/ with babel.
      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,
      // please link the files into your node_modules/ and let module-resolution kick in.
      // Make sure your source files are compiled, as they will not be processed in any way.
      new ModuleScopePlugin(paths.appSrc, [
          paths.appPackageJson,
          paths.appReadmeMD         // README.md lives outside of ./src/ so needs to be explicitly included in ModuleScopePlugin()
      ]),
    ]
  }
}

the best solution is to fork react-scripts, this is actually mentioned in the official documentation, see: Alternatives to Ejecting

참고URL : https://stackoverflow.com/questions/44114436/the-create-react-app-imports-restriction-outside-of-src-directory

반응형