简体   繁体   中英

What is a correct approach to a javascript monorepo

I'm trying to figure out correct approach for a javascript monorepo. Imagine monorepo containing packages / libraries:

root
  - node_modules
  - packages
      + lib-a
          * node_modules
      + lib-b
          * node_modules

Now let's say both lib-a and lib-b packages use webpack as their build tool.

I see two approaches

  1. Add wepback as dependency to root. Include "build" script in both packages: "build": "webpack -p --config webpack.config.js . webpack.config.js could include root webpack.config.js . Then I could use tool like lerna to run the build from root directory (which means webpack binary is recognized. However I will be unable to run the build in specific packages since webpack is not available there. I could probably change the build script to something like "build": "../../node_modules/.bin/webpack -p --config webpack.config.js

  2. Always include webpack in each package. This means that build script will succeed. This also means that each package will have the same dependency and I should probably watch that each package uses same webpack version.

Basically what I'm getting at is how should packages inside monorepo be structured? If any package is published, should it always be possible to build that package separately.

Your approach #2 is right. You handle each package separately as it was an individual, self-contained package.

The advantage of a monorepo lays not in sharing files through the directory structure but in:

  1. Bootstrapping all dependencies to a single node_modules with flat structure, effectively deduplicating them.
  2. Making your packages available to your other packages through regular package import / require() as they were external dependencies. And, thanks to symlinks to node_modules , your "dependency" packages contain always the latest content without publishing.
  3. Enforcing consistent, always up-to-date, dependency structure in all your packages. As you said "This also means that each package will have the same dependency".
  4. Automation tools to perform different maintainance tasks (like build, publish) on all your packages with a single command.

I know it's not so easy at the beginning, but when you dig into Lerna documentation it's becoming more clear. Besides Lerna main page I recommend reading about hoisting , FAQ and individual commands like bootstrap and publish .

Our current configuration is same as you:

root
  - node_modules
  - packages
      + lib-a
          * node_modules
      + lib-b
          * node_modules

We use lerna to handle our project: https://github.com/lerna/lerna

You just need to specify your package folder in the lerna.json

{
  "lerna": "3.16.4",
  "packages": ["packages/*"],
  "version": "0.0.0",
  "npmClient": "yarn",
  "useWorkspaces": true
}

Then in your package.json scripts you can use the line:

"build": "lerna run build",

This will basically run a build in all packages. So as long as your build script in each package has the proper params and webpack installed it will automatically run the webpack build.

After that you can simply handle working in your designated packages.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM