This is the third episode of a series about the work I've done to create a web3 DApp in a NX monorepo.
Check the previous articles to have a better context understanding.
BALUNI CORE
Creating the project
Once we have created the previous 2 projects with the contracts, we can start building the core library of our DApp.
This library will need to expose an "api" to consumers to allow them to perform common operations.
We will start by adding a new library to our monorepo
npx nx g @nx/js:lib baluni-core
Main goal ⚽
One of the mail goal here is to provide a good developer experience by offering a well organized set of import paths.
At the moment, the actual project is used like this:
import something from "baluni/dist/some/path
Note the dist
piece in the import path, is so ugly!
We want instead to import things in a nicer way
import something from "baluni/feature1"
import somethingElse from "baluni/feature2"
// and so on
Importing the code
This is the original project's main code structure
I have to say my friend, quite messy, but I forgive you
Since digging in the code is not in the scope of this article, the goal was to bring in the monorepo the things as they are now.
So here I just did 2 things:
- I copy/pasted
core
andapi
folders under the new library's src folder - copied all the dependencies from package.json the the library's package.json and prevented the hoisting as we did previously
This is the new library structure:
After importing the dependencies and the code (this project has no assets) I tried to build the project but I had to fix some typescript configurations that NX has set by default.
The first one was related to the fact that we are importing json files (the contracts).
I fixed this by setting "resolveJsonModule":true
in the root tsconfig.base.json, typescript also made me set "esModuleInterop":true
With this in place, I was able to use this kind of import in baluni-core
import factoryAbi from 'baluni-contracts/artifacts/contracts/orchestators/BaluniV1AgentFactory.sol/BaluniV1AgentFactory.json'
After fixing that the project built successfully, let's see the output:
as we can see, this output contains the src folder, which makes it impossible to use the import as we wish.
Organizing import paths
As I said previously, we want to provide good developer experience by proving clear an well organized import paths.
Moreover, I'd like to do it without modifying the existing code.
By analyzing the actual used imports from outside, I decided to provide this imports
-
baluni-core
: should export everything from thecore
folder -
baluni-core/api
: should export everything fromapi
folder -
baluni-core/utils
: should export everything fromcore/utils
folder -
baluni-core/types
: should export everything fromcore/types
In order to do that, we first need to add this to baluni-core
's package.json
"exports": {
".": "./index.js",
"./types": "./src/core/types/index.js",
"./api": "./src/api/index.js",
"./utils": "./src/core/utils/index.js"
},
This is the final package.json
it will define additional entry points for our library as we wish.
Now we need to instruct NX to output the content of the source src
folder to dist/packages/baluni-core
instead of dist/packages/baluni-core/src
to make this we need to edit project.json:
After I had set the flag "rootDir": "packages/baluni-core/src"
, the build output was changed to this:
Now we have the proper build output so also this package is ready to be deployed on npm.
On the next articles we'll se how to create a cli, a backend and a NextJS app using this library.
You are very welcome to leave a comment, I will be happy to answer to all your questions.
Top comments (0)