Kotsu icon indicating copy to clipboard operation
Kotsu copied to clipboard

Extract parts of Kotsu into external modules

Open ArmorDarks opened this issue 6 years ago • 3 comments

Kotsu definitely becoming bigger and updating it within 3rd-party projects becomes harder.

As a potential solution, we could move into standalone NPM modules pieces, which are less likely to be changed by a user.

Besides, it will resolve an issue with few pieces of Kotsu, which are reusable on its own in other projects, like Stylelint config, tcomb additional types and clean-workdir script.

Before moving forward, I must admit that there are two factors, which held me back from such changes:

  1. It will make Kotsu less boilerplate, meaning, that everything no longer at disposal of the end user. Some code pieces will become not editable, and there is no easy way to make them overridable or extensible without tons of undesired and obscure code.
  2. In some cases, it makes features of Kotsu less obvious. For instance, it is easier to grasp what Ekzo is by looking into it directly in source/styles instead of finding it in package.json. After all, not all devs checking package.json at all.
  3. It will make maintenance of dependencies harder because will would need to update them in several places instead of just in central Kotsu repository.
  4. It will complicate development, since now to write or test something we would need to constantly link with NPM local modules to our local copy of Kotsu and maintain development-related dependencies in those modules too.

The last issue is mostly solvable by moving to the concept of monorepository, like babel or create-react-app do, and using Lerna. But while it seems to be the handiest solution, I'm still not sure.

So, here what we can potentially do to reduce distributable Kotsu codebase:

  • .stylelintrc.yml and it dependencies (Stylelint, Stylelint SCSS, Stylelint standard config) move to @kotsu/stylelint-config, so that other related modules, like Ekzo, could reuse it

    Though, I'm not sure that @kotsu/stylelint-config is a fitting name. It sounds like it tied to Kotsu, but actually, it's our Sass codestyle.

  • tasks and it dependencies move to @kotsu/tasks.

    Tasks should be invoked in Gruntfile by importing @kotsu/tasks and running kotsuTasks(grunt)

    That way project can opt to use predefined tasks or not too. Besides, tasks should be importable based on layers (for instance, only @kotsu/tasks/scripts for scripts), if a project needs an only small portion of default tasks.

    The project also will be able to override any task by placing files in tasks directory and using grunt.merge or grunt.config, coupled with Object.assign or lodash.merge (which would be preferable, because it handles deep objects). This can be considered as a benefit since with it it will be much easier to understand how exactly project deviates from original Kotsu config.

    Some downsides:

    • Importing@kotsu/tasks will install all dependencies, even if the project doesn't need part of default tasks.
    • Merging operations could potentially make Grunt tasks startup even slower.
    • List of already defined tasks now will be obscure because you no longer can simply check tasks directory to see all of them

    It also unclear what to do with tasklist in Gruntfile (default, build and serve). We could provide them within @kotsu/tasks too, but it means that they won't be effectively extensible.

    As a workaround, we can add some simple API for inserting custom tasks before or after some tasks, like

    tasks.default
     .runBefore('sass', 'some-custom-task')
     .runAfter('csso', 'some-other-task')
    

    But I have a feeling that it will enormously complicate tasklist.

    Finally, note that some tasks, like default and serve are only partially controlled by Grunt and usually launched by NPM scripts at full (like serve also launching in parallel JS watch). It makes providing of such functionality at a 3rd-party module even more challenging task.

  • modules and it dependencies should be moved to @kotsu/utils

    This is a part of Kotsu, which almost never should be altered by the user unless some very specific behavior needed.

    As a downside, we giving less freedom to the user and it compromises the main purpose of Kotsu of being a boilerplate with great defaults.

  • modules/refinements should be moved to tcomb-refinements or tcomb-xtypes or tcomb-x or something like that.

    That module, which provides additional refinements and irreducibles for tcomb turned out to be used in many our side and commercial projects, and it would be better to not tie it exclusively to @kotsu.

  • modules/clear-workdir could be moved to clean-workdir (or maybe we need a better name).

    This script is small but useful in any project, which involves building, so there is no sense to make it exclusive to Kotsu

  • Following modules:

    • modules/grunt (run Grunt via JavaScript)
    • modules/nunjucks-test-utils (a thin wrapper for assembling rendering for tests)
    • modules/validate (a thin wrapper to make easier validation with tcomb)

    Are actually mostly used for tests, and probably be better to move to @kotsu/test-utils

    Though, they can be left in @kotsu/utils. I don't see any harm.

  • Modules-related tests/kotsu (but not Nunjucks-components related ones) would be better to move to @kotsu/utils/tests

    We can't move components tests out of user's reach because provided components and their tests are just defaults, the user most likely would change them to fit project visuals.

    Such change will also prevent the user from running related to modules tests, which is mostly pointless waste of time anyway.

  • Ekzo should be moved to dependencies.

    I'm not a super fan of such change since it will make obscure where Ekzo styles are coming from (Sass isn't that friendly with NPM), and it will complicate development, but hassle with submodules each time you need to init new project for such trivial thing just does not worth it.

So far I do not see a way to make similar simplification with source/styles or source/templates. While we potentially could move few components to the standalone modules, I do not see much benefit in it, while other pieces are too subjective and most likely would be modified by the user.

ArmorDarks avatar Mar 25 '18 12:03 ArmorDarks