Collection of examples of how you would use Next.js with Vovk.ts in practice. You can see them live on vovk-examples.vercel.app. The client-side library generated with Vovk.ts is published as vovk-examples NPM package as an illustration on how you can distribute API library of your REST endpoints to be used by other projects.
Install:
npm i vovk-examples
Use:
import { BasicController } from 'vovk-client';
const response = await BasicController.getHello();
The documentation assumes that you already have set up Next.js + Vovk.ts project and now you want to create an NPM package to publish a TypeScript library for your REST API.
You can use any bundler but at this example we're going to use the most common one.
Install Webpack and ts-loader.
npm i -D ts-loader webpack webpack-cli
Create a Webpack config that inits the loader. The entry
and output.filename
definitions can vary for your project but this syntax is going to enable Worker interface bundling that's explained below. See full Webpack config here.
// webpack.config.js
const path = require('path');
module.exports = {
entry: {
index: './index.ts',
},
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: 'ts-loader',
options: {
configFile: 'tsconfig.webpack.json',
},
},
],
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
library: { type: 'commonjs2' },
},
};
Create tsconfig.webpack.json, enable decorators, add outDir
and include required files. See full tsconfig here.
{
"compilerOptions": {
// ...
"experimentalDecorators": true,
"outDir": "./dist"
},
"include": ["./src/app/api/[[...vovk]]/route.ts"]
}
In the root of the project create index.ts
with the following content:
// index.ts
export * from './.vovk';
As you can see the entry file exports everything as is but if needed you can rename variables or create an abstraction to make your library look nicer to the end user.
// index.ts
import type { VovkClientBody } from 'vovk';
import { FormController } from './.vovk';
/*
import { form } from 'my-lib';
await form.createUser(...);
*/
export const form = FormController;
// or
/*
import { createUser } from 'my-lib';
await createUser(...);
*/
export function createUser(body: VovkClientBody<typeof FormController.createUser>) {
return FormController.createUser({ body })
}
You may want to exclude this file at the main tsconfig.ts in order to fix deployment errors because .vovk folder doesn't exists and the imports/re-exports are going to be considered as invalid.
// tsconfig.ts
"exclude": ["node_modules", "index.ts"],
As you also may notice the entry point file re-exports or imports the library from .vovk folder from the root of the repository. In our case the Vovk.ts library is compiled to this folder to avoid limitations trying to bundle files from node_modules and keep the configuration as simple as possible. This does nothing to the main application logic you implement and does nothing to the original generated client node_modules/.vovk, in other words your app doesn't need to reconfigured in order to create the package. You can add .vovk to .gitignore file to exclude it from Git index as well ass the dist folder that used as a destination for the compiled files.
# .gitignore
dist
.vovk
At the package.json create build-client NPM script
...
"scripts": {
...
"build-client": "rm -rf .vovk dist && VOVK_PREFIX=https://vovk-examples.vercel.app/api VOVK_OUT=.vovk vovk generate && webpack --mode production"
},
...
The script does the following:
- Removes the existing .vovk (compiled by Vovk.ts) and dist (compiled by Webpack) folders (you can use rimraf to do that on Windows).
- Runs
vovk generate
withVOVK_PREFIX
variable that indicates the root endpoint of your REST API andVOVK_OUT
that makes the client to be compiled to .vovk in the root of the project. webpack --mode production
compies the bundle.
- Run
npm run build-client
. - Bump the version with
npm version patch
or manually. - Run
npm run publish
to publish.
Depending ont he name of your library defined at package.json you can now install and import the library in another project.
npm i my-lib
import { FormController } from 'my-lib';
await FormController.createUser(...);
To keep the configuration as simple as possible, you can compile your WPC Classes separately from the main bundle.
// webpack.config.js
module.exports = {
entry: {
index: './index.ts',
HelloWorker: './src/modules/worker/HelloWorker.ts',
HelloWorkerYield: './src/modules/worker-yield/HelloWorkerYield.ts',
},
// ...
The package is going to include additional files that need to be initalised and injected to the worker client interface when the library imported in another project. Check WPC Class for more info.
import { HelloWorker } from 'my-lib';
// ...
HelloWorker.use(new Worker(new URL('my-lib/dist/HelloWorker.js', import.meta.url)));
await HelloWorker.heavyCalculation();