Yarn Workspaces Example

Working with workspaces via yarn seems to be pretty finicky in rescript, any resources out there that can better explain how to best setup a repo that has multiple modules that are separated by project within a single repo?

We have UI libraries that we would like shared across multiple apps, and we have started experiencing issues now that we are using a module for a second time in a separate app that is using this nextjs template.

Lots of random modules are showing as not found and its hard to even start to track down what the potential issues could be.

Just to be sure: Did you check out the Pinned Dependencies docs already?

1 Like

Ah this is EXACTLY what I was looking for.

I will give this a try but I am also guessing that the nextjs example with workspaces is at the root of these issues with its webpack config hard coding the node modules directory.

Any examples or further explanation on the important note about file watcher not working across the packages?

So we still have the same issues, this must be an issue with the nestjs package.

/my-app
/app (able to use wonka just fine - no issues)
/wonka
/totan (nextjs)

Within totan we are trying to use the wonka module which has a dependency DineroJs (@bettercart/rescript-dinero - npm) and we are now getting this error when the nextjs app runs:


or:

I should note that I changed some of the lines in the next.config.js for webpack from ./node_modules to ../node_modules and also had to change package specs in bsconfig from:

"package-specs": {
    "module": "es6",
    "in-source": true
  },

to:

"package-specs": {
    "module": "commonjs",
    "in-source": true
  },

FormattedMoney.bs.js

Before this change, rescript would throw errors saying modules were not found…

My hunch is that these lines of code in next.config.js are causing these issues?

function patchResDeps() {
  ["rescript"].concat(bsconfig["bs-dependencies"]).forEach((bsDep) => {
    fs.writeFileSync(`../node_modules/${bsDep}/index.js`, "");
    const json = require(`../node_modules/${bsDep}/package.json`);
    json.main = "index.js";
    fs.writeFileSync(
      `../node_modules/${bsDep}/package.json`,
      JSON.stringify(json, null, 2)
    );
  });
}

EDIT:
I have also just recently noticed that this error no longer exists if these components from Wonka are rendered client side rather than SSR - But the only reason we are using nextjs is to get these Wonka components rendered SSR.

EDIT:

Well we are still receiving this same error even after removing this code entirely…

Well we narrowed this down to our DineroJs binding, when we comment this out, we are working perfectly!!

Any idea why this binding is causing issues? - GitHub - bettercart/rescript-dinero

Might be that your external binding to a default export might be wrong, depending on if you are using commonjs or ES6 import style (those are subtly different unfortunately, and the ReScript user needs to write bindings specifically for the relevant compile target).

I guess this is the problem

So every package in the monorepo is exporting for commonjs and the other package has no issues using the DineroJS binding via the wonka package (within in /app) - we are only seeing this issue in the nextjs package (/totan). Any ideas why the binding would work in one package but not the other?

Thanks for all your help @ryyppy

same issue here. mimic the document for pinned-dependencies,but not work. always prompt me

Error: package common not found or built

  • Did you install it?
  • If you did, did you run rescript build -with-deps?

I have rethink do I really need workspaces or lerna?

I just wanna make a React components library, some project only import subset component, and I don’t want to install full of dependency and make my bundle larger.

If rescript have good dead code elimination and tree-shake friendly, So my purpose is satisfied.

Can someone answer me, thanks?

1 Like

So is your Next app configured to compile to commonjs as well, or not? My assumption is that you are currently trying to use my nextjs-template which is configured to compile to es6 by default. If that is the case, your external will not work, you’d need to have a separate binding that handles the ES6 import correctly because commonjs default export !== es6 default export.

If you are asking this question, then the answer is most likely “no”. Workspaces and all the micro-package jazz in the JS ecosystem is adding so much maintenance overhead that they had to invent extra tools (yarn workspaces / lerna), just to be able to deal with the complexity.

Keep it simple, if possible.

ReScript compiles to tree-shakeable ES6 modules (if configured to es6 output). From there on, it is the responsibility of the bundlers (webpack, vite, rollup, esbuild, etc) to do the tree-shaking business. Also worth mentioning: Tree-shaking has nothing to do with yarn workspaces / lerna.

2 Likes