Back to Blog Home
← all posts

Introducing plugin workspaces to simplify and streamline maintenance

September 14, 2020 — by Nathan Walker

Let's say you're a plugin developer and you have over 2-3 plugins. You are first of all an amazing individual for creating a plugin at all. Well done 👏🏻

Now lets say a new TypeScript version comes out...or a new Angular version...or a new Vue version...or a new NativeScript version...and perhaps there are breaking changes or features you now want to integrate with? How does it make you feel that you now need to maintain all your plugin repos and update them individually? Maybe you don't mind?

We however shudder everytime and we suspect many out there do as well.

The process is made a bit worse by the fact that most plugin repo's have their own set of demo app's (typically 3: angular, vue and vanilla), all with their own package dependencies, their own tsconfig, their own App_Resources and even their own duplicated demo code making plugin maintainance very time consuming when dependencies or configurations need to be updated.

Enter plugin workspaces to make lives easier

When we say "make lives easier", we mean for yourself and the entire community. Because we love your plugins!! However one thing noone loves is when a major version occurs and our teams and projects have to wait for plugin compatibility. This is no different in other tech communities and/or frameworks.

We wanted to address this squarely not only for right now but provide a way to make the future easier in these circumstances as well. The workspace contains helpful tooling that removes a ton of the boring mundane work ordinarily required for maintenance and really lets you focus on the source that matters.

Let's dig into the details. - Or if you prefer a video you can watch here.

Why a plugin workspace?

Workspaces are intended to manage a suite of plugins bound to an npm scope.

  1. Reduces package.json and tsconfig.json updates to 1 for entire suite of plugins and demo apps instead of multiplied by the dozens. This is a game changer and life saver for source maintenance in general.
  2. Demo'ing plugin functionality can be written once and shared across multiple NativeScript app flavors to confirm frontend framework integration compliance with ease and comfort
  3. It's clear what npm scope these plugins belong to from management perspective but also from consumer perspective
  4. It's very organized structurally
  5. You can automate build/publishing tasks in a sweeping fashion
  6. A less obvious but nice bonus is it allows your scope/username as a plugin author to become more visible inherently because it shows up neatly organized in a project's dependencies vs. being hidden in an embedded package that is not usually seen up front.

If you manage multiple npm scopes you can have a workspace for each scope to simplify your development life.

Setting up a new plugin workspace

  1. Download a zip of this repo: https://github.com/NativeScript/plugin-seed
  2. Unzip and name the folder appropriately (perhaps the name of the npm scope you intend to manage here like myscope - typically this would be your npm username or your organization)
  3. Setup workspace tooling: npm run setup
  4. Configure your npm scope: npm run config
plugin workspace config

Your plugin workspace is now setup.

Add a package

You're now ready to add a package to manage in the workspace.

npm run add

This will prompt to enter the name of the package you would like to add.

plugin workspace add

This takes care of an enormous amount of often boring and mundane work like:

  • creating README, package.json and base level structure ready to scale
  • adjusting all demo apps to use the new package
  • setting up build and publishing tasks
  • even creating a reusable demo structure allowing you to share demo setup code across all flavors so you don't have to duplicate demo code

NOTE: You can also easily bring in existing plugins - check this out for a reference

Build the package

npm start

This opens an interactive display clarifying what can be done in the workspace. You can type {package-name}.build to auto drill down the list to the build task and hit ENTER.

plugin workspace build

Your package is now built to dist/packages/{package-name} and ready to publish to npm.

The build tooling automatically handles copying in your README, the LICENSE, the typings and platforms if present.

Angular integration often involves a fair bit of mundane setup as well so if your plugin needs a specific Angular integration you can execute:

npm run add-angular

You will be prompted to type the name of the package to add Angular support to.

NOTE: generally plugins don't need Angular specifics unless they provide a custom view component - not always the case but a good rule of thumb when considering if your plugin needs Angular specifics. The tooling adds a nice registerElement line in the module prepped and ready if your plugin does need it

plugin workspace angular

This sets up the Angular bits properly to build with ng-packagr for Angular compliance now and well into the future.

Demo that package

When you used npm run add it already added a shareable demo structure which allows you to write demo code once and can just simply use it across all the demo flavors.

You'll always find it in: tools/demo/{package-name}/index.ts

This is a class which can manage all your demo code. It's automatically extended in all the demos thus allowing you to bind in demo view markup to code you've written once.

For example:

  • tools/demo/awesomeplugin/index.ts:
import { DemoSharedBase } from '../utils';
// ready for you to bring classes and symbols in to test out
import { } from '@myscope/awesomeplugin';

export class DemoSharedAwesomeplugin extends DemoSharedBase {
	testIt() {
		console.log('test awesomeplugin!');
	}
}

Publish that package

Once you've tested out your package and feel it's ready for the world, publish it to npm!

  • Confirm your package's package.json details.
  • Confirm your package's README.md reflects something helpful regarding usage.

Note: make sure you're logged into the npm username you want to publish with.

npm whoami // confirm if logged in and which username npm login // to login

npm run publish-packages
plugin workspace publish

You can type in a single package name, a comma separated list of packages, or type nothing at all and hit enter to publish all packages in the workspace. You will then be prompted to enter an explicit version or you can simply hit enter to auto bump the patch version (this also handles alpha, beta, rc semver version strings).

Scalability with 10's to 100's of packages

Whether you manage 1, a couple or even 100's of packages in your workspace the tooling has you covered. To avoid mental overload and improve focus and efficiency (as well as IDE speed) with isolated plugin development you can lean on the focus modes. We use them all the time.

npm start
plugin workspace focus

Choose the focus modes for a certain package at the bottom of the interactive display. This will isolate all demo app's to exclude source from any other package and drill down it's dependencies to only include the focused package. Also if using VS Code it will additionally isolate the IDE's file tree to only contain the focused package. More IDE support is coming.

You can reset the focus to bring all packages back and reset the demo's for all by using the focus.reset option in the npm start interactive menu.

Future maintenance

Ah yes! This is truly the big bonus with the workspace. It's based on Nrwl's excellent Nx dev tools which provides helpful tooling allowing the TSC to introduce new migrations when improvements are made or when package dependencies change helping plugin developers get the latest changes to NativeScript minimizing the labor needed for all to maintain their plugins.

In fact, we will be adding the first migration soon which will auto add Vue, React and Svelte demo app flavors already setup for your workspace so any demo code you write today can be easily bound to a view in these additional flavors soon to have fun demoing your plugin with popular NativeScript integrations.