Open subhero24 opened 6 years ago
@RandScullard hi and no I don't. It works fine with the dependency being just inside editor (which in turn imports another workspace package that uses prosemirror-model
). Anyway, installing the deps for the CRA would be even more annoying than just adding aliases so I'll let my hack stand in my repo. But thanks though for the explanation!
I just had to add another thing to my overrideWebpackConfig for my TypeScript project:
const tscheckerPlugin = getPlugin(webpackConfig, pluginByName("ForkTsCheckerWebpackPlugin"))
tscheckerPlugin.match.options.reportFiles.splice(0)
Explanation: ForkTsCheckerWebpackPlugin
does the TypeScript type checking in the webpack build. The default webpack config sets the reportFiles
option for this plugin to filter out errors from anywhere outside the local project1. As a result I did not get any TypeScript compiler errors from my shared project, only from my main project. My solution is just to clear out the reportFiles array so there is no filtering of errors. (This might be too broad a brush for your project and you may find it preferable to modify the array to leave some of the filters in place.)
1 This is the default value for reportFiles:
[
'../**/src/**/*.{ts,tsx}',
'**/src/**/*.{ts,tsx}',
'!**/src/**/__tests__/**',
'!**/src/**/?(*.)(spec|test).*',
'!**/src/setupProxy.*',
'!**/src/setupTests.*',
]
All this to try to get symlinks to work the way the OS designers intended them to work?
Surely, this needs re-evaluation on the part of CRA? If an application developer is creating symlinks, he/she probably has a good reason - I don't think its right to second guess them.
All this to try to get symlinks to work the way the OS designers intended them to work?
FWIW, I used the techniques described in this issue to get my shared module working without symlinks. Rather than symlinking my shared module into my main project, I have it linked in my package.json like so:
"atclient-shared": "file:../../ATClientShared",
Thanks @RandScullard - yes, there are workarounds but they shouldn't really be necessary. I sometimes use a similar workaround to the one you describe but HMR doesn't work; package manager caching gets in the way. I have to delete node_modules and/or clean caches when updating components - all very unproductive.
Hi @RandScullard, Just wanted to confirm, are you using CRA v5.0.0?
Since I've upgraded my code to v5.0.0 none of the above workarounds seem to work.
To get rid of the duplicates, I had to remove duplicated packages from the main app and rely on the nested dependencies of linked packages.
@hasan-aa I am not using CRA v5, I am still on 4.0.3. I am waiting to upgrade until craco fully supports v5. (https://github.com/gsoft-inc/craco/issues/378)
I have taken a look at the changes to webpack.config.js in CRA v5 and I can tell you that the workarounds above will definitely have to be modified to be compatible with the new config. I believe they still can be made to work, but not exactly as shown above.
Hi @RandScullard Thanks for the clarification.
It turned out the caching behavior was making it almost impossible to debug. If the previous build was creating duplicate modules, even if you fix the configuration and build again, it was still resolving the wrong modules due to the cache I believe.
Once I enable memory cache, it became debuggable and now it's working fine.
config.resolve.cache = true;
(memory cache)
By the way, my solution is to move 'node_modules' to second position in the config.resolve.modules
array so that the project node_modules folder takes the precedence:
before:
config.resolve.modules:["node_modules", "path/to/project/node_modules"]
after
config.resolve.modules:["path/to/project/node_modules", "node_modules"]
For the ones hoping for a fix for webpack and when you npm link
a package you will have to do the following.
It seems like when you have a linked package npm link "myPackage"
(you are creating a symlink) this does not get properly resolved by the following line
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
To fix npm link
packages not updating on your main directory you have to do the following:
/config/webpack.config.dev.js
{
resolve: {
symlinks: true,
}
}
/config/webpack.config.dev.js
{
test: /\.(js|jsx|mjs)$/,
include: [paths.appSrc, paths.myPackage],
use: {
...
}
}
/config/paths.js
(the resolveRealPathApp
will also work in a production build as it will just get the normal package, and not follow the symlinked one)
const resolveRealPathApp = relativePath => fs.realpathSync(process.cwd() + relativePath)
/config/paths.js
file
module.exports = {
...
myPackage: resolveRealPathApp('/node_modules/myPackage')
};
Catches:
Verify that you are not ignoring the folders in the /config/webpackDevServer.config.js
file
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
}
Has any progress been made on this issue? I was using symlinks as a way to share interfaces between my Firebase Cloud Functions project and its React frontend project, but was surprised to find that as soon as I added enums everything broke (similar to the issue that @ali-wetrill was having above). Unfortunately, all the workarounds above seem to rely on unmaintained stuff, with react-app-rewired, customize-cra, and craco all not supporting CRA 5.0. If not, does anyone have any alternative suggestions for how to achieve the same thing?
It's a decades old trick to symlinks to a single source directory for multiple architecture builds. This issue has broken that for me. 👎
FWIW, I've added a small cp -a ../shared src/
command to all my NPM commands in package.json
and added the src/shared
under every project to their .gitignore
file to work around the issue. From CRA's perspective, it's just a file and you still get to maintain a single copy for multiple projects.
FWIW, I've added a small
cp -a ../shared src/
command to all my NPM commands...
I've elaborated on this solution by using watch
to monitor the files (the source and destination) and rerun rm -rf and copy commands to sync destination with source if they are changed in either location (rsync is not universally available). I then run this in parallel with react scripts like start
and test
, which support live loading. This means the live coding aspect is fully inclusive of the shared files and the files are protected from being edited in the wrong place. React picks up the overwriting of the files in destination as file edits and refreshes them as you'd hope.
npm install --save-dev watch
This is what my script look like:
"scripts": {
"watch-shared": "watch \"rm -rf src/shared && cp -a ../other-project/shared/ src/\" ../other-project/shared src/shared --ext ts",
"sync-shared": "rm -rf src/shared && cp -a ../other-project/shared/ src/",
"start": "run-p watch-shared start-react",
"start-react": "react-scripts start",
"build": "run-s sync-shared build-react",
"build-react": "react-scripts build",
"test": "run-p watch-shared test-react",
"test-react": "react-scripts test",
"eject": "react-scripts eject"
}
run-s
and run-p
come from npm install --save-dev npm-run-all
I don't recommend trying to re-use the "sync-shared"
script from "watch-shared"
, because running a node script in from watch
may restart everything.
On linux-like systems you might also be able to use mount --bind
instead of copy & watch to link your shared directory.
If I add a symlink in my src directory to another directory, and then include files from that path, create-react-app gives an error:
I assume create-react-app wants to have this import already built/transpiled. I would expect this to be the case for imports outside the src directory (node_modules for example). But since the symlink resides in the src directory, I would assume create-react-app would fetch these files as if they were truly in src directory.
Is this a bug, or expected behaviour? It makes it really hard to extract common components.