Modern Workflow Tutorial
Warning
This page is still under construction
Set up new experiments
Requirements:
- Node.js
Step 1: Initialize experiment files
Here we are using the pcllab/create-exp
tool to quickly scaffold a new experiment.
Open a terminal where you want to create the experiment. If you are using VSCode, press Ctrl+J to open a terminal in the current directory.
# Create a new folder
npm create @pcllab/exp
# Create experiment in current folder
npm create @pcllab/exp .
Follow the instructions and finish setup by installing the dependencies.
# If a folder was created, cd into the directory
cd sample-experiment
npm install
Finally, you should have a file structure that looks like this.
📂 sample-experiment
-- 📂 node_modules
-- 📂 public
-- 📂 src
---- 📄 experiment.js
---- 📄 style.css
-- 📄 index.html
-- 📄 package.json
-- 📄 postcss.config.cjs
-- 📄 tailwind.config.cjs
-- 📄 tsconfig.json
Step 2: Adding trials and using plugins
It's time to add new trials. First we have to install the desired plugins. We will install @pcllab/consent-form-plugin
to show a consent page before the experiment starts and @jspsych/plugin-instructions
to show instructions.
With this modern workflow, we can install plugins from the terminal. These plugins are hosted on npm, a registry for javascript packages.
# we can use official jsPsych plugins
npm i @jspsych/plugin-instructions
# we can also have our own custom developed plugins
npm i @pcllab/consent-form-plugin
Using Local Plugins
It is still possible to use plugins located in a local folder. In that case, make sure to import from the relative path. It might look something like this.
This is not recommeneded, since it makes it harder to maintain plugin versions, but use it if you need to.
Add the plugin imports at the top of the file.
// These can have arbitrary names, but try to be consistent.
// Javascript default exports/imports are nameless
import jsPsychInstructions from "@jspsych/plugin-instructions";
// is equivalent to
import InstructionsPlugin from "@jspsych/plugin-instructions";
import ConsentFormPlugin from "@pcllab/consent-form-plugin";
Add the trials to the timeline. The @pcllab/consent-form-plugin
takes a url to an HTML file. This can be a local file (located in the assets
folder) or even an external url. By default, it uses an example consent form hosted on Jarvis.
Documentation for @pcllab/plugins
are on Github. Take a look at @pcllab/consent-form-plugin
.
Documentation for @jspsych
plugins are on the jsPsych website. Take a look at @jspsych/plugin-instructions
.
// ...
timeline.push({
type: ConsentFormPlugin,
// Real experiments should have a custom consent form. This is an example.
// url: assets/consent.html
});
timeline.push({
type: InstructionsPlugin,
pages: [
"Welcome to the experiment. Click next to begin.",
"This is the second page of instructions.",
"This is the final page.",
],
show_clickable_nav: true,
});
//...
Step 3: Testing experiment
Head to http://localhost:5173/
to run through your experiment.
While this is running, any change you make to your experiment will cause the page at http://localhost:5173/
to reload with your changes!
To stop the development server, press Ctrl+C (on MacOS as well!) in the terminal where you ran the original command. You can also just close the terminal if you prefer the nuclear approach.
Step 3: Saving data to Jarvis
//...
const jsPsych = initJsPsych({
on_finish: () => {
fetch("JARVIS_ENDPOINT_HERE", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(jsPsych.data.get()),
});
},
});
//...
Step 4: Uploading experiment to Jarvis
Final Demo Code
Here is the final code.
/**
* @title sample-experiment
* @description simple example using jspsych-builder
* @version 0.1.0
*
* @assets assets/
*/
// You can import stylesheets (.scss or .css).
import "../styles/main.scss";
import FullscreenPlugin from "@jspsych/plugin-fullscreen";
import HtmlKeyboardResponsePlugin from "@jspsych/plugin-html-keyboard-response";
import PreloadPlugin from "@jspsych/plugin-preload";
import { initJsPsych } from "jspsych";
import InstructionsPlugin from "@jspsych/plugin-instructions";
import ConsentFormPlugin from "@pcllab/consent-form-plugin";
/**
* This function will be executed by jsPsych Builder and is expected to run the jsPsych experiment
*
* @type {import("jspsych-builder").RunFunction}
*/
export async function run({
assetPaths,
input = {},
environment,
title,
version,
}) {
const jsPsych = initJsPsych();
const timeline = [];
// Preload assets
timeline.push({
type: PreloadPlugin,
images: assetPaths.images,
audio: assetPaths.audio,
video: assetPaths.video,
});
// Switch to fullscreen
timeline.push({
type: FullscreenPlugin,
fullscreen_mode: true,
});
timeline.push({
type: ConsentFormPlugin,
});
timeline.push({
type: InstructionsPlugin,
pages: [
"Welcome to the experiment. Click next to begin.",
"This is the second page of instructions.",
"This is the final page.",
],
show_clickable_nav: true,
});
await jsPsych.run(timeline);
fetch("", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(jsPsych.data.get()),
});
// Uncomment this line to show saved data at end
// return jsPsych;
}