Skip to content

Completely disallow importing from outside of src/, packages/ or node_modules/ #834

Closed

Description

@gaearon

There shouldn’t be multiple conflicting ways to do the same thing. Currently we allow importing JS from anywhere but we don’t process it with Babel if it is outside src. This is slightly confusing and inconsistent. It also allows invalid/unsupported patterns like importing from public folder (which exists for a completely different purpose), or from build.

After #741 is implemented and we have a first-class support for multiple top-level modules in a single repo, I think we should completely disallow importing JS or assets from anywhere else. Then we would have a clear picture of what each directory is for:

node_modules # JS unprocessed by Babel, third party modules
src # JS processed by Babel, entry point
packages # JS processed by Babel, additional self-contained "packages"
public # escape hatch for non-module assets, never processed
build # build output, never processed
<other folders> # docs and other resources, never part of build output

Activity

  1. added this to the 1.0.0 milestone on Oct 3, 2016
  2. wdhorton commented on Oct 11, 2016

    @wdhorton
    Contributor

    Are you thinking this be implemented with an ESLint rule?

  3. jasonszhao commented on May 3, 2017

    @jasonszhao

    The lack of Babel processing for importing outside of the src folder makes it harder for me to use code shared between the server and browser. I have three sibling folders: server, client, and shared. My current workaround is making a tiny change in CRA's webpack config to process the code in shared.

  4. gaearon commented on May 8, 2017

    @gaearon
    ContributorAuthor

    Importing outside of src is not and has never been supported at all.
    This is mentioned in the documentation.

    I understand the difference is annoying, but you are just relying on unintentional behavior.

    I have three sibling folders: server, client, and shared.

    This is not really a supported way of using CRA. The supported way is to keep the project generated by CRA in the client folder.

  5. Timer commented on May 17, 2017

    @Timer
    Contributor

    done in #2189; a61be9c

  6. dnsorlov commented on May 20, 2017

    @dnsorlov

    @gaearon, if I want to import version from package.json, what should I do?

  7. gaearon commented on May 20, 2017

    @gaearon
    ContributorAuthor

    Maybe we could add an exception for this use case. @Timer thoughts?

  8. Timer commented on May 20, 2017

    @Timer
    Contributor

    I believe supporting package.json is reasonable.

  9. a-tokyo commented on Jun 13, 2017

    @a-tokyo

    I think some web apps would like to import the version number, or the dependencies used by the project to list somewhere. That's why I believe supporting package.json is reasonable.

  10. shaneosullivan commented on Oct 22, 2017

    @shaneosullivan

    What's the suggested solution for the following setup:

    I have two CRA-created apps. They each need a number of shared custom components that I also wrote. Do I need to

    (a) Host these component files in one app, and manually/scripted copy them over into the src folder of the other app every time I change them?
    (b) Store them in a separate sibling folder and reach outside the app? eg..

    • /app1/src/
    • /app2/src/
    • /shared/

    I understand that (b) is forbidden. Does that just leave me with (a)?

  11. 2 remaining items

  12. devictoribero commented on Feb 19, 2018

    @devictoribero

    What about if I want do distinct my real CORE (application) than the other things? (source).
    I had the idea to put my entities and domain servives inside the /app and... inside /src all the mvvm files. Like components, scenes, actions, etc... @gaearon

  13. Frexuz commented on Mar 8, 2018

    @Frexuz

    We're also looking into this problem with our monorepo, as we're finishing our RN app, and moving into building the web, wanting to re-use as much as possible :/

  14. Oroneki commented on May 3, 2018

    @Oroneki

    I am having the same problem. I want to reuse components across my electron, web and RN projects.

  15. Timer commented on May 3, 2018

    @Timer
    Contributor

    2.0 beta adds monorepo support, you can give it a try.

  16. francistito commented on Jun 1, 2018

    @francistito

    i have the same problem. My create-react-app has client directory with src file and but when i try to import models which are outside the client file
    ./src/App.js Module not found: You attempted to import ../models/users which falls outside of the project src/ directory. Relative imports outside of src/ are not supported. You can either move it inside src/, or add a symlink to it from project's node_modules/.

  17. bugzpodder commented on Jun 1, 2018

    @bugzpodder

    @dontito94 at this point, I recommend the prompt suggestion (ie move models/ into src/)

  18. devxpy commented on Jun 5, 2018

    @devxpy

    @jasonszhao I am working on a project that allows you to do this.

    React Pages

    It has the concept of pages, which are basically multiple src directories inside a single ejected create-react-app project.

    Your comments and bug reports are highly appreciated!

  19. augnustin commented on Jul 13, 2018

    @augnustin

    Same issue here: some shared code between several projects in a sibling folder.

    We've implemented the symlink logic, it is working okay, but here are several downsides I see:

    • needs an extra watch process to compile files from the shared folder => not too bad
    • generates built files, which appear in my text editor file selection => can be configured out, but annoying out-of-the-box
    • needs another package.json, with its own dependencies, which - want it or not - is code duplication. When we upgrade any package (eg. react, babel presets etc.), we must think of doing the same for the shared folder ... hence for all dependent folders also => this is the biggest point IMHO, it would work for code written as modules, but this is not always the case for shared code, especially for components, which can have several dependencies
    • imports are more obscure: import { exportName } from 'shared-package' is less readable than import {exportName} from '../shared/utils/string'. In the latter, I know I'm requiring the string utility file => there might be a way around this, but don't know it for now

    On the other hand, I have implemented an alias logic, this way:

    // webpack.config.dev.js
    
        alias: {
          shared: path.resolve(__dirname, '../../shared/src'),
        },
        plugins: [
          // commented the scope checker plugin
          // new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
        ],
    

    then I can write:

    import { exportName } from 'shared/utils/string'
    

    and it is compiled in the bundle (checked it).

    This feels much cleaner for me, as this circumvents all the above points. There shall be some reason for not encouraging this, but I can't think of any for now. Any insight?

    Cheers

  20. augnustin commented on Jul 13, 2018

    @augnustin

    @devxpy could you detail how you would do that? I can't see how. Thanks

  21. devxpy commented on Jul 13, 2018

    @devxpy

    @augnustin I removed my comment because I don't correctly understand your directory structure, and it might not work for you.

  22. devxpy commented on Jul 13, 2018

    @devxpy

    I do it automatically using .env file in react-pages.

  23. devxpy commented on Jul 13, 2018

    @devxpy
  24. devxpy commented on Jul 13, 2018

    @devxpy
  25. kopax commented on Jan 12, 2019

    @kopax

    Hi, I have a project that I can't install with npm install but is in dependencies, I have tried babel-plugin-resolve-loader and webpackConfig.resolve.alias but each time I do hook my source, I have :

    Module not found: You attempted to import /home/dka/workspace/module/bootstrap-styled/ra-ui/examples/demo/data-generator/examples/data-generator which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
    

    I know I have been using alias before without the need to eject (craco, react-app-rewired), why do I have this message?
    Thanks!

  26. locked and limited conversation to collaborators on Jan 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions