Repositories & Projects Organization

Well, we could add a /examples folder to the Lerna packages and mark the packages inside as private in their package.json. Just that the examples will be versioned and tagged in the git repository, but that’s not bad either!

I’m having a problem with travis and jest.

https://travis-ci.org/frontity/frontity/builds/502130354
My build are failing because jest doesn’t find the npm packages that go inside @frontity/core.

Cannot find module 'hash-it'

How do people usually manage test and npm packages in a monorepo?

It looks like it doesn’t find path and fs as well, I have no idea why:

Cannot find module 'path'

@David :point_up_2: :slight_smile:

Fixed it!

I mentioned that I would add the lerna bootstrap command in the postinstall script inside package.json. That’s what I’ve done but with a couple of changes:

  • Instead of postinstall, I used prepare that fits our needs better (it runs after a local npm install or npm ci, postinstall does it after installing the package, not its dependencies).
  • I added the --hoist argument to the bootstrap command. It causes all packages to be installed in the root (this is good, isn’t it?).
  • Travis will check if the current job is a pull request before running the release command (we don’t want to release anything during a PR!).

Interesting…

I don’t know if installing all the packages in the root is a good idea. What happens if one package needs one version of certain npm package and other package needs other? I think it’s safer to keep the dependencies in their original places.

I’ve taken a look at what other monorepo projects do and another option would be:

// package.json
"scripts": {
  "install:ci": "lerna run install --parallel",
  "test:ci": "lerna run test:ci --stream"
}
// travis.yml
script:
  - npm run install:ci
  - npm run test:ci

This will run install on each /package folder and then test:ci on each folder. We would have to move the "test" scripts to each package instead of the root, but again, I think it’s a better idea.

Why do we need to avoid releasing on a PR? Aren’t the releases triggered only in master?

:sweat_smile:

When using --hoist Lerna moves just the common dependencies of the packages to the top-level node_modules, and those packages that have a specific-version dependency will get a local node_modules with it (more info here).

Anyway, You are right when you said it’s safer to not use it…

Well, there is a problem with Travis and Lerna, and that’s Travis works with the git repository in “detached HEAD” mode. For Lerna to work properly you must checkout a branch first. This is not possible during a PR, so the release script will fail. Travis won’t fail though, but it will show error messages that can make you think that something has gone wrong, when actually not.

I’ve made the change and I really like it!

Now that we have a monorepo, what do you think about using the scope of each commit to indicate the package:

type(package): message

For example:

feat(core): something super cool <-- /frontity/packages/core
fix(file-settings): fix something bad <-- /frontity/packages/file-settings
build(frontity): changes to the cli <-- /frontity/packages/frontity
ci(root): fix for travis <-- /frontity

For the root (no package) we can use root.

I talked about this with @David a while ago. It looks like lerna already knows what package is modified by the commit, so we can keep using the scope like before.

Uh, I see. Ok then.

About fix and feat commits

In order to keep the Changelog clean, I think it should be only one fix or feat commit per PR in general. For example, these are some hypothetical commits of a PR:

chore(basic-typescript): add package.json
chore(lerna): add examples folder to lerna
chore(basic-typescript): change @frontity/core and dev script
chore(lerna): install common packages in root node_modules
chore(examples-folder): example folders now work like external projects [WIP]
feat(examples-folder): example folders now work like external projects
docs(dev-script): add better comments
test(basic-typescript): add test for the build

This PR will only add one line to the Changelog:

Feature:

  • examples-folder: example folders now work like external projects

If we add fixes when we are just fixing stuff that’s only relevant to the PR, the Changelog will get things that are not relevant:

chore(basic-typescript): add package.json
build(lerna): add examples folder to lerna
fix(basic-typescript): change @frontity/core and dev script
fix(lerna): install common packages in root node_modules
feat(examples-folder): example folders now work like external projects [WIP]
feat(examples-folder): example folders now work like external projects
docs(dev-script): add better comments
test(examples-folder): add test for the build

This PR will only add multiple lines to the Changelog:

Feature:

  • examples-folder: example folders now work like external projects :white_check_mark:
  • examples-folder: example folders now work like external projects [WIP] :x:

Bug fixes:

  • lerna: add examples folder to lerna :x:
  • basic-typescript: change @frontity/core and dev script :x:

So I think that each time we use a fix or a feat commit we should take into account that it must be relevant to the Frontity project, not to the PR itself.

Most of the commits will be just chore(...) until the problem is finally solved, but I don’t think that’s a problem.

Forget about using only one fix or feat commit per PR. That’s difficult to do.

What we should do is:

  • Never use fix, feat or perf inside branches.
  • Rename the commit message when merging the branch to include the fix, feat or perf of that PR.
2 Likes

Hey guys, when using lerna bootstrap, do you know if the package I have in devDependencies needs to be published in npm in order for lerna to create the symlink?

I don’t think so because I’m using @frontity/core in other packages and it’s not published in npm yet, but it’s on dependencies, not devDependencies. @david do you know?

You don’t need to publish any package in the monorepo for lerna to create the symlink, at least for them that are on dependencies. I’ll investigate the case of those on devDependencies but it should work the same.

BTW, @orballo, don’t use lerna bootstrap directly, use better npm i at the root of the monorepo .

OK, thanks. Yeah I noticed the behaviour was different between npm install and lerna bootstrap.

Maybe instead of npm install at the root we should use something like npm run bootstrap?

I mean, most of the time you don’t need to install anything at the root.

@luisherranz I noticed we have a tsconfig.json file on the root, but none on the core package. Is it using the one from the root?

Yes. I don’t know yet if it makes sense to have a root tsconfig.json or one per package.

What do you think?

Actually in this case, where I wanted to extend the main one, with another tsconfig.build.json for the scripts, I don’t know if I can use the one from the root? If yes, I don’t see the problem in having only one in the root.