webpack a module that contains node_modules - npm

Question
I want to make changes to an open source JavaScript library. Using webpack and npm and keeping everything local, what options do I have to make changes to a local module and import it into project in place of an public npm module downloaded from the registry? The local module and consuming app will also be source controlled under two separate git repositories.
Problem
I am testing this within an Aurelia app, but I think it is a webpack and npm problem. I have an app called my-app which has a dependency on aurelia-binding. I wish to make local changes to aurelia-binding and push them to a fork in GitHub. My project structure looks like this:
└───my-app
├───.git
├───dist
├───node_modules
│ └───aurelia-binding
| ├───.git
│ ├───dist
│ └───src
└───src
When built and run, everything works as expected. To make a change to aurelia-binding and test them in my-app, I need to install its dependencies and build it. This results in a structure like this:
└───my-app
├───dist
├───node_modules
│ └───aurelia-binding
| ├───.git
│ ├───dist
| ├───node_modules
| | └───dependencies...
│ └───src
└───src
When the node_modules are installed on the dependency, webpack throws an error at runtime. The error may look like an issue with the aurlia module, but I do not believe this is the case.
Unhandled rejection Error: Error invoking SVGAnalyzer. Check the inner error for details.
------------------------------------------------
Inner Error:
Message: __WEBPACK_IMPORTED_MODULE_1_aurelia_pal__.a.createElement is not a function
I have also tried this using npm link with the library cloned next to my-app instead of within in but got the same result.

I used the following addition to the webpack.config.js to be able to use npm/yarn linked packages. It forces webpack to resolve the modules only using the main node_modules and not the "nearest" ones.
resolve: {
extensions: [".ts", ".js"],
symlinks: false,
modules: ["ClientApp", path.resolve('node_modules')],
}
Where "ClientApp" is the folder where my aurelia app is located. The symlinks parameter is used to prevent webpack from resolving the symlinked path to an absolute path.
A word of warning, with this setup you circumvent version checking by npm so you are responsible for linking a compatible version.

Related

React native monorepo with PNPM

My goal
I am trying to use React native monorepo with PNPM, because I need performance of pnpm.
Expected
I should be able to bundle React native app with pnpm android and start development server with pnpm start.
Actual results
I can bundle app, but I cant start metro server. I always get this error:
More info
I have node v16.14.2, react native v0.69.
I know default metro bundler doesn't support symlinks (https://github.com/pnpm/pnpm/issues/1252#issuecomment-667600769), which pnpm use, so I tried to patch metro in metro.config.js:
This works perfectly fine with pure React native repo like here e.g: https://github.com/gjhughes/react-native-pnpm-example
My project structure looks like this:
project
└───shared
└───backend
│ │ package.json
│
└───frontend
│ │ package.json
│
└───mobile-app
│ │ package.json
Here is my pnpm-workspace.yaml:
I am desperate. Is it even possible?
If you have any more questions, feel free to ask!
Use pnpm without symlinks. Create a .npmrc in the root of your monorepo with the following setting:
node-linker=hoisted
Remove node_modules and run pnpm install. Related docs: https://pnpm.io/npmrc#node-linker

How to correctly setup a local ReasonMl / Bucklescript dependencies

New to ReasonML, and I probably don't understand the bucklescript documentation for setting up
a module as a dependency.
ReasonML project, compiles correctly, with the file MyUtils.re in directory ~/ml/myutils/src.
second ReasonML project in ~/ml/project2/src, file Demo.re starts with
open MyUtils;
I installed the first project: I tried both
npm install -g
inside ~/ml/myutils, and
npm install ../myutils --save
inside ~/ml/project2
the module looks installed globally :
npm list -g | grep myutils
├─┬ myutils#0.1.3 -> /home/user/ml/myutils
and also locally
npm list | grep myutils
└─┬ myutils#0.1.3 -> /home/user/ml/myutils
bsconfig.json
"bs-dependencies": [
"#glennsl/bs-json",
"myutils"
],
package.json
"dependencies": {
"#glennsl/bs-json": "^5.0.2",
"myutils": "file:../myutils"
}
but npm run build :
We've found a bug for you!
/home/user/ml/project2/src/Demo.re 2:6-12
1 │
2 │ open MyUtils;
3 │
4 │
The module or file MyUtils can't be found.
- If it's a third-party dependency:
- Did you list it in bsconfig.json?
- Did you run `bsb` instead of `bsb -make-world`
(latter builds third-parties)?
- Did you include the file's directory in bsconfig.json?
I tried adding file:../myutils to bsconfig.json: no change
What am I doing wrong?
#gash go check bsconfig.json of myutils.
Set "namespace": false
If Myutils namespace is true. it will probably create extra module layer for you.
Something like MyUtils.MyUtils

Metro Bundler error: Expected path […] to be relative to one of the project roots

When trying to run my React Native app I get this error:
error: bundling failed: Error: Expected path `/Users/jgallaso/Projects/aerogear/aerogear-react-native-core/index.js` to be relative to one of the project roots
at toLocalPath (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/lib/toLocalPath.js:33:9)
at ModuleCache.getModule (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/ModuleCache.js:94:20)
at ModuleResolver._getFileResolvedModule (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:320:42)
at ModuleResolver.resolveDependency (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:311:989)
at ResolutionRequest.resolveDependency (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:96:16)
at DependencyGraph.resolveDependency (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/node-haste/DependencyGraph.js:269:4352)
at /Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:201:36
at next (native)
at step (/Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:256:306)
at /Users/jgallaso/Projects/aerogear/aerogear-js-sdk/example/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:256:536
BUNDLE [android, dev] ./index.js ▓▓▓▓▓▓▓▓▓░░░░░░░ 56.6% (331/440), failed.
My app has a dependency installed aerogear-react-native-core that is a Native Module. Source code is at: https://github.com/josemigallas/aerogear-react-native-core
This package on the other hand depends on other TS one (I ignore if this is problematic) and this code is located at: https://github.com/josemigallas/aerogear-js-sdk/tree/poc_react_native_library/packages/core
And the app code that actually tries to use all this is located at: https://github.com/josemigallas/aerogear-js-sdk/tree/poc_react_native_library/example/react-native
This means:
App
└─┬ aerogear-react-native-core#0.0.2
└── #aerogearmobile/core#1.0.0
Since this is all at development stage, nothing is pushed to npmjs, I'm just using npm link to include all dependencies.
Honestly I don't have a clue why this is failing, without the second dependency everything worked all right so that makes me think typescript has something to do. However, the error is complaining about aerogear-react-native-sdk's index.js file so maybe the error is related with the link.
I tried deleting all caches, re-installing npm modules, re-running the bundler many times...
If you have used "npm link" in the project, that might be the reason. Metro Bundler does not work with symlink correctly. Try to install the dependency without using "npm link".

what is npm doing differently when loading a project with a github url vs the usual npm install?

There's an npm module I'm using, that works fine in my project when installed with npm and its semver, but that fails with the below error when I try to install it with its github url.
The error: Uncaught Error: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component'srendermethod, or you have multiple copies of React loaded
I'm loading the same version of the module, not changing any build configs, the only difference is loading with semver vs github url.
I should say, the module's lib folder is not checked into github. So I do run a build of the module manually.
I'm using webpack for the build. I suspect its a problem with the copies of react being loaded, but that doesn't seem to have changed, and webpack seems to be handling duplicates.
npm ls react:
├── react#15.6.1
├─┬ react-color#2.2.0
│ └─┬ reactcss#0.4.6
│ └── react#0.14.9
└─┬ react-with-context#1.2.1
└── react#15.6.1 deduped
A little confused, any tips appreciated
(If that makes any difference, the error seems to be thrown from a dependency of the module that I'm testing. And in both modules (the one I'm testing + its dependency), react is listed as a peerDependency package.json)

Share node_modules installation between sub-projects, while maintaining separate package.json files

I have the following folder structure:
project
├───components
│ ├───component-one
│ │ package.json
│ │
│ └───component-two
│ │ package.json
│ │
│ └───node_modules
├───node_modules
└───package.json
Project root project folder contains package.json and is intended to have various infrastructural modules installed (Gulp, for example, as the build is centralized).
Each component under components folder is eventually, after build and whatnot, is deployed somewhere to be consumed by an application - using the usual npm install from folder or tarball. For that reason, each component must maintain its own dependencies in its own package.json.
Going the trivial route, installing node_modules into each of the component folders would lead to a crazy amount of duplication, as there may be 100s of components, each installing mostly the same dependencies.
Ideally I would like to:
run, for example, npm install -D <module> in component-one folder
have package.json in that folder updated with the <module>
have <module> installed in the project folder
This can be achieved, to some extent, running (on Windows, in this case) mklink /D node_modules ..\..\node_modules from component-one to create a symlink.
However, symlinks are fragile and finicky, so I'd like to avoid that solution.
Is there an npm solution, via npm link or something that I am missing?