Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New build system #11

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/
dist/
build/

yarn.lock
yarn-error.log
Expand Down
217 changes: 136 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# TerriaJS sample plugin
# 🔌 TerriaJS sample plugin

This repository implements a sample TerriaJS plugin. The plugin implements a
custom tool for drawing an interactive 3D box on the map. It serves as an
example for setting up an loading an external plugin library that adds some new
functionality to Terria without forking it.
This repository implements a sample TerriaJS plugin which adds a custom tool to
Terria map for drawing an interactive 3D box.

It serves as an example for setting up and loading an external plugin library
that adds new functionality to Terria without forking it.

Plugins allow extending Terria in two ways:

Expand All @@ -21,121 +22,175 @@ library and are pre-requisites for understanding the code:
- [yarn](yarnpkg.com) - Package manager


Additional documentation for developing with terria is available at
[https://docs.terria.io](https://docs.terria.io/). You can also reach us through our [discussion forum](https://github.com/TerriaJS/terriajs/discussions) if you require additional help.
Additional documentation for developing with Terria is available at
[https://docs.terria.io](https://docs.terria.io/).

👷 This plugin repository is a work in progress and will be updated as the different APIs evolve. Meanwhile expect breaking changes

This plugin repository is a work in progress and will be updated as the different
APIs evolve. Meanwhile expect breaking changes 👷
💬 Reach us through our [discussion forum](https://github.com/TerriaJS/terriajs/discussions) if you require additional help.

### Current status
- [x] Load external plugins in TerriaJS at build time
- [x] Support for registering custom data types (aka catalog items)
- [x] Initial, limited support for extending UI to add custom workflows
- [ ] Testing
- [ ] Linting
## Guides

# Adding the plugin to your terriamap
- [Installing the plugin](#-installing-the-plugin)
- [Developing your own plugin](#-developing-your-own-plugin)

### Clone terriamap
```bash
git clone https://github.com/terriajs/terriamap
cd terriamap
```
## 🚀 Installing the plugin

### Add this plugin as dependency in package.json
```bash
yarn add -W 'terriajs-plugin-sample'
```
If you just want to try out the plugin to see how it works, add the plugin as a dependency to your terriamap and register it in `plugins.ts` file. The steps below show how to do that.

### Add it to the plugin registry file `plugins.ts`
```typescript
const plugins: any[] = [
import("terriajs-plugin-sample")
];
...
export default plugins;
```
1. **Clone terriamap**

Note: The file `plugins.ts` is in the terriamap project root directory.
```bash
git clone https://github.com/terriajs/terriamap
cd terriamap
```

### Now build your terriamap and start the server
2. **Add the plugin package as dependency**

```
# From the terriamap directory run
yarn run gulp dev
```
```bash
yarn add -W terriajs-plugin-sample
```

3. **Add the plugin to `terriamap/plugins.ts`**

```typescript
const plugins: any[] = [
import("terriajs-plugin-sample")
];
...
export default plugins;
```

4. **Build terriamap and run a dev server**

```bash
# From the terriamap directory run
yarn run gulp dev
```

#### Testing the plugin

Once the server is running visit http://localhost:3001 to load the app. You should see a new plugin button added to the map toolbar on the right hand side. Opening the tool will prompt the user to draw a rectangle on the map, this will place a 3d box of the same dimension on the map. Screenshot of the plugin in action:

![Sample plugin](sample-plugin.png "Sample plugin")

# Plugin development workflow
## 👩‍🔬 Developing your own plugin

This section assumes you have completed the steps for [adding the plugin to your terriamap](#adding-the-plugin-to-your-terriamap).
### Setting up development enviroment

Developing the plugin requires correctly setting up the yarn workspace. Your local directory structure should look something like:

```
terriamap/
packages/
├── plugin-sample
└── terriajs
└── plugin-sample
```

The `terriajs` and `plugin-sample` repositories must be checked out under `terriamap/packages/` folder
This `plugin-sample` repository must be checked out and setup correctly under `terriamap/packages` directory. The steps below shows how to do that.


### Checkout terriajs and sample-plugin into the packages folder
1. Checkout `plugin-sample` into the packages folder

```bash
cd terriamap/
mkdir -p packages
git clone https://github.com/terriajs/terriajs packages/terriajs
git clone https://github.com/terriajs/plugin-sample packages/plugin-sample
```
```bash
cd terriamap/
mkdir -p packages
git clone https://github.com/terriajs/plugin-sample packages/plugin-sample
```

### Add the plugin package to the [yarn workspace](https://classic.yarnpkg.com/lang/en/docs/workspaces/) settings of your terriamap `package.json` file.
2. Add the plugin package to the [yarn workspace](https://classic.yarnpkg.com/lang/en/docs/workspaces/) settings of your terriamap's `package.json` file.

Edit `package.json` for terriamap:
Edit `terriamap/package.json`:

```json
{
"private": true,
"workspaces": {
"packages": [
"packages/terriajs",
"packages/cesium",
"packages/terriajs-server"
"packages/plugin-sample" // <-- plugin-sample added here
],
```json
{
"private": true,
"workspaces": {
"packages": [
"packages/terriajs",
"packages/cesium",
"packages/terriajs-server"
"packages/plugin-sample" // <-- plugin-sample added here
],

...

"dependencies": {
"terriajs-plugin-api": "0.0.1-alpha.16",
"terriajs-plugin-sample": "0.0.1-alpha.8", // <-- plugin-sample version should match the version in packages/plugin-sample/package.json
```

...
3. Install the new dependencies

Make sure you are in the `terriamap` directory and run:

"dependencies": {
"terriajs-plugin-api": "0.0.1-alpha.16",
"terriajs-plugin-sample": "0.0.1-alpha.8", // <-- plugin-sample version should match the version in packages/plugin-sample/package.json
```
```bash
yarn install
```

### Build terriamap
4. Build the plugin-sample

From your `terriamap` folder run:
```bash
cd terriamap/packages/plugin-sample
# Start a plugin build process that watches for file changes
yarn run watch
```

5. Build terriamap

Now, from your `terriamap` folder run:

```bash
yarn install
# Starts a terriamap dev server that watches for code changes and rebuilds the map
yarn run gulp dev
```

👉 You need to keep both the yarn commands running, then start making make changes to the plugin code, terriamap will automatically
rebuild your changes.

👉 Watch for errors from the plugin build process. Note that the app page doesn't reload automatically when the code rebuilds, you
have to refresh the page to see your changes.

### Troubleshooting

The plugin provides a script to check if the dev environment has been set up correctly.

```bash
yarn install
# Starts a terriamap dev server that watches for code changes and rebuilds the map
yarn run gulp dev
$ cd packages/plugin-sample
$ yarn check-dev-env
```

### Build plugin-sample
If it generates an output like below with all checks passing, then your dev enviroment setup is probably correct.

```bash
cd terriamap/packages/plugin-sample
# Start a plugin build process that watches for file changes
yarn run watch
$ node scripts/checkDevEnv.js
✅ Find map workspace - Yes (/home/user/terriamap)
✅ Plugin added to workspaces setting - Yes
✅ Plugin added to dependencies - Yes
✅ Package versions match - Yes (1.0.0 matches ^1.0.0)
✅ Plugin import resolves correctly - Yes
✅ Plugin added to plugins registry - Yes
✅ terriajs-plugin-api versions match - Yes (0.0.1-alpha.16 matches ^0.0.1-alpha.15)
Done in 0.10s.
```

Note: you need to keep both the yarn commands running, then start making make changes to the plugin code, terriamap will automatically
rebuild your changes.
### Plugin scripts

The following scripts are available to help with development

`yarn build` - Bundle `src` and `specs` folders, typecheck and lint.

`yarn watch` - Watch files and rebuild plugin.

`yarn test` - Runs the tests

`yarn typecheck` - Typechecks the files using typescript compiler

`yarn check-dev-env` - Verifies that the plugin development enviroment is setup correctly

### Plugin API

Documentation for the plugin API is still in works, meanwhile please inspect the [terriajs-plugin-api](https://github.com/terriajs/plugin-api) repository for available APIs.



Watch for errors from the plugin build process. Note that the app page doesn't reload automatically when the code rebuilds, you
have to refresh the page to see your changes.
55 changes: 55 additions & 0 deletions karma.conf.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"use strict";

module.exports = function (config) {
config.set({
basePath: "build/specs",
proxies: {
"/data/": "/base/data",
"/images/": "/base/images",
"/test/": "/base/test",
"/build/TerriaJS/build/Cesium/build": "/base/Cesium",
"/build/Cesium": "/base/TerriaJS/build/Cesium",
"/build": "/base"
},

autoWatch: true,
autoWatchBatchDelay: 500, // Delay between tests, hopefully enough time for the bundler to finish writing everything

reporters: ["spec"],

specReporter: {
suppressErrorSummary: false,
suppressFailed: false,
suppressPassed: false,
suppressSkipped: false
},

files: [
{ pattern: "stdin.js", watched: true, nocache: true },
{
pattern: "**/*",
included: false,
served: true,
watched: false,
nocache: true
}
],
singleRun: true,
failOnEmptyTestSuite: false,
frameworks: ["jasmine"],
browsers: ["ChromeHeadless"],
detectBrowsers: {
enabled: true,
usePhantomJS: false,
postDetection(availableBrowsers) {
return availableBrowsers.filter((b) => /chrom/i.test(b));
}
},
plugins: [
require("karma-spec-reporter"),
require("karma-jasmine"),
require("karma-chrome-launcher"),
require("karma-detect-browsers")
]
});
};
5 changes: 5 additions & 0 deletions lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
👉 Note:

This folder contains plugin library code.

The code for your plugin should go under [src](../src) folder.
5 changes: 5 additions & 0 deletions src/declarations.d.ts → lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ declare module "assets/icons/*.svg" {
const icon: import("terriajs-plugin-api").IconGlyph;
export default icon;
}

declare module "sprite.svg" {
const sprite: string;
export default sprite;
}
28 changes: 28 additions & 0 deletions lib/withSvgSprite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { TerriaPlugin } from "terriajs-plugin-api";

/**
* Load SVG sprite when the plugin is intialized.
*
* SVG icons can be imported in plugin code as: `import someIcon from "assets/icons/someIcon.svg"`.
* During build, these SVG assets are merged into a single sprite. This
* function ensures the sprite is added to the DOM when the plugin is initialized.
*/
export default function withSvgSprite(plugin: TerriaPlugin): TerriaPlugin {
return {
...plugin,
register(...args) {
document.readyState === "complete"
? loadSvgSprite()
: window.addEventListener("load", () => loadSvgSprite());
plugin.register(...args);
}
};
}

function loadSvgSprite() {
import("sprite.svg").then(({ default: sprite }) => {
const div = document.createElement("div");
div.innerHTML = sprite;
document.body.appendChild(div);
});
}
Loading