@cscart/tools
is a bunch of tools and presets for develop libraries, add-ons and packages for @cscart
yarn add -D @cscart/tools
- create
cscart.config.js
at the root of your project - Install required dependencies (like
@cscart/tools-gql
) -
yarn build-modules
oryarn build-modules --watch
Add NODE_ENV=production
before yarn build-modules
package.json
...
"scripts": {
"build": "NODE_ENV=production yarn build-modules"
},
Library is a bunch of reusable components and functions unioned by a single purpose or role. Such as UI library or form table.
With this tool you can create a preconfigured library available to publish to NPM. In addition you may use this configuration with your add-on for @cscart and share you code via npm package.
edit cscart.config.js
:
import { libraryPlugin } from '@cscart/tools/library-plugin'
const cscartConfig = {
rollup: () => ({
destinationPath: 'dist/',
...
entries: [
libraryPlugin,
],
}),
}
libraryPlugin
is a configuration for handle your root src scripts as library entry points, so it looks like:
const libraryPlugin = {
input: ['src/*.ts'],
...
}
It may be inconvenient to place library entrypoints at top level of src directory but this is a side effect of esm imports.
For example @cscart/ui
emits multiple separate entries like Button, Checkbox and etc available for imports like
import Button from '@cscart/ui/Button'
without path aliases or import rewrites like package.json
exports which works only in nodejs
environment.
Sharing code for reusing by other developers is a good practice. It allows to reduce develop time and bundle size, so you should keep your code accessible.
- Create properly defined
package.json
{
"name": "@vendor-name/package-name",
"version": "0.0.1",
...
"type": "module",
"scripts" : {
"build": "NODE_ENV=production yarn build-modules"
},
"devDependencies": {
...
},
}
// TODO: add auto file generating with init binary
- create
cscart.config.js
import { libraryPlugin } from '@cscart/tools/library-plugin'
const cscartConfig = {
rollup: () => ({
destinationPath: 'dist/',
externals: [ 'react' ],
entries: [
libraryPlugin,
],
}),
}
export default cscartConfig
- create
src
folder - Configure
typescript
- Create some sharable components or utils at
src
likesrc/sanitizeHtml.ts
yarn build
- cd to
dist
folder:cd ./dist
npm login
npm publish
install-esm
is a command to install directly npm package without it`s dependencies. It very handy for packages and libraries with external or bundled dependencies. And only acceptable for using in projects not libraries.
For example yarn install-esm @cscart/ui ./public
brings a fully functioning package as ESM library available stright in a browser runtime. In case when ./public
is a folder with static files emitted along with a bundle.
Variant 1: with projectPlugin
- Edit
cscart.config.js
:
import { projectPlugin } from '@cscart/tools/project-plugin'
export default {
rollup: ({isProduction}) => ({
externals: [
'@cscart/ui',
],
destinationPath: 'dist/',
entries: [
...
//
projectPlugin({
htmlPath: 'src/index.html'
}),
],
}),
}
create arrange.js
next to cscart.config.js
:
export default [
{
shell: /^@cscart\/backoffice\/features\/product_features\//,
after: /^@cscart\/backoffice\/features\/product\//,
},
]
Where shell
describes items top be moved by rules before
and after
.
If there are many items found for shell
and before
then a chunk of shell
will be placed before
Initial importmap:
{
"b": "b",
"b": "b",
"a": "a",
"b": "b",
"a": "a",
}
Rule:
{
shell: a,
before: b,
},
Result:
{
"a": "a",
"a": "a",
"b": "b",
"b": "b",
"b": "b",
}
So items will be arranged so that the last item of group a will be before the first item of group b
Initial importmap:
{
"b": "b",
"b": "b",
"b": "b",
"a": "a",
"a": "a",
}
Rule:
{
shell: a,
after: b,
},
Result:
{
"a": "a",
"a": "a",
"b": "b",
"b": "b",
"b": "b",
}
So items will be arranged so that the first item of group a will be after the last item of group b
Note that order of moved groups may not be preserved. Specify rule if items are meant to be ordered;
Now all imports from @cscart/ui
package in your project will treated as external and will not be included to your bundle. Moreover all imports like import Button from '@cscart/ui/Button'
will generate corresponding chunk for importmap.
This allows you to write esm imports without transpilation and share heavy dependencies like @cscart/ui
and @cscart/core
as native prebuilt ES modules.
All generated importmaps can be collected and inserted to available index.html
due to projectPlugin build process.
Q: I haave a heavy third-party library such as @mui, how can I share it for reusing it by other add-ons and libraries?
A: The best way is not to share such dependencies. You never know who and how will use this. But it heavily loads your filesystem and result project size. Instead of this you should consume functions and components of the library and rely on tree-shaking due to build process. Many of ESM libraries not to meant to use as native ESM at browser runtime. There is necessity to bundle this libraries. So other developers should too. Example: Your project:
import Button from '@mui/Button'
Some third-party add-on for your project:
import Checkbox from '@mui/Checkbox'
Conslusion: consume only necessary components. Create reusable code and share it with libraryPlugin.