Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
gaearon opened this issue Oct 3, 2016 · 25 comments
Closed
Milestone

Comments

@gaearon
Copy link
Contributor

gaearon commented Oct 3, 2016

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
@gaearon gaearon added this to the 1.0.0 milestone Oct 3, 2016
@wdhorton
Copy link
Contributor

Are you thinking this be implemented with an ESLint rule?

@jasonszhao
Copy link

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.

@gaearon
Copy link
Contributor Author

gaearon commented May 8, 2017

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.

@Timer
Copy link
Contributor

Timer commented May 17, 2017

done in #2189; a61be9c

@Timer Timer closed this as completed May 17, 2017
@dnsorlov
Copy link

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

@gaearon
Copy link
Contributor Author

gaearon commented May 20, 2017

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

@Timer
Copy link
Contributor

Timer commented May 20, 2017

I believe supporting package.json is reasonable.

@a-tokyo
Copy link

a-tokyo commented Jun 13, 2017

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.

@shaneosullivan
Copy link

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)?

@Hurtak
Copy link
Contributor

Hurtak commented Dec 2, 2017

What is currently the best solution to import components across CRA apps in monorepo?
Yarn workspaces, symlinks?

@rolandjitsu
Copy link

I was also wondering what do you do in cases with monorepos and multiple cra apps that want to import from a shared packages folder and have ts path mappings?

Because it currently does not work.

@devictoribero
Copy link

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

@Frexuz
Copy link

Frexuz commented Mar 8, 2018

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 :/

@Oroneki
Copy link

Oroneki commented May 3, 2018

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

@Timer
Copy link
Contributor

Timer commented May 3, 2018

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

@francistito
Copy link

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/.

@bugzpodder
Copy link

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

@devxpy
Copy link

devxpy commented Jun 5, 2018

@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!

@augnustin
Copy link

augnustin commented Jul 13, 2018

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

@augnustin
Copy link

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

@devxpy
Copy link

devxpy commented Jul 13, 2018

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

@devxpy
Copy link

devxpy commented Jul 13, 2018

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

@devxpy
Copy link

devxpy commented Jul 13, 2018

related issue

@devxpy
Copy link

devxpy commented Jul 13, 2018

related medium article

@kopax
Copy link

kopax commented Jan 12, 2019

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!

@lock lock bot locked and limited conversation to collaborators Jan 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests