Open FelixKuehl opened 6 years ago
Hey @FelixKuehl, we're really sorry about this! As mentioned in https://github.com/facebook/create-react-app/issues/5024, our monorepo support was incomplete and we think it would create more issues for our users in long term if we shipped it in that state. On the other hand, the 2.x branch has stalled for many months, and we were worried it would never get shipped. So we made a difficult decision to remove some of the features that existed in 2.0 earlier alphas in order to ship a stable 2.0 within two weeks.
We'll offer migration strategies that you could use to unblock your migration to 2.x, but they'll likely include introducing another compiler like nwb
for packages outside the main one. We are also open to more proposals about monorepo support, except that if we land it next time it would need to be a more complete one.
Hey @gaearon, thank you for your fast reply. This actually is quite a bummer for our current setup. We did enjoy developing cra powered applications in a monorepo due to the flexibility and the productive development workflow it gave us. Personally I have no experience with nwb
or similar. Wouldn't it be possible to at least support Yarn Workspaces to be able to share components between applications? I feel like this is quite an important feature when developing multiple applications, that have shared elements.
Do you have migration proposals written down already? Having to use an intermediate compiler feels like it would come with a lot of configuration work and some serious pitfalls.
Yeah I understand why it's useful very well. It was just half-baked, especially with regards to how testing works, or how to opt out certain packages from compilation.
@Timer can give you some pointers.
@gaearon Thanks for explaining. I will take a look at projects like nbw
and create-react-library
to transpile our library code. I am especially worried about sass and css-modules. Would be great to get a hint on your future roadmap / ideas regarding this topic. Every pointer would be helpful @Timer ;)
Hey @FelixKuehl! I'll probably be drawing up some more extensive documentation here soon. I'll post here when it's ready.
As an Update for all those having the same issue:
I gave create-react-library
a try and it did a decent job as a drop-in solution without a lot of manual adjustments.
However it comes with some caveats:
Another problem I stumbled across, that might be interesting for @Timer's migration proposals or create react app itself, was the way ESLint handles locally symlinked dependecies. With cra's current ESLint setup, everything within the "node_modules" folder gets ignored by ESLint as expected. However, if a dependency is symlinked locally (Yarn Workspace, Lerna, npm link, etc.) the path is resolved first and then checked against the eslintignore settings and therefore not excluded from linting. This results in ESLint errors showing up in your create react app when consuming a locally linkend library (Or more precisely its "dist" folder). A quick fix for this was using babel-plugin-eslint-disable
. However I do not see any use case where you would want to lint a dist folder, so adding **/dist*
to the default eslintignore would be a more defensive solution. Or am I missing something?
I will take a look at nbw
now and see how this integrates.
Hmm, ESLint resolving symlinks sounds like a bug. Can we turn this feature off?
This bug is referenced in https://github.com/webpack-contrib/eslint-loader/issues/165, https://github.com/webpack-contrib/eslint-loader/issues/202 and https://github.com/webpack/webpack/issues/985. I am not a webpack expert but setting symlinks: false
in the webpack config or adding **/dist/*
to eslintignore could work. Would need to test this though.
@Timer following @gaearon's suggestion, I spend the last day experimenting with nwb as a compiler. The setup I came up with, seemed quite decent to me. I put up an example repo here: https://github.com/FelixKuehl/cra-monorepo Maybe this can help you out a bit or gets you some ideas for your documentation. Let me know if I can do anything to help.
So what did I do? (See https://github.com/FelixKuehl/cra-monorepo/blob/master/README.md for details)
Using nwb as a compiler seemed quite intuitive. However it did require some configuration in order to work with create react apps features, such as CSS Modules, SASS, etc. Also, I wanted to have a dev server / watcher, that handles recompiling on code changes.
All this can be found in the library-utils
package within the example repository. These utils provide a nwb (and Storybook) config, that works quite well when the components are targeted at being consumed by a create react app.
In order to have a decent development workflow, I build the library-utils build:watch
and library-utils start
scripts. The first one starts a custom nodemon based watcher, that automatically recompiles the library on changes in the src folder and the second one starts this watcher together with a storybook server. This feels quite convenient when developing.
When having multiple libraries in the monorepo you can now simply run lerna exec -- yarn run build:watch
to start a single terminal application that watches all the packages that have the "build:watch": "library-utils build:watch"
script in their package.json.
The watcher simply transpiles all the components and copies the assets for the create react app to bundle.
Again for details just take a look at the linked example repository above or just ask me :)
Hope this might help a bit.
Form commit https://github.com/FelixKuehl/cra-monorepo/commit/0d21eb5534dfa5a13d90282af55f91429baa4738 on, this repo uses babel to watch and compile the libraries. Also I switched to using Styleguidist over Storybook.
@FelixKuehl in terms of performance, a couple of questions:
create-react-app
automatically refresh the page when running in dev mode?I currently using a babel --watch to achieve this rather than nwb (haven't had time to evaluate nwb/create-react-library) and it works fine from limited testing. (obviously you'll need your own babel config).
@mattfysh
- when a change is detected in a source dependency, are the whole contents of that package recompiled, or just the file that changed?
At the moment it is recompiling the entire library on every code change. Sadly this cannot really be avoided when using nwb. It would be trivial to detect changes to assets and css / scss files (nodemon does that automaticly) and copy those without any recompilation. That would also enable the create react app to show style changes without recompiling. I am currently trying a babel --watch
setup, as @bugzpodder suggested. Using babel directly feels much more performant, but of course compromises the advantages of nwb. To be honest this feels like a simpler and faster approach. (Until nwb findes a way of making their babel work in watch mode)
- does
create-react-app
automatically refresh the page when running in dev mode?
Yes ist does.
I will update the example repo once I am happy with my final solution. At the moment I feel like I am going to build a simple container around a babel watch process.
@bugzpodder At first I kind of liked the idea of using a library like nwb over using babel directly but
rm -rf es && NODE_ENV=production babel -w --presets=react-app src --out-dir es --copy-files --ignore __tests__,spec.js,test.js,__snapshots__
pretty much gets the job done.
Hello all! I have been searching for a solution to my problem, and this seems to be the most relevant. Please let me know if this doesn't fit with this open issue.
I am building two separate repositories. One will be a page which will import other React Components as npm packages once published. So currently I have a local repository that depends on another. For development, I am attempting to link them with npm link
.
.../Code/A/MyComponent/src/TL
.../Code/A/MyApp/src
npm create-react-app MyApp
npm link
, starting with MyComponent
, then running npm link MyComponent
in MyApp
MyComponent
node_module in MyApp
.MyComponent
in MyApp
, received Syntax error
Unexpected token
at the beginning of MyComponent
's JSX code.npm run transpile
in MyComponent
to create a dist
directory.npm start
now, I receiv this message: Error: Failed to compile.
.../MyApp/src/App.js
:Module not found: Can't resolve 'A/MyComponent' in '.../Code/A/MyApp/src'
I tried adding symlinks: false
here in node_modules/react-scripts/config/webpack.config.js
:
module.exports = function(webpackEnv) {
return {
resolve: {
symlinks: false,
}
}
}
This did not help.
This seems to be either a Babel or Webpack issue concerning npm link
. I imagine MyApp
is either not being pulled together by Webpack and/or not being compiled by Babel.
An update on my issue for future reference if someone may have a similar issue:
The code for the MyComponent
React component was showing up and being unrecognized (as in my #4 in Circumstances). This was because I had yet to build
the code. I ran npm build
and re-did the npm link
process, and this works.
Hopefully that was clear and helpful.
I have a similar error but @irmerk solution did not work for me. I just simply get a syntax error.
I have got the issue (ref: https://stackoverflow.com/questions/56680612/react-script-compatibility-issue-with-third-party-node-module) which is very similar to @irmerk
if anyone got this issue resolved please help here.
@gaearon @Timer i am not sure if this is out of the scope of cra 2.1.8 because this issue look like babel/webpack config issue and in cra we are not suppose to make any changes in config.
I have got the exact issue as @chrisdel101 . Any updates on resolving the compilation error?
We've had quite some time figuring this one out, but I think we found the reason and solution. Check this out guys - I bet you'll be blown away.
So, when CRA tries to transpile your package, it uses babel to transpile JSX code to commonjs. Last versions of babel transpilers have big troubles with unnamed exports. So when you try and import your default as unnamed export (for example export default YourComponent
), it throws an error.
But we do not see this error, 'cause of CRA bundle. This error shows in console, for example, when we try and configure babel with webpack in monorepo by hand.
The solution, that worked for me and my colleagues is this one:
make package structure like this
YourPackage
|-src
| |-index.js
|-index.js
Export your component or module code in /src/index.js as a default export (export default YourComponent
)
In root index.js export your component as follows
export { default as YourComponent } from './src/index.js'
you can import your component in consumer app like this:
import {YourComponent} from YourPackage
(plus the namespace, of course)
And that's it. This worked for us beautifully.
Special thanks to this hero, https://github.com/aivtel who actually solved the problem. My part was in pointing where to look and why this unfortunate issue was happening in the first place.
I have the same issue integrating with react native mono repo. It has issues with external libraries in the react native repo, and I also had the suggested structured
YourPackage
|-src
| |-index.js
|-index.js
But it doesn't work because it is symlinked by lerna.
any updates?
Spent a day to work out this heap of crap. Why is the React eco system so f__ked? Back to Vue I go.
any updates on this?
any updates? getting the following error when importing from own npm package containing jsx:
I have the same issue when using a component from node_modules. Error is not happening when loading the component from the current working project itself.
Module parse failed: Unexpected token (38:15)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| return;
| }
> return <HeaderMenuButton aria-label="Open menu" onClick={onClickSideNavExpand} isActive={isSideNavExpanded}/>;
| }
| const searchBar = props.search ?
When I change App.js
to App.jsx
, the error message is slightly different.
./node_modules/@...my-vendor.../style-guide/src/components/Header/Header.js
SyntaxError: C:\foo\node_modules\@...my-vendor...\style-guide\src\components\Header\Header.js: Support for the experimental syntax 'jsx' isn't currently enabled (38:16):
36 | return;
37 | }
> 38 | return <HeaderMenuButton aria-label="Open menu" onClick={onClickSideNavExpand} isActive={isSideNavExpanded}/>;
| ^
39 | }
40 | const searchBar = props.search ?
It seems that this is all expected behavior, as Dan aka @gaearon says here https://github.com/facebook/create-react-app/issues/5103#issuecomment-425459196.
We only compile valid JavaScript syntax in node_modules. JSX is not valid JavaScript. You are using JSX there.
So this issue will likely never be solved within create-react-app. The external library maintainer should serve a transpiled code i guess.
Also see https://stackoverflow.com/a/57762228/4840661:
the duty is on package developers to distribute an npm package with standard JavaScript features.
A different alternative would be to adjust Webpack config (only possible with ejected CRA).
Is this a bug report?
Yes
Did you try recovering your dependencies?
Yes
Which terms did you search for in User Guide?
(Write your answer here if relevant.)
Environment
Running
npx create-react-app --info
does not seem to work. Getting:However I am using: Node v8.11.3 Yarn 1.9.4 npm 6.4.1 react-scripts 2.0.0-next.2150693d
Steps to Reproduce
This used to work with react-scripts 2.0.0-next.a671462c
Expected Behavior
The app should compile just fine as it used to in 2.0.0-next.a671462c
Actual Behavior
Application fails to compile with "Syntax error: Unexpected token" in the component, that was attempted to be imported from the other application.
To me it seems like the babel loader is somehow not transpiling the imported component.
Reproducible Demo
https://github.com/FelixKuehl/cra-alpha-issue-example