Yarn install Lerna monorepo directory with local dependencies - javascript

I have a monorepo that has 20 visual components built using Lerna. This component library is being used by another app repo and is included in it's package.json
I'm pulling in a single component from the component library into the app using a Yarn 2+ feature in package.json:
"#author/component-a": "git+ssh://git#github.server.com:Author/component-lib.git#head=feature/updated-component&workspace=#author/component-a",
We want to push to a branch on Github rather having to publish to npmjs every time we need a change in the app. This reason we want to take this approach (rather than something like yarn link) is because we have a staging environment that we want to build with the changes in the branch.
The component library file structure looks like:
packages
component-a
package.json
component-b
package.json
package.json
Where packages/component-a/package.json looks like:
{
"name": "#author/component-a",
"version": "1.1.0-alpha.1",
"description": "Component A",
"author": "Author",
"license": "MIT",
"main": "dist/index.js",
"files": [
"dist"
],
"dependencies": {
"#author/component-b": "1.1.0-alpha.1"
}
}
and packages/component-b/package.json looks like:
{
"name": "#author/component-b",
"version": "1.1.0-alpha.1",
"description": "Component B",
"author": "Author",
"license": "MIT",
"main": "dist/index.js",
"files": [
"dist"
]
}
I've been trying ways to get the build to refer to the local files rather than the ones published on NPMjs:
packages/component-a/package.json
"dependencies": {
"#author/component-b": "file:../component-b"
}
Which works fine locally (building in the component library, but downstream building in the app, via a branch it breaks.
Question: How can I get a downstream app to pull in other components defined defined in the same repo from a monorepo without publishing the packages (to NPMjs) and working only via a branch.

Related

How to create shared NPM package?

I have an NPM package that I am creating in Typescript which just contains my type interfaces.
I currently have a folder structure like this:
project
│ index.ts
│
└───types
│ restaurant.ts
│ menus.ts
and package.json that points to the index file:
{
"name": "my-package",
"version": "1.0.0",
"description": "Shared type definitions",
"type": "module",
"main": "./index.ts",
"source": "./index.ts",
"scripts": {
"tsc": "tsc --noEmit"
},
"license": "ISC",
"devDependencies": {
"typescript": "^4.8.4"
}
}
I can link this with another package in "project A" and all works well.
But as soon as I move my index.ts and type files into a directory called src, the link no longer works
Cannot find module 'my-package' or its corresponding type declarations.
I have tried removing the symlink / reinstalling the linked package as well as updating my package.json file of my shared package to "main": "./src/index.ts", but to no avail
How am I supposed to create an NPM package which points to my src or even a dist file?
What you are looking for is a monorepo project.
Take a look at turborepo, which does exactly what you want.
You can also try lerna, but I personally prefer the other one.

How to properly expose subpaths in package.json using the ”exports” key?

I’ve released a NPM package which is a plugin for a framework where only the main entry of my package.json is needed for usage in the framework and its environment. I also want to be able to use a subpath of the plugin in order for users to be able to use the plugin outside of this framework as well, which will require that the main entry point is never initialized as there are framework specific dependencies used there which I don't want to initialize when using this plugin outside of the framework.
My project structure looks like this:
.
├── index.js
├── submodule.js
└── package.json
Source code for the sake of this example looks like this:
// index.js
export default function () {
return "foo";
}
// submodule.js
export default function () {
return "bar";
}
// package.json
{
"name": "my-package",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"exports": {
".": "./index.js",
"./submodule": "./submodule.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "MIT"
}
According to Node.js documentation on this matter, this setup should allow me to use my package like this:
import myPackage from ’my-package’
import mySubModule from ’my-package/submodule’
In order to be able to test my package locally I run npm link in the project root of my npm package and then in another project i run npm link my-package. Now that I try to run the project (using parcel-bundler) that imports my-package and my-package/submodule like in the example above I get the following exception:
Cannot resolve dependency 'my-package/submodule'
I'm using NVM with Node v.12.18.4 and NPM v.7.15.0. I have also tried with Node v.14.17.0 but the issue persists. What am I missing?
It seems that the project setup is correct and that the problem lies in the parcel-bundler which does not support package.json#exports yet. There's currently an open issue on this matter.

Webpack: prebuild lifecycle hook for libraries

I'm the author of a library and I need a script to be run each time before webpack bundles my library into the user's app code.
My library's package.json would be something like this:
{
"name": "some-js-library",
"version": "0.1.0",
"scripts": {
"prebuild": "./path/to/my-libs-prebuild-script.js"
}
}
The user's package.json could be anything, for example:
{
"scripts": {
"//": "or however the user uses webpack",
"build": "webpack"
},
"dependencies": {
"some-js-library": "^0.1.0"
}
}
I don't have any control over my users' package.json, so I'm left to wonder if it's possible to have my-libs-prebuild-script.js executed every time before webpack starts building?
Ideally this would be a standard that every bundler agrees on, but a webpack only solution would be fine.
Thanks!

package.json - how to determine what parts of the module are installed

I have a project structure like this:
__tests__
example
src
.bablerc
.eslintignore
.eslintrd
.gitignore
package.json
package-lock.json
README.md
and package.json parameters like:
{
"name": "",
"version": "0.0.1",
"description": "",
"main": "src/index.js",
"scripts": {
"test": "jest"
},
"files": [
"src/"
],
"repository": {
"type": "git",
"url": "url"
},
"jest": {
},
"devDependencies": {
},
"peerDependencies": {
}
}
When I npm install this modules I only get src folder with an empty index.js file. The goal was to only have the user install all of the src folder and not the example part since that is an example app. I thought that "files": ["src/"], would solve this. However it's not doing what I would expect. I don't see anything that is in the src folder. It's empty!
npm docs say:
The optional files field is an array of file patterns that describes
the entries to be included when your package is installed as a
dependency. File patterns follow a similar syntax to .gitignore, but
reversed: including a file, directory, or glob pattern (*, **/, and
such) will make it so that file is included in the tarball when it’s
packed. Omitting the field will make it default to [""], which means
it will include all file
How do I allow the user to install all of the src folder and ignore the example folder?
I'm on npm 5.6.0 and node v9.11.2
Almost there! Files entry behave like in a line a .gitignore. That works:
"files": ["src"]
For testing purposes, you can run npm pack --dry-run to check in the pack reports what files would be included when running npm install on the package you're developing.

Javascript code completion for arango and module handling

Introduction
I've been using Eclipse for Java(!) development for more than a decade. Due to high demand I'm jumping in the deep end with javascript and arangodb. Task is to develop several microservices running within arangodb.
I'm free to use the IDE/Editor of my choice. Only remaining competitors are MS VS Code and IntelliJ. VS Code beeing my favorite as of writing.
Project setup
According to arangos documentation I've composed a project with:
mainfest.json (content skipped to improve readability)
package.json
{
"name": "abc",
"version": "0.0.2",
"description": "foxxy service",
"comment" : "This file contains the NPM package definition",
"main": "main.js",
"directories": {
"test": "test"
},
"dependencies": {
"crypto-js": "^3.1.9-1",
"jsonq": "^1.1.0",
"xml2js": "^0.4.19",
"xmldom": "^0.1.27",
"xpath.js": "^1.0.7"
},
"devDependencies": {
"chai": "^4.1.1",
"mocha": "^3.5.0"
},
"scripts": {
"test": "node node_modules/mocha/bin/mocha"
}
}
jsconfig.json
{
"compilerOptions": {
"target": "ES6",
"checkJs": true
},
"include": [
"scripts/**/*",
"lib/**/*",
"models/**/*",
"node_modules/#arangodb/**/*",
"node_modules/jsonq/**/*",
"node_modules/xml2js/**/*",
"/*"
]
}
Current state
VS Studio Code offers code completion for:
- standard Javascript (ES6) expressions
- resolves actual files behind require expressions ( e.g.: require('lodash') is resolved to the actual filesystem path
C:/Users/notte/AppData/Local/Microsoft/TypeScript/2.5/node_modules/#types/lodash/index' which proves (for me) that npm module resolution and code completion are working
Question
Arango does not offer modules via npmjs or other public repositories. I therefore copied the files (#arangodb) from an local arangodb installation to the projects "node_modules" folder.
Altough VS Code is informed about the #arango modules and submodules it does not come up with a useful code completion. What should I do or try to do?
What would be a pragmatic, sustainable solution for handling modules like those from arango? (it is not present in npmjs, has no package.json and hence no versioning)
Thank you.
We Currently collecting user efforts to create Syntax hilighting via https://github.com/arangodb/arangodb/issues/1755 - Please share your thoughts if you have something to add.

Categories

Resources