- Start Date: (2020-08-07)
- Target Major Version: None
- Reference Issues: None
- Entity Issue: #4551
- Implementation PR: None
Using current best practices and available tools/packages, create a library of shared Vue (UI) components that can be used by different UI projects.
In particular, this library/framework/architecture will contain (simple) business-focused components (eg, BaseAddress, list of directors, entity info, etc) that won't be in every app but will get reused. This is in contrast to the https://github.com/bcgov/sbc-common-components library that contains components that will probably be in every BCRS app and which contains more complex components that use services, etc. Ultimately, there may be a thin line between the proposed and existing library and, in the future, they could possibly be merged.
Another goal is to be able to individually version each component. This would allow components to be individually updated without forcing the consuming project to import all other changes to the library. This should make smaller rollouts easier.
Whether the proposed approach is a good one -- or needs tweaking -- should become clear when we start to use it and accumulate numerous (increasingingly complex) components over time.
BCRS Shared Components is a multi-package Lerna repository of shared Vue components, each published individually and that you can explore/ develop/ document/ test using Storybook.
The prototype repository is here: https://github.com/bcgov/bcrs-shared-components
The Storybook pages for this project is here: https://bcgov.github.io/bcrs-shared-components/
-
Reuse existing functionality in new projects
-
Reduce duplicated code / fix bugs in one place only
-
Common design / styles between apps
-
Simpler component development than in sbc-common-components
-
Easier component maintainability than in sbc-common-components
-
Independent versioning of each component
-
Duplicated code between projects
Don't actually do this if possible!
-
Component inheritance / mixins / plugins / slots (ie, within Vue framework itself)
We are already doing some of this but it's a compromise between development effort and value, and is within individual projects only.
-
Git submodules
Is not generally recommended.
-
Multiple repositories
Lots of overhead.
-
Monorepo
All projects/components/packages are within a single repository.
Sbc-common-components is a library example of this (using npm alone). However, additional tools can facilitate management of multiple projects, packages, libraries, components - see below.
-
https://github.com/features/packages
GitHub Packages (Registry) is an alternative to npm. I did not look into this deeply because we already use npm and it does not seem to limit us at the moment. Also there are many online examples using npm and few using GPR.
-
https://www.npmjs.com/package/meta
Meta is a tool for managing multi-project systems and libraries. I did not look into this deeply due to a lack of online examples.
-
https://github.com/git/git/tree/master/contrib/subtree
Git-subtree allows you to merge subtrees and split a repository into subtrees, which allows projects to be included within a subdirectory of the main project. I did not look into this deeply due to a lack of online examples, and it didn't seem like subtrees was a great way to deal with multiple projects and versioning.
-
https://github.com/lerna/lerna
Lerna a tool for managing JavaScript projects with multiple packages. The prototype uses this.
-
Storybook is an open source tool for developing UI components in isolation. The prototyps uses this.
-
Bit an open source tool that helps you easily publish and manage reusable components. I did not look into this deeply due to unanswered questions about hosting and cost.
The prototype is based on https://github.com/pixari/component-library-monorepo.
In short:
- Create a GitHub repo
- Check it out locally
- Install and initialize Lerna
- Install and configure Storybook
- Add a component to the library
- Run/build Storybook
- Commit/publish to GitHub (*)
(*) The prototype uses GitHub Pages to serve the Storybook app folder, however this requires a developer to build before committing and may not lend itself well to concurrent independent/multiple component development.
This section is incomplete. In theory, each component can simply be imported as follows:
{
"dependencies": {
"@mylibrary/my-button": "*"
}
}
I am not sure how Lerna/npm work together here. (Research was time-boxed.) However, I am confident that the information is easily available on the Internet as Lerna seems to be popular.
- Inform the team about this RFC and solicit feedback.
- Add some components to the prototype library.
- Learn to use the tools and document the steps for other developers to use.
- Evaluate as time goes by. Review and make changes as needed.
See ticket #4551.
- Update prototype to latest config (ie, current config is a few years old)
- Document our Lerna config and usage
- Document our Storybook config and usage
- Figure out how to use individual components in an app
- Document any other development processes (how to develop, test, publish, import, etc)
- Figure out how components can use VueX
- Figure out how components can use services, etc
- Configure automatic build/publish for GH Pages
- https://github.com/storybookjs/storybook
- https://storybook.js.org/docs/vue/
- https://www.learnstorybook.com/
- https://christopherkade.com/posts/storybook - automatically deploying your Storybook to Github Pages
- https://github.com/storybookjs/storybook-deployer - can deploy to GH Pages using CI
- https://www.npmjs.com/package/@storybook/cli
- https://www.npmjs.com/package/@storybook/vue - a UI development environment for your Vue components, to visualize different states of your UI components and develop them interactively
- https://www.npmjs.com/package/vue-storybook - a Webpack loader + helper script that allows you to embellish your pre-existing Vue single file components (SFC) with a custom block that's automatically translated into a Storybook-flavored story - use in future maybe?
- https://github.com/storybookjs/vue-cli-plugin-storybook - will create a config folder for storybook, a sample component and a sample story
- https://github.com/white-rabbit-japan/vue-vuetify-storybook
- https://github.com/pixari/component-library-monorepo - monorepo solution for multiple VueJs Apps and a shared component library
- https://github.com/lerna/lerna - a tool for managing JavaScript projects with multiple packages
- https://medium.com/js-dojo/sharing-reusable-vue-js-components-with-lerna-storybook-and-npm-7dc33b38b011 - sharing reusable Vue.js components with Lerna, Storybook, and npm or GitHub Package Registries
As part of my research, I visited many other pages. They are documented here: https://app.zenhub.com/workspaces/entity-5bf2f2164b5806bc2bf60531/issues/bcgov/entity/4551#issuecomment-677903928
This template is heavily based on the Vue, Golang, React, and other RFC templates. Thanks to those groups for allowing us to stand on their shoulders.