Package setup
All the Codey packages focus to support ESM & TS. The packages are also tree shackable to lower the imported size.
The Codey packages need to be used on different levels, internal and external.
Internal
Inside the mono-repo itself we will be using the packages too. Most packages depend on other packages to work correctly. For this we need to keep the source files (.vue, .ts, ...) available and configured in the package.json on the root of that package. This can be done by setting the main
and exports
option in the package.json
file to the index
file in the src
folder.
Which makes it possible to import those files inside the mono-repo, without the need of building the package itself.
{
...
"main": "./src/index.ts",
"exports": "./src/index.ts",
...
}
External
The Codey packages are build for external use in other Vue and/or Node projects. This mean they have to ship ESM and CommonJS files. (More about this at Output format).
Packages will be build in the dist
folder, to have them ready for tree shaking, they are created as seperate modules. To do this, we add a package.json
file with the module setup in. A changelog.md
file is also added to supply an overview of changes on that package.
The package.json
file is generated during the build step of the package, thanks to the ViteModuleBuilder
function from the @xerius/codey-internal-node
package. Which sets the config options right, for example the main
and exports
option is different than the package.json
in the root of the package.
Tree shaking
Tree shaking is a term commonly used within a JavaScript context to describe the removal of dead code.
It relies on the import and export statements to detect if code modules are exported and imported for use between JavaScript files. Read more about Tree shaking here.
Vite
We use the bundler feature of Vite to build the Codey packages. More information about Vite in library mode here.
Output format
The default output file format for Codey packages is ESM and CommonJS. This is set inside the vite.build
file where ViteModuleBuilder
is called as its params.
Package layout for internal use
Each of the Codey packages will need to provide a way to import them inside the Codey
monorepo itself. You can configure this by setting the following options in the package.json
file of that package.
{
"type": "module"
"main": "./src/index.js" // default es modules
"exports": {
"import":"./src/index.js"
},
}
Based on: https://nodejs.org/api/packages.html#conditional-exports
Package layout for library
Each of the Codey packages will be exported so they can be imported in other Xerius projects. You can configure this by setting the following option in the package.json
file of that package.
For JavaScript packages
{
"type": "module"
"main": "./index.js" // default es modules
"exports": {
"import": "./index.js",
"require": "./index.cjs"
},
}
For Vue packages
INFO
The chosen approach only outputs ESM and no commonJS. As we do not intend the components to be used directly in the browser.
For more information about this decision, check out the ADL record within the repo.
src structure
There is a main index
file in the src
folder that represents the entrypoint used by the package.json
for internal use. This imports all available component modules, which allows them to remain tree shakeable.
This gives the following src
structure:
- src/
- button/
- button.vue
- index.ts
index.ts
where src/index.ts
contains:
export * from "./button";
and src/button/index.ts
contains:
export { default as XerButton } from "./button.vue";
Building dist
For creating the dist output we don't simply build the root src/index.ts
file. Doing so would create a single module of all components killing the tree shaking features of the library.
Instead we run vite build on every module within the source folder create the same structure within the dist folder with the build output.
The src/index.ts
file is copied and renamed to dist/index.js
as and esm entry point.
A package.json
is also created set with this entrypoint.
This results in the following structure within the dist
folder:
- dist/
- button/
- index.js
index.js
package.json
Vite config
Using vite as our build tool, we created a module builder to handle building separate modules in order to support our packages structure.
INFO
It is possible that vite will support this out of the box at some point. At the time of writing, multiple entry points that result in multiple outputs isn't supported.
vite.base-config.js
The vite.base-config.js
is the config file for Vite. Please do not rename this file to vite.config.js as it will clash with running the programmatically build in vite.build.js
.
import path from "path";
import { fileURLToPath } from "url";
import vue from "@vitejs/plugin-vue";
import { defineConfig } from "vite";
import { externalizeDeps, createVitestConfig } from "@xerius/codey-internal-node";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default {
plugins: [externalizeDeps(), vue()],
build: {
outDir: "./dist", // lib & emptyOutDir controlled by vite.build.js
},
test: createVitestConfig(path.resolve(__dirname, "./../../reports/components")),
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
"@support": path.resolve(__dirname, "./cypress/support"),
},
},
// Server config is present for Cypress component testing
server: {
port: 5200,
fs: {
allow: ["./../../"], // Allow imports from outside this module, used by cypress
},
},
};