jl-svelte-components-library
Audience: Developer working in this repository.
Summary
This is a starting point for developing a reusable Svelte component library using Storybook and Rollup.
Features
Note: For applications (as opposed to a "component library"), use create-svelte-app or Next.js.
Install
git clone https://github.com/jmlivingston/svelte-components-library.git
cd svelte-component-library
npm i
Note: To make this your own, replace the text "jl-svelte-components-library" in package.json, README_PACKAGE.md, and README.md files. There is several places where the package.json name property is used.
Start
npm start
npm start:info
- This starts with additional Storybook plugins enabled and is good for testing documentation, but not as good for debugging.
Build
npm run build
Styling
This project allows CSS, SASS, CSS Modules, and SASS Modules. If you are importing from node_modules, you will need to prefix with a tilde ~
. SASS Example:
@import '~bootstrap/scss/_variables.scss'
Publish Package
npm publish dist
Publish Documentation
npm run publish-documentation
Note: Defaults to GitHub Pages and assumes git is initialized with a GitHub repository. To remove, delete publish-documentation in package.json scripts and uninstall @storybook/storybook-deployer.
Naming Conventions
- PascalCase - Component names, component parent folders, and any component related file names (.js, .test.js, .stories.js, .css, .module.css, .scss, .module.scss)
- SNAKE_CASE (upper cased) - constant files and constant variables within.
- kebab-case - class and id names for CSS or SASS.
- camelCase - class and id names for CSS modules or SASS modules. All other functions, variables, and folders.
Folders
This project aims to stay flat as possible, but can be easily changed or extended.
- dist - build directory
- storybook-static - documentation build directory
- scripts - this includes utilities, build, storybook, plop templates, and Jest configuration
- src - source code
- constants - shared constants
- documentation - Stories for high-level documentation
- helpers - shared helpers and hooks
- resources - localization resources and helpers
- services - API helpers and mock data
- ui - components, tests, stories, and style (SASS) files
- core - base components
- report - report components
- compound - components based on other components such as dashboards and pages
Build
Build uses Rollup to generate indepdendent component bundles based on the folder structure under src. Here are a few features:
- All documentation, mock, styles, tests, and stories are filtered out.
- An index is also created for components where they are the only component in the directory. For example: BlueButton/BlueButton becomes BlueButton/index.js in dist.
- The dist package.json is created in rollup.config.js
- The README_PACKAGE.md is copied over to dist as README.md.
Special notes on index.js and exports
- Export rules - Unless using an index.js file, always export as default.
- When to create an index.js file? - Only create when a component relies on others. (For example, Sveltestrap's Dropdown component works alongside the DropdownToggle, DropdownMenu, and DropdownItem components and could be packaged together.)
- Build Autogeneration - To make files more easier searchable within the IDE and to avoid redundancy when consuming the package, an auto-generated index.js file is created when the file is the same name as the parent directory and the directory doesn't already have an index.js file.
- Example: src/ui/BlueButton/BlueButton would become dist/cjs/ui/BlueButton/index.js if index.js doesn't exist in src/ui/BlueButton. This gives us the best of both worlds, by allowing us to search with IDE on BlueButton (not index.js) and allow consumers to import like this
import BlueButton from 'jl-svelte-components-library/cjs/ui/BlueButton'
.
Settings - scripts/build/*
Lint
These are based on create-svelte-app's linting rules, whith a few minor tweaks. Husky and lint-staged is used to prevent commits when any lint rules or errors are broken.
Settings - package.json (eslintConfig, lint-staged, and husky)
Prettier is used and is configured under prettier in package.json. Husky and lint-staged is used to format before commits.
Settings - package.json (eslintConfig, lint-staged, and husky)
Test
Jest, @testing-library/svelte, and svelte-hooks-testing-library are used for testing.
Settings package.json (Jest), scripts/test/*
NPM Linking for debugging
If you have a separate app and want to reference this package locally without using the registry, npm-link is supported. Here are the required steps:
- Using the terminal, run the build. You can also opt to use
build
if testing once.
npm run build-watch
cd
into the dist
directory and run npm link
cd dist
npm link
- Navigate to the root directory of the app you will be integrating with and run the following:
npm link jl-svelte-components-library
- If finished debugging, unlink in both the package source dist folder and your other app's root directory.
In the other app
npm unlink --no-save jl-svelte-components-library
In the package source dist folder
npm unlink
Create New Component
To create new components, you can use the following to generate the component, styles, stories, and test. This feature utilizes Plop.
npm run generate
Settings - scripts/templates
Links
3rd Party Issues
Storybook
- Storybook bug - shows accessibility errors on CSS Modules.
- Storybook bug - shows accessibility errors on root elements
- Storybook bug - Error in console: The pseudo class ":first-child" is potentially unsafe when doing server-side rendering.
Peer Dependency Notes
The following come up as warnings, but we don't need to add.