简体   繁体   English

src 目录之外的 create-react-app 导入限制

[英]The create-react-app imports restriction outside of src directory

I am using create-react-app.我正在使用 create-react-app。 I am trying to call an image from my public folder from a file inside my src/components .我正在尝试从我的src/components内的文件中调用我的公用文件夹中的图像。 I am receiving this error message.我收到此错误消息。

./src/components/website_index.js Module not found: You attempted to import ../../public/images/logo/WC-BlackonWhite.jpg which falls outside of the project src/ directory. ./src/components/website_index.js 未找到模块:您尝试导入项目 src/ 目录之外的 ../../public/images/logo/WC-BlackonWhite.jpg。 Relative imports outside of src/ are not supported.不支持 src/ 之外的相对导入。 You can either move it inside src/, or add a symlink to it from project's node_modules/.你可以将它移到 src/ 中,或者从项目的 node_modules/ 中添加一个符号链接。

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

I have read many things saying you can do an import to the path but that is still not working for me.我读过很多东西说你可以对路径进行导入,但这仍然对我不起作用。 Any help would be greatly appreciated.任何帮助将不胜感激。 I know there are many questions like this but they are all telling me to import logo or image so clearly I am missing something in the big picture.我知道有很多这样的问题,但他们都告诉我要导入徽标或图像,所以很明显我在大局中遗漏了一些东西。

This is special restriction added by developers of create-react-app.这是 create-react-app 的开发者添加的特殊限制。 It is implemented in ModuleScopePlugin to ensure files reside in src/ .它在ModuleScopePlugin实现以确保文件驻留在src/ That plugin ensures that relative imports from app's source directory don't reach outside of it.该插件确保来自应用程序源目录的相对导入不会到达它之外。

You can disable this feature (one of the ways) by eject operation of create-react-app project.您可以通过 create-react-app 项目的eject操作禁用此功能(其中一种方法)。

Most features and its updates are hidden into the internals of create-react-app system.大多数功能及其更新都隐藏在 create-react-app 系统的内部。 If you make eject you will no more have some features and its update.如果您进行eject您将不再拥有某些功能及其更新。 So if you are not ready to manage and configure application included to configure webpack and so on - do not do eject operation.因此,如果您还没有准备好管理和配置包含的应用程序以配置 webpack 等 - 请勿执行eject操作。

Play by the existing rules (move to src).按照现有规则进行操作(移至 src)。 But now you can know how to remove restriction: do eject and remove ModuleScopePlugin from webpack configuration file .但是现在你可以知道如何移除限制:从 webpack 配置文件中eject和移除ModuleScopePlugin


Instead of eject there are intermediate solutions, like rewire which allows you to programmatically modify the webpack config without eject .而不是eject有中间解决方案,如再布线,让您以编程方式修改的WebPack配置没有eject But removing the ModuleScopePlugin plugin is not good - this loses some protection and does not adds some features available in src .但是删除ModuleScopePlugin插件并不好- 这会失去一些保护并且不会添加src可用的一些功能。

The better way is to add fully working additional directories similar to src .更好的方法是添加类似于src完全可用的附加目录。 This can be done using react-app-rewire-alias这可以使用react-app-rewire-alias来完成


Do not import from public folder - that will be duplicated in the build folder and will be available by two different url (or with different ways to load), which ultimately worsen the package download size.不要从public文件夹导入 - 这将在build文件夹中复制,并且可以通过两个不同的 url(或使用不同的加载方式)访问,这最终会恶化包下载的大小。

Importing from the src folder is preferable and has advantages.src文件夹导入是可取的并且具有优势。 Everything will be packed by webpack to the bundle with chunks optimal size and for best loading efficiency .一切都将被 webpack 打包到具有最佳大小最佳加载效率的块的包中。

The package react-app-rewired can be used to remove the plugin.react-app-rewired可用于删除插件。 This way you do not have to eject.这样您就不必弹出。

Follow the steps on the npm package page (install the package and flip the calls in the package.json file) and use a config-overrides.js file similar to this one:按照 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;
};

This will remove the ModuleScopePlugin from the used WebPack plugins, but leave the rest as it was and removes the necessity to eject.这将从使用的 WebPack 插件中删除 ModuleScopePlugin,但保留其余部分并消除弹出的必要性。

If your images are in the public folder then you should use如果您的图像在公共文件夹中,那么您应该使用

"/images/logo_2016.png"

in your <img> src instead of importing在你的<img> src而不是导入

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

This will work这将工作

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

Remove it using Craco:使用 Craco 删除它:

module.exports = {
  webpack: {
    configure: webpackConfig => {
      const scopePluginIndex = webpackConfig.resolve.plugins.findIndex(
        ({ constructor }) => constructor && constructor.name === 'ModuleScopePlugin'
      );

      webpackConfig.resolve.plugins.splice(scopePluginIndex, 1);
      return webpackConfig;
    }
  }
};

To offer a little bit more information to other's answers.为其他人的答案提供更多信息。 You have two options regarding how to deliver the .png file to the user.关于如何将 .png 文件交付给用户,您有两种选择。 The file structure should conform to the method you choose.文件结构应符合您选择的方法。 The two options are:这两个选项是:

  1. Use the module system ( import x from y ) provided with react-create-app and bundle it with your JS.使用 react-create-app 提供的模块系统( import x from y )并将其与您的 JS 捆绑在一起。 Place the image inside the src folder.将图像放在src文件夹中。

  2. Serve it from the public folder and let Node serve the file.public文件夹提供它,让 Node 提供文件。 create-react-app also apparently comes with an environment variable eg <img src={process.env.PUBLIC_URL + '/img/logo.png'} />; create-react-app 显然也带有一个环境变量,例如<img src={process.env.PUBLIC_URL + '/img/logo.png'} />; . . This means you can reference it in your React app but still have it served through Node, with your browser asking for it separately in a normal GET request.这意味着你可以在你的 React 应用程序中引用它,但仍然通过 Node 提供它,你的浏览器在普通的 GET 请求中单独请求它。

Source: create-react-app来源: 创建反应应用程序

There are a few answers that provide solutions with react-app-rewired , but customize-cra includes a removeModuleScopePlugin() API which is a bit more elegant.有一些答案提供了react-app-rewired解决方案,但customize-cra包含一个更优雅的removeModuleScopePlugin() API。 (It's the same solution, but abstracted away by the customize-cra package.) (这是相同的解决方案,但被customize-cra包抽象掉了。)

npm i --save-dev react-app-rewired customize-cra

package.json包.json

"scripts": {
    - "start": "react-scripts start"
    + "start": "react-app-rewired start",
    ...
},

config-overrides.js config-overrides.js

const { removeModuleScopePlugin } = require('customize-cra')

module.exports = removeModuleScopePlugin()

You need to move WC-BlackonWhite.jpg into your src directory.您需要将WC-BlackonWhite.jpg移动到您的src目录中。 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. public目录用于将直接链接到 HTML 中的静态文件(例如收藏夹图标),而不是您将直接导入到包中的内容。

I think Lukas Bach solution to use react-app-rewired in order to modify webpack config is a good way to go, however, I wouldn't exclude the whole ModuleScopePlugin but instead whitelist the specific file that can be imported outside of src:我认为Lukas Bach 解决方案使用react-app- rewired 来修改 webpack 配置是一个很好的方法,但是,我不会排除整个ModuleScopePlugin而是将可以在 src 之外导入的特定文件列入白名单:

config-overrides.js config-overrides.js

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

module.exports = function override(config) {
  config.resolve.plugins.forEach(plugin => {
    if (plugin instanceof ModuleScopePlugin) {
      plugin.allowedFiles.add(path.resolve("./config.json"));
    }
  });

  return config;
};

install these two packages安装这两个包

npm i --save-dev react-app-rewired customize-cra

package.json包.json

"scripts": {
    - "start": "react-scripts start"
    + "start": "react-app-rewired start"
},

config-overrides.js config-overrides.js

const { removeModuleScopePlugin } = require('customize-cra');

module.exports = function override(config, env) {
    if (!config.plugins) {
        config.plugins = [];
    }
    removeModuleScopePlugin()(config);

    return config;
};

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.此限制确保所有文件或模块(导出)都在src/目录中,实现在./node_modules/react-dev-utils/ModuleScopePlugin.js ,在以下代码行中。

// 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.或者eject然后从目录中删除ModuleScopePlugin.js
  3. or comment/remove const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');或注释/删除const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); from ./node_modules/react-scripts/config/webpack.config.dev.js来自./node_modules/react-scripts/config/webpack.config.dev.js

PS: beware of the consequences of eject . PS:注意eject的后果。

Image inside public folder公用文件夹内的图像

  use image inside html extension
  <img src="%PUBLIC_URL%/resumepic.png"/>

  use image inside  js extension
  <img src={process.env.PUBLIC_URL+"/resumepic.png"}/>
  • use image inside js Extension在 js 扩展中使用图像

I have had to overcome this same issue in Truffle.我不得不在 Truffle 中克服同样的问题。 The solution was as follows:解决方法如下:

ince Create-React-App's default behavior disallows importing files from outside of the src folder, we need to bring the contracts in our build folder inside src.由于 Create-React-App 的默认行为不允许从 src 文件夹外部导入文件,我们需要将我们的 build 文件夹中的合约放在 src 中。 We can copy and paste them every time we compile our contracts, but a better way is to simply configure Truffle to put the files there.我们可以在每次编译合约时复制和粘贴它们,但更好的方法是简单地配置 Truffle 以将文件放在那里。

In the truffle-config.js file, replace the contents with the following:在 truffle-config.js 文件中,将内容替换为以下内容:

const path = require("path");

module.exports = {
  contracts_build_directory: path.join(__dirname, "client/src/contracts")
};

I don't know if this helps you, but I know I found your question when I had the same issue in Truffle, and this might help someone else.我不知道这是否对您有帮助,但我知道我在 Truffle 遇到同样问题时发现了您的问题,这可能对其他人有所帮助。

Copy-Paste Typescript solution复制粘贴打字稿解决方案

(eg this will work for a CRA/TS stack, which requires an additional step compared to CRA/JS. The solution itself is not typed.) (例如,这将适用于 CRA/TS 堆栈,与 CRA/JS 相比,这需要一个额外的步骤。解决方案本身没有类型化。)

Adds the required paths to the ModuleScopePlugin instead of bluntly removing the plugin.将所需的路径添加到ModuleScopePlugin而不是直接删除插件。

This code below is using craco , but should be easily usable for react-app-rewired or similar solutions.下面的代码使用craco ,但应该很容易用于react-app-rewired或类似的解决方案。 You just need to find the spot where you have a webpackConfig object (react-app-rewired: module.exports.webpack inside your config-overrides.js ), and pass it to the provided functions.您只需要找到您拥有webpackConfig对象的位置(react-app- module.exports.webpack : module.exports.webpack在您的config-overrides.js ),并将其传递给提供的函数。

craco.config.js craco.config.js

const path = require("path");
const enableImportsFromExternalPaths = require("./src/helpers/craco/enableImportsFromExternalPaths");

// Paths to the code you want to use
const sharedLibOne = path.resolve(__dirname, "../shared-lib-1/src");
const sharedLibTwo = path.resolve(__dirname, "../shared-lib-2/src");

module.exports = {
    plugins: [
        {
            plugin: {
                overrideWebpackConfig: ({ webpackConfig }) => {
                    enableImportsFromExternalPaths(webpackConfig, [
                        // Add the paths here
                        sharedLibOne,
                        sharedLibTwo,
                    ]);
                    return webpackConfig;
                },
            },
        },
    ],
};

helpers/craco/enableImportsFromExternalPaths.js helpers/craco/enableImportsFromExternalPaths.js

const findWebpackPlugin = (webpackConfig, pluginName) =>
    webpackConfig.resolve.plugins.find(
        ({ constructor }) => constructor && constructor.name === pluginName
    );

const enableTypescriptImportsFromExternalPaths = (
    webpackConfig,
    newIncludePaths
) => {
    const oneOfRule = webpackConfig.module.rules.find((rule) => rule.oneOf);
    if (oneOfRule) {
        const tsxRule = oneOfRule.oneOf.find(
            (rule) => rule.test && rule.test.toString().includes("tsx")
        );

        if (tsxRule) {
            tsxRule.include = Array.isArray(tsxRule.include)
                ? [...tsxRule.include, ...newIncludePaths]
                : [tsxRule.include, ...newIncludePaths];
        }
    }
};

const addPathsToModuleScopePlugin = (webpackConfig, paths) => {
    const moduleScopePlugin = findWebpackPlugin(
        webpackConfig,
        "ModuleScopePlugin"
    );
    if (!moduleScopePlugin) {
        throw new Error(
            `Expected to find plugin "ModuleScopePlugin", but didn't.`
        );
    }
    moduleScopePlugin.appSrcs = [...moduleScopePlugin.appSrcs, ...paths];
};

const enableImportsFromExternalPaths = (webpackConfig, paths) => {
    enableTypescriptImportsFromExternalPaths(webpackConfig, paths);
    addPathsToModuleScopePlugin(webpackConfig, paths);
};

module.exports = enableImportsFromExternalPaths;

Taken from here and here 🙏取自这里这里🙏

You don't need to eject, you can modify the react-scripts config with the rescripts library不需要eject,可以用rescripts库修改react-scripts配置

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;
};

Adding to Bartek Maciejiczek's answer, this is how it looks with Craco:添加到 Bartek Maciejiczek 的回答中,这就是 Craco 的样子:

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

    module.exports = {
      webpack: {
        configure: webpackConfig => {
          webpackConfig.resolve.plugins.forEach(plugin => {
            if (plugin instanceof ModuleScopePlugin) {
              plugin.allowedFiles.add(path.resolve("./config.json"));
            }
          });
          return webpackConfig;
        }
      }
    };

If you only need to import a single file, such as README.md or package.json, then this can be explicitly added to ModuleScopePlugin()如果你只需要导入单个文件,比如 README.md 或 package.json,那么这可以显式添加到 ModuleScopePlugin()

config/paths.js配置/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配置/webpack.config.dev.js + 配置/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()
      ]),
    ]
  }
}

最好的解决方案是 fork react-scripts ,这实际上在官方文档中有提到,请参阅: Alternatives to Ejecting

If you need multiple modifications, like when using ant design , you can combine multiple functions like this:如果您需要多次修改,例如使用 ant design 时,您可以像这样组合多个功能:

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

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
  removeModuleScopePlugin(),
);

You can try using simlinks, but in reverse.您可以尝试使用 simlinks,但反过来。

React won't follow simlinks, but you can move something to the source directory, and create a simlink to it. React 不会遵循 simlinks,但您可以将某些内容移动到源目录,并创建一个指向它的 simlink。

In the root of my project, I had a node server directory that had several schema files in it.在我的项目的根目录中,我有一个节点服务器目录,其中包含多个架构文件。 I wanted to use them on the frontend, so I:我想在前端使用它们,所以我:

  • moved the files /src移动文件 /src
  • in the termal, I cd'ed into where the schema files belonged in server在终端中,我进入了模式文件在服务器中的位置
  • ln -s SRC_PATH_OF_SCHEMA_FILE

This gave react what it was looking for, and node was perfectly happy including files through simlinks.这给了反应它正在寻找的东西,节点非常高兴通过 simlinks 包含文件。

Came to the same issue in my project, and found this in the official create-react-app docs: https://create-react-app.dev/docs/using-the-public-folder/在我的项目中遇到了同样的问题,并在官方的 create-react-app 文档中找到了这个: https : //create-react-app.dev/docs/using-the-public-folder/

There is an "escape hatch" to add an asset outside the module system:有一个“逃生舱口”可以在模块系统之外添加资产:

If you put a file into the public folder, it will not be processed by webpack.如果将文件放入 public 文件夹,则 webpack 不会对其进行处理。 Instead it will be copied into the build folder untouched.相反,它将被原封不动地复制到构建文件夹中。 To reference assets in the public folder, you need to use an environment variable called PUBLIC_URL.要引用公共文件夹中的资产,您需要使用名为 PUBLIC_URL 的环境变量。

Here's an example they provide:这是他们提供的示例:

 render() { // Note: this is an escape hatch and should be used sparingly! // Normally we recommend using `import` for getting asset URLs // as described in “Adding Images and Fonts” above this section. return <img src={process.env.PUBLIC_URL + '/img/logo.png'} />; }

If you want to access CSS files from the public, you might face an error OUTSIDE OF SOURCE DIRECTORY如果你想从公共访问 CSS 文件,你可能会遇到一个错误OUTSIDE OF SOURCE DIRECTORY

Alternatively, you can link this file in index.html which also resides in the public directory.或者,您可以在index.html 中链接此文件,该文件也位于公共目录中。

<link rel="stylesheet" href="App.css">

Here's an alternative that works well in simple cases (using fs and ncp ).这是在简单情况下运行良好的替代方案(使用fsncp )。 While developing, keep a script running that watches for changes to your shared folder(s) outside of /src.在开发过程中,保持运行脚本以监视 /src 之外的共享文件夹的更改。 When changes are made, the script can automatically copy the shared folder(s) to your project.进行更改时,脚本可以自动将共享文件夹复制到您的项目中。 Here's an example that watches a single directory recursively:这是一个递归监视单个目录的示例:


// This should be run from the root of your project

const fs = require('fs')
const ncp = require('ncp').ncp;

ncp.limit = 16

// Watch for file changes to your shared directory outside of /src
fs.watch('../shared', { recursive: true }, (eventType, filename) => {
    console.log(`${eventType}: ${filename}`)

    // Copy the shared folder straight to your project /src
    // You could be smarter here and only copy the changed file
    ncp('../shared', './src/shared', function(err) {
        if (err) {
          return console.error(err);
        }

        console.log('finished syncing!');
    });
})

This is an issue with the relative import, which might have caused because we've used "create-react-app project" command which forms a directory named project with node_modules folder and several other files in public and src folders inside it.这是相对导入的一个问题,这可能是因为我们使用了“create-react-app project”命令,该命令形成了一个名为 project 的目录,其中包含 node_modules 文件夹以及其中 public 和 src 文件夹中的几个其他文件。 The create-react-app command puts a limitation that we can't import anything from outside src. create-react-app 命令有一个限制,即我们不能从 src 外部导入任何东西。

My Problem:我的问题:

  1. I had to import react-bootstrap css files which are created in node_modules folder outside the src folder.我必须导入在 src 文件夹外的 node_modules 文件夹中创建的 react-bootstrap css 文件。
  2. I used import "../node_modules/bootstrap/dist/css/bootstrap.min.css";我使用了 import "../node_modules/bootstrap/dist/css/bootstrap.min.css"; but I got the error on terminal.但我在终端上遇到了错误。
  3. I found out that I can create a new react app and follow solution steps from A to G, in order to fix this issue.我发现我可以创建一个新的 React 应用程序并按照从 A 到 G 的解决方案步骤来解决这个问题。

Solution: A) Create a new react app, using create-react-app new解决方案:A)创建一个新的反应应用程序,使用 create-react-app new

B) cd new B) 新光盘

C) run this command: "npm install react-bootstrap bootstrap@4.6.0" (without the "" double quotes ) C)运行这个命令:“npm install react-bootstrap bootstrap@4.6.0”(没有“”双引号)

D) in your react file put this to import bootstrap: D.1) import "../node_modules/bootstrap/dist/css/bootstrap.min.css"; D) 在你的反应文件中把它导入 bootstrap: D.1) import "../node_modules/bootstrap/dist/css/bootstrap.min.css"; or D.2)import Button from "react-bootstrap/Button";或 D.2) 从“react-bootstrap/Button”导入按钮;

E) create a bootstrap element like a Button or anything in your react file, for D.1) < button className="btn btn-success" > Bootstrap < /button> or for D.2) < Button variant="primary"> Bootstrap < /Button> E) 为 D.1) < button className="btn btn-success"> Bootstrap </button> 或 D.2) < Button variant="primary" 创建一个引导程序元素,例如 Button 或您的反应文件中的任何内容> 引导程序</Button>

F) in terminal: cd src F) 在终端:cd src

G) in terminal: npm start, G)在终端:npm start,

this time it will be compiled successfully.这次就编译成功了。

Reasoning: I could see react-bootstrap working finally once I followed steps A to G in order, and this time I didn't get any error.推理:一旦我按顺序执行步骤 A 到 G,我就可以看到 react-bootstrap 终于工作了,这次我没有收到任何错误。 (I thought of this solution because: (我想到了这个解决方案,因为:

  1. I've used npm install "@material-ui/icons" and that got installed in the node_modules folder outside the src.我使用了 npm install "@material-ui/icons" 并将其安装在 src 之外的 node_modules 文件夹中。
  2. In my react file I've used import Add from "@material-ui/icons/Add"在我的反应文件中,我使用了 import Add from "@material-ui/icons/Add"
  3. and Material-ui icons were working fine for me, but here also we are importing from outside src, from node_modules.. and everything works fine.和 Material-ui 图标对我来说很好用,但在这里我们也从外部 src 导入,从 node_modules .. 一切正常。 Why there is no error of importing from outside src this time)为什么这次从外部src导入没有错误)
  4. That's why I just created a new react app, and followed solution steps A to G.这就是为什么我刚刚创建了一个新的 React 应用程序,并遵循解决方案步骤 A 到 G。

This can be done directly without using the path to the public folder.这可以直接完成,而无需使用公用文件夹的路径。 You can do it like你可以这样做

<img src="/images/image-name" alt=""/>

This happens because we do not use App.js in the browser, in the browser only index.html is executed, and the path to images is already in the public folder containing index.html file发生这种情况是因为我们在浏览器中没有使用 App.js,在浏览器中只执行了 index.html,并且图片的路径已经在包含 index.html 文件的公共文件夹中

If you want to set a background image using CSS.如果要使用 CSS 设置背景图像。 So you have to set the image using the URL of your's localhost and add the path of your image.因此,您必须使用本地主机的 URL 设置图像并添加图像的路径。 Just see the example below.请看下面的例子。

.banner {
  width: 100%;
  height: 100vh;
  background-image: url("http://localhost:3000/img/bg.jpg");
  background-size: cover;
  background-repeat: no-repeat;
}

So apparently, using Create-react-app will restrict you from accessing Images outside the root directory of your project - usually src .显然,使用Create-react-app将限制您访问项目根目录之外的图像 - 通常是src

A quick fix for this is to move your images from the public folder to the src folder and you are good to go.对此的快速解决方法是将您的图像从public文件夹移动到src文件夹,您就可以开始了。
So your code will be like this for example:所以你的代码会是这样的,例如:

background-image: URL('/src/images/img-2.jpg');

Posting here what @Flaom wrote as a comment in the marked as reply answer and that actually saves lives:在这里发布@Flaom 在标记为回复答案中作为评论写的内容,这实际上可以挽救生命:

"How is this the accepted answer? This bogus restriction is trivially eliminated by simply setting NODE_PATH=./src/.. in the .env file. By doing so, you can import from outside of the src folder without going through the pain associated with ejecting your app. " “这是如何被接受的答案?只需在 .env 文件中设置 NODE_PATH=./src/.. 就可以轻松消除这种虚假限制。通过这样做,您可以从 src 文件夹外部导入,而无需经历相关的痛苦弹出你的应用程序。”

  • Flaom火焰

EDIT Added some more info as @cigien requested.编辑根据@cigien 的要求添加了更多信息。

All the answers above describe very well why we cannot use an image from the public folder when we create our react app with the create-react-app.上面的所有答案都很好地描述了为什么当我们使用 create-react-app 创建我们的 React 应用程序时我们不能使用来自公共文件夹的图像。 Having the issue myself and reading all these answers I realized that, what the answers say is to "hack" the app in order to remove the module that restricts us.我自己遇到了这个问题并阅读了所有这些答案,我意识到,答案是“破解”应用程序以删除限制我们的模块。 Some of the answers don't even have an undo option.有些答案甚至没有撤消选项。 For a "training" application that is ok.对于可以的“培训”应用程序。

Personally I would not want to add a solution that alters the concept of the app to my own project, specially in a commercial one.就我个人而言,我不想在我自己的项目中添加一个改变应用程序概念的解决方案,特别是在商业项目中。 @Flaom solution is the simplest and if anything change in the future it can be replaced with another solution. @Flaom 解决方案是最简单的,如果将来有任何变化,可以用另一种解决方案替换。 It has no risk, it can be removed anytime and is the simplest.它没有风险,可以随时删除,而且是最简单的。

I could import files outside of src/ by "copying" the outside files with file: as local dependency.我可以通过使用file:作为本地依赖项“复制”外部文件来导入src/之外的文件。

"dependencies": {
    "@my-project/outside-dist": "file:./../../../../dist".
}

then然后

import {FooComponent} from "@my-project/outside-dist/components";

No eject or react-app-rewired or other 3rd-party solution was needed.不需要ejectreact-app-rewired或其他 3rd 方解决方案。

This was my code:这是我的代码:

import React from 'react';

import './Navbar.scss';
import {images} from '../../constants';
const Navbar = () => {
    return (
        <nav>
            <div>
                < img src = {images.logo} alt = "logo" />

            </div>

        </nav>
    );
}

export default Navbar;

Changed it too:也改了:

import React from 'react';

import './Navbar.scss';
import {images} from '././constants';
const Navbar = () => {
    return (
        <nav>
            <div>
                < img src = {images.logo} alt = "logo" />

            </div>

        </nav>
    );
}

export default Navbar;

And it worked!它奏效了! Im getting better at fixing bugs haha.我越来越擅长修复错误哈哈。

If you file reside in public folder and if you want to import it without eject or without using react-app-rewired then in that case you can access file via domains name and the path of the file and using axios.如果您的文件位于公共文件夹中,并且如果您想在不弹出或不使用 react-app-rewired 的情况下导入它,那么在这种情况下,您可以通过域名和文件路径并使用 axios 访问文件。 Example: There is a font file called favico.ico located inside public folder.示例:在 public 文件夹中有一个名为 favico.ico 的字体文件。 You want to import it in one the file located in src.您想将其导入位于 src.xml 的文件中。 You can access the font using following logic.您可以使用以下逻辑访问字体。

axios.get('example.com/favico.ico').then(() => {
  // here you can access this file.
})

In above example example.com is domain.在上面的示例中 example.com 是域。 If you have different environment like localhost, staging, production then in that case the domain name is different.如果您有不同的环境,如本地主机、登台、生产,那么在这种情况下,域名是不同的。 So, to get the favico.ico you can use following logic.因此,要获取 favico.ico,您可以使用以下逻辑。

axios.get(`${window.location.origin}/favico.ico`).then(() => {
  // here you can access this file.
})

In above example you window.location.origin give you current domain meaning if you run your code locally then, it will give you http://localhost:{portnumber}, If your code run on production and production domain is example.com then, it will give you "example.com".在上面的示例中,如果您在本地运行代码,window.location.origin 会为您提供当前域含义,它将为您提供 http://localhost:{portnumber},如果您的代码在生产和生产域上运行,那么 example.com ,它会给你“example.com”。 So using this pattern you can access assets located in public folder.因此,使用此模式,您可以访问位于公共文件夹中的资产。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 create-react-app中的src / images文件夹 - src/images folder in create-react-app 在 create-react-app 中解构依赖项导入对性能更好吗? - Is better for performance to destructure dependency imports in create-react-app? 如何在 craco 中使用 create-react-app 目录之外的 js 文件? - How to use a js file from outside of create-react-app directory, with craco? 如何使 svg 从使用 create-react-app 的外部模块导入组件? - How to make svg react component imports from external module working with create-react-app? ESLint 仅针对特定目录(eslintrc、create-react-app) - ESLint only target a specific directory (eslintrc, create-react-app) 带有 Create-react-app 的 Cordova - Cordova with Create-react-app Create-React-App 在 src 中添加文件夹“找不到模块:无法解析” - Create-React-App adding folders inside src 'Module not found: can't resolve' reactjs create-react-app在src文件夹中缺少index.html - reactjs create-react-app missing index.html in src folder 当我们 create-react-app 时,BUILD DIR 中的 HTML 如何链接到 SRC DIR 中的 JS? - How HTML in BUILD DIR is linked to JS in SRC DIR when we create-react-app? Jest 和 Create-react-app:不能在模块外使用 import 语句 - Jest and Create-react-app: Cannot use import statement outside a module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM