Three.js JavaScript 3D library on a WordPress site - wordpress

I wanted to use Three.js JavaScript 3D library on my WordPress site, so I tried the three.min.js in the:
body of a post
<script src="/three.min.js"></script>
then the footer
<script type='text/javascript' src='/three.min.js'></script>
and now the Pinboard: Theme Functions (functions.php) file
function pinboard_enqueue_scripts() {
wp_register_script('three.min', '/three.min.js', true);
wp_enqueue_script( 'three.min' );
}
add_action( 'wp_enqueue_scripts', 'pinboard_enqueue_scripts' );
Unfortunately the cube from Mr.doob’s page is not showing up on my Cube page.
Your help in running the Three.js on my WordPress site would be greatly appreciated.
Thank you.

Well that has also a lot to do with CSS ^^ I do the same at http://lizkats.com, maybe get some inspiration there.
In the wordpress theme editor I edited the header file (header.php) to include both the library and the script there. I used an absolute URL (i.e. I cheated, maybe you have more patience and find a better way) and inserted libraries and script like following:
</head>
<body <?php body_class(); ?>>
<!-- Here (after head & body in Heaper.php) starts the stuff I added myself -->
<div id="3dcontainer" style="position: fixed; z-index: -1;"></div>
<div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner" style="overflow: visible;">
<script src="http://lizkats.com/wp-content/fromGame/three.js"></script>
<script src="http://lizkats.com/wp-content/fromGame/models/modelMeerkatPoseWeb.js"></script>
<script>
var container, stats;
var camera, scene, renderer, objects;
var clock = new THREE.Clock();
function init() {
container = document.getElementById('3dcontainer');
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.5, 200 );
camera.position.set( 0.4, 0.42, 0.9 );
scene = new THREE.Scene();
// ...
// Renderer
renderer = new THREE.WebGLRenderer( { alpha: true } );
renderer.setClearColor( 0x453326, 1);
renderer.setSize( window.innerWidth, window.innerHeight);
container.appendChild( renderer.domElement );
animate();
}
init();
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var delta = clock.getDelta();
renderer.render( scene, camera );
}
</script>
The 3dcontainer is where I insert the canvas object.
Further you'll also have to update your style.css in order to make it look the way you want. Here's a paste of my current (entire) stylesheet: http://pastebin.com/9uUiAZhY
Good luck!

This is popular search, so I decided to write little help for feature readers.
I'm assuming that you have properly installed and working Wordpress.
Installation without bundlers
The simplest way to make example three.js cube working on your Wordpress home page, following three.js docs:
1. Depending on your Wordpress configuration open index.php / page.php
2. First we need to import library, there are two common ways to do that via : npm or cdn.
CDN:
<script type="module">
// Find the latest version by visiting https://cdn.skypack.dev/three.
import * as THREE from 'https://cdn.skypack.dev/three#0.137.5';
const scene = new THREE.Scene();
</script>
NPM (check Downloading and installing Node.js and npm if needed):
Open your terminal and run npm install three. This will create node_modules folder in your directory, which contains library. Example provided in three.js docs, assumes that you will bundle html. Although we will import our library without bundling for the needs of this question.
Open functions.php and enqueue library:
wp_enqueue_script( 'three-min', get_template_directory_uri() . '/node_modules/three/build/three.min.js', array(), null, false );
Make a notice, it's placed in <head> so it will be run before our script.
3. Add the basic cube to the script:
<script type="module">
// Find the latest version by visiting https://cdn.skypack.dev/three.
import * as THREE from 'https://cdn.skypack.dev/three#0.137.5';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
for NPM type="module" and import * as THREE from 'https://cdn.skypack.dev/three#0.137.5'; is not needed. Because we have imported it already using UMD.
I might update it in the future for Webpack bundler integration.

Related

Next 13 & Tailwind Darkmode Flickering

I'm looking to achieve the results listed in this blog but with Next 13's new appDir.
Flicker-free Dark Theme Toggle
My darkmode flickers on refresh.
// pages/_app no longer exist. How do you alter the < themeProvider > to match the new layout.tsx?
My files are listed below. Thank you for any knowledge.
Quick Setup
npx create-next-app#latest -D tailwindcss my-app
Next 13 Setup Documentation
https://beta.nextjs.org/docs/upgrade-guide
// app/layout.tsx
import Darkmode from './darkmode'
export default function RootLayout({
children,
}:{
children: React.ReactNode;
}) {
return (
<html lang="en">
<head></head>
<body>
<button className='h-8 w-8 p-1 bg-blue-300 dark:bg-red-600 rounded-full'>
<Darkmode/>
</button>
{children}
</body>
</html>
)
}
// app/darkmode.tsx
'use client'
import{useEffect, useState}from'react';
function Darkmode() {
const[darkMode,setDarkMode]=useState(false);
useEffect(()=>{
if(localStorage.theme==='dark'||(!('theme'in localStorage)&&window.matchMedia('(prefers-color-scheme:dark)').matches)){
document.documentElement.classList.add('dark')
localStorage.theme='dark'
setDarkMode(!darkMode)
}else{
document.documentElement.classList.remove('dark')
localStorage.theme='light';
}
},[])
const changeTheme=()=>{
localStorage.theme=darkMode?'light':'dark'
setDarkMode(!darkMode)
if(darkMode){
document.documentElement.classList.remove("dark");
}else{
document.documentElement.classList.add("dark");
}
};
return (
<div className='h-6 w-6' onClick={changeTheme}/>Dark</div>
);
}
export default Darkmode;
Lee over at vercel actually has a really cool way of doing this using tailwind in his blog example. I would recommend that pattern as it is much easier to maintain.
You can set a dark mode theme in your tailwind config and use the Nextjs ThemeProvider component to change it. Here is the code from Lee and the tailwind docs. Good luck.

It is possible to using flowbite (or any UI component libraries) for tailwindCSS on angular 12?

I'm trying to use tailwindCSS on angular 12, and it's works fine.
My question is about using flowbite or tailwindui for UI component - is it support on angular too?
because i'm trying to flow the instructions of flowbite and it's not working
https://flowbite.com/docs/getting-started/quickstart/
the css work's fine but not the script.
For example I try to build a dropdowns like this - and it's not working (i'm not getting any error on console)
https://flowbite.com/docs/components/dropdowns/#
What is wrong ?
Having the same issue, tried:
Using scripts:["../path/to/#themesberg/flowbite/dist/flowbite.bundle.js"] in angular.json
Adding <script src="../path/to/#themesberg/flowbite/dist/flowbite.bundle.js"></script> on the head of index.hmtl
Update:
Adding import '#themesberg/flowbite'; on either the main.ts or polyfills.ts correctly exports the functions to the vendor.js or polyfills.js respectfully. But even though they are present, the event listeners are not working:
() => {
const toggleCollapse = (elementId, show = true) => {
const collapseEl = document.getElementById(elementId);
if (show) {
collapseEl.classList.remove('hidden');
} else {
collapseEl.classList.add('hidden');
}
}; // Toggle target elements using [data-collapse-toggle]
document.querySelectorAll('[data-collapse-toggle]').forEach(function (collapseToggleEl) {
var collapseId = collapseToggleEl.getAttribute('data-collapse-toggle');
collapseToggleEl.addEventListener('click', function () {
toggleCollapse(collapseId, document.getElementById(collapseId).classList.contains('hidden'));
});
});
window.toggleCollapse = toggleCollapse;
/***/
},

Masonry layout with Next.js

I am developing a multi-page website using Next.js for the frontend and Strapi for the backend. On the blog page, the data is dynamically fetched from the database. I am trying to display this data in an adaptive layout using Masonry.
The problem I am having is that on first load, the page displays every grid-item in a single vertical column. On reload, the Masonry layout then takes effect, but with some overlapping items. On a second reload, everything then displays properly and is even responsive. However, if I navigate away from the page and come back, it is back to square one.
Here is the code for the blog page :
import React from 'react';
import Layout from '../components/StaticLayout';
import Link from 'next/link';
import fetch from 'isomorphic-unfetch';
import '../../static/styles.min.css';
let Masonry = '';
export default class Blog extends React.Component {
constructor(props) {
super(props);
this.state = {
appIsMounted: false
}
}
static async getInitialProps() {
const res = await fetch('http://localhost:1337/blogposts');
const data = await res.json();
return {
posts: data
};
}
async componentDidMount() {
let masonry = await import('masonry-layout');
this.setState({
appIsMounted: true
})
}
render() {
return (
<Layout>
<h1 className="blogHeader">Blog</h1>
{this.state.appIsMounted ? (
<div className="grid js-masonry" data-masonry-options='{ "itemSelector": ".grid-item", "columnWidth": 400 }'>
{this.props.posts.map(
post => (
<div key={post.id} className="grid-item">
<Link href="/p/[id]" as={`/p/${post.id}`}>
<img src={`http://localhost:1337${post.Image.url}`} alt={post.Image.name} className="postImage" />
</Link>
<div className="text">
<Link href="/p/[id]" as={`/p/${post.id}`}>
<a className="postLink">{post.Title}</a>
</Link>
<p className="blurb">{post.Content.substring(0, 300) + '...'}</p>
<Link href="/p/[id]" as={`/p/${post.id}`}>
<button className="viewPost">Read More!</button>
</Link>
</div>
</div>
)
)}
</div>
) : null}
</Layout>
)
}
}
To be noted, the StaticLayout script only ensure the header is at the top of each page.
EDIT
So I've solved the overlapping part of the problem. Instead of initializing Masonry in the html, I've added a js file to './static'. On my blog page, I've added the following :
import Head from 'next/head'
...
return(
<Head>
<script type="text/javascript" src="/static/runMasonry.js"></script>
</Head>
...
)
And the runMasonry.js file looks like this :
window.onload = function () {
var elem = document.querySelector('.grid');
var msnry = new Masonry(elem, {
// options
itemSelector: '.grid-item',
columnWidth: 160,
gutter: 20
});
}
But when I first arrive on the page or navigate away and come back, the elements are still displayed in a column and require a reload.
Came up with a non-ideal fix, but it works.
Added the following code to the runMasonry.js file :
window.addEventListener("DOMSubtreeModified", function () {
var elem = document.querySelector('.grid');
if (elem) {
var msnry = new Masonry(elem, {
// options
itemSelector: '.grid-item',
columnWidth: 160,
gutter: 20
});
}
});
So it detects when new page content is loaded and, if it finds my .grid element, re-runs masonry.
Leaving this open in case someone can provide a better, long-term solution.

Multi-language support for different map views with HERE

currently I am trying to display the HERE map with the JavaScript API in German.
According to this example it is possible to change the language of the map. This works fine for German when the map is first loaded. However, when the map view is changed e.g. to 'Satellite' these settings seem to be lost. In all the multi-language examples I found online, the option to change the map view is disabled. Can the language be set for example to German for all the available views or is this customizing restricted to one view only and I need to disable the other views?
Thanks in advance, Team DG7
Below is the entire sample code to have all views of the map in Chinese Language. You can change it according to your needs.
Please use your own app id and app code. The main snippet in the below code is the createDefaultlayers where you speciy the language parameter for all layers.
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320,
lg: 'CHI'
});
Happy Coding!
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="UTF-8" >
/**
* Switches the map language to simplified Chinese
*
* #param {H.Map} map A HERE Map instance within the application
* #pama {H.service.Platform} platform A stub class to access HERE services
*/
function switchMapLanguage(map, platform){
var mapTileService = platform.getMapTileService({
type: 'base'
}),
// Our layer will load tiles from the HERE Map Tile API
chineseMapLayer = mapTileService.createTileLayer(
'maptile',
'normal.day',
pixelRatio === 1 ? 256 : 512,
'png8',
{lg: 'CHI', ppi: pixelRatio === 1 ? undefined : 320}
);
map.setBaseLayer(chineseMapLayer);
// Display default UI components on the map and change default
// language to simplified Chinese.
// Besides supported language codes you can also specify your custom translation
// using H.ui.i18n.Localization.
var ui = H.ui.UI.createDefault(map, defaultLayers, 'zh-CN');
}
/**
* Boilerplate map initialization code starts below:
*/
//Step 1: initialize communication with the platform
var platform = new H.service.Platform({
app_id: 'YOUR-APP-ID',
app_code: 'YOUR-APP-CODE',
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320,
lg: 'CHI'
});
//Step 2: initialize a map - this map is centered over Hong Kong.
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map,{
center: {lat:22.2783, lng:114.1588},
zoom: 12,
pixelRatio: pixelRatio
});
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Now use the map as required...
switchMapLanguage(map , platform);
</script>
</body>
</html>

How to use Sass inside a Polymer component

I'm currently using Polymer as my front end development framework. I love SASS.
Now I understand I can create a Sass file and import it like I normally would.
However, I've really gotten into the habit of using style tags within my web components.
Basically the workflow I am looking for is to be able to simply define a script tag within my Web Component maybe add type='sass; to it. Then have grunt go through and compile all of my SASS within those tags before outputting the files to my .tmp directory.
Is something like this achievable with something like Grunt or Gulp? If so what are the best modules to help me achieve this?
My implementation is based on a replacement of a tag inside the Polymer html file. I'm using gulp but could be changed to use simply fs.
The files structure should be as this example:
app-view
|- app-view.html
|- app-view.scss
app-view.html:
<dom-module id="app-view">
<template>
<style>
<!-- inject{scss} -->
</style>
</template>
</dom-module>
app-view.scss:
:host{
margin-top: 50px;
justify-content: center;
display: flex;
}
#container{
font-size: 12px;
h1{
font-size: 20px;
}
}
gulpfile.js:
var gulp = require('gulp');
var nodeSass = require('node-sass');
var path = require('path');
var fs = require('fs');
var map = require('map-stream');
var srcPath = 'src/';
var buildPath = 'build/';
var buildSrcPath = path.join(buildPath, 'target');
gulp.task('processComponents', function () {
return gulp.src([srcPath + '/components/**/*.html'])
.pipe(map(function (file, cb) {
var injectString = '<!-- inject{scss} -->';
// convert file buffer into a string
var contents = file.contents.toString();
if (contents.indexOf(injectString) >= 0) {
//Getting scss
var scssFile = file.path.replace(/\.html$/i, '.scss');
fs.readFile(scssFile, function (err, data) {
if (!err && data) {
nodeSass.render({
data: data.toString(),
includePaths: [path.join(srcPath, 'style/')],
outputStyle: 'compressed'
}, function (err, compiledScss) {
if (!err && compiledScss) {
file.contents = new Buffer(contents.replace(injectString, compiledScss.css.toString()), 'binary');
}
return cb(null, file);
});
}
return cb(null, file);
});
} else {
// continue
return cb(null, file);
}
}))
.pipe(gulp.dest(path.join(buildSrcPath, 'components')));
});
RESULT:
<dom-module id="app-view">
<template>
<style>
:host{margin-top:50px;justify-content:center;display:flex}#container{font-size:12px}#container h1{font-size:20px}
</style>
</template>
</dom-module>
First of all, a million Thanks and gratitude goes to David Vega for showing how it is done! I made some adaptations and optimized the code a little bit.
Here's the github for the file!
https://github.com/superjose/polymer-sass/tree/master
Well, this took me a while. Here it goes!
Polymer unleashed version 1.1. From its website:
Note: Style modules were introduced in Polymer 1.1; they replace the
experimental support for external stylesheets.
Instead, they now support "shared styles".
So this means that we can import .html files with css content. The problem is that we can't do .sass the normal way.
Fortunately here's a simpler solution.
What the following script does is that it gets your .scss files, parse them, and inject them into the shared style .html.
Here is the code. Below it, it's step by step on how to use and setup:
var gulp = require('gulp');
var nodeSass = require('node-sass');
var path = require('path');
var fs = require('fs');
var map = require('map-stream');
var basePath = "app/";
var excludeDir = basePath+"bower_components/";
var ext = "**/*.html";
/**
* We need to specify to nodeSass the include paths for Sass' #import
* command. These are all the paths that it will look for it.
*
* Failing to specify this, will NOT Compile your scss and inject it to
* your .html file.
*
*/
var includePaths = ['app/elements/**/'];
gulp.task('watchSass', function(){
gulp.watch(['app/**/*.scss', '!app/bower_components/**/*.scss'], ["injectSass"]);
});
//This is currently not used. But you can enable by uncommenting
// " //return gulp.src([basePath+ext,...excludeDirs])" above the return.
var excludeDirs = [`!${basePath}/bower_components/${ext}`,`!${basePath}/images/${ext}`]
/**
*
* Enable for advanced use:
*
*
*/
gulp.task('injectSass', function () {
/* Original creator: David Vega. I just modified
* it to take advantage of the Polymer 1.1's shared styles.
*
* This will look all the files that are inside:
* app/elements folder. You can change this to match
* your structure. Note, this gulp script uses convention
* over configuration. This means that if you have a file called
* my-element-styles.html you should have a file called
* my-element-styles.scss
*
* Note #2:
* We use "!" (Exclamation Mark) to exclude gulp from searching these paths.
* What I'm doing here, is that Polymer Starter Kit has inside its app folder
* all the bower dependencies (bower_components). If we don't specify it to
* exclude this path, this will look inside bower_components and will take a long time
* (around 7.4 seconds in my machine) to replace all the files.
*/
//Uncomment if you want to specify multiple exclude directories. Uses ES6 spread operator.
//return gulp.src([basePath+ext,...excludeDirs])
return gulp.src([basePath+ext, '!'+excludeDir+ext])
.pipe(map(function (file, cb) {
//This will match anything between the Start Style and End Style HTML comments.
var startStyle = "<!-- Start Style -->";
var endStyle = "<!-- End Style -->";
//Creates the regEx this ways so I can pass the variables.
var regEx = new RegExp(startStyle+"[\\s\\S]*"+endStyle, "g");
// Converts file buffer into a string
var contents = file.contents.toString();
//Checks if the RegEx exists in the file. If not,
//don't do anything and return.
//Rewrote the if for reduced nesting.
if (!regEx.test(contents)) {
//Return empty. if we return cb(null, file). It will add
//the file that we do not want to the pipeline!!
return cb();
}
/**
* Getting scss
* This will get the .html file that matches the current name
* This means that if you have my-app.component.html
* this will match my-app.component.scss. Replace with .sass if you
* have .sass files instead.
*/
var scssFile = file.path.replace(/\.html$/i, '.scss');
fs.readFile(scssFile, function (err, data) {
//Rewrote the if for reduced nesting.
//If error or there is no Sass, return null.
if (err || !data) {
return cb();
}
nodeSass.render({
data: data.toString(),
includePaths: [path.join('app', 'style/'), ...includePaths],
outputStyle: 'compressed'
}, function (err, compiledScss) {
//Rewrote the if for reduced nesting.
//If error or there is no Sass, return null.
if (err || !compiledScss)
return cb();
/**
* What we are doing here is simple:
* We are re-creating the start and end placeholders
* that we had and inject them back to the .html file
*
* This will allow us to re-inject any changes that we
* do to our .scss or files.
*
*/
var injectSassContent = startStyle +
"<style>" +
compiledScss.css.toString() +
"</style>" +
endStyle;
//This is going to replace everything that was between the <!-- Start Style --> and
// "<!-- End Style -->"
file.contents = new Buffer(contents.replace(regEx, injectSassContent), 'binary');
//This return is necessary, or the modified map will not be modified!
return cb(null,file);
});
});
}))
.pipe(gulp.dest(basePath));
}); //Ends
1) Setup your element:
Suppose you have an element called "hero-tournament":
<dom-module id="hero-tournament">
<template>
<style>
</style>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'hero-tournament',
});
})();
</script>
</dom-module>
And you want to inject your .scss file into it.
Create besides it two new files:
hero-tournament-style.html
hero-tournament-style.scss
Inside the first file, hero-tournament-style.html write the following:
<!-- hero-tournament-style.html -->
<dom-module id="hero-tournament-style">
<template>
<!-- Start Style -->
<style>
</style>
<!-- End Style -->
</template>
</dom-module>
Note the:
<!-- Start Style --> <!-- End Style -->
comments?
These are SUPER important, as all the css will go inside these ones. These are case sensitive, but not position sensitive. Be sure to include them inside your template tags and outside of your style tags.
Then on your hero-tournament-style.scss file, include your sass' css:
(Example)
.blank{
display: none;
}
2) Run Gulp:
gulp watchSass
Bam! You'll see that your "hero-tournament-style.scss" file will be overwritten with your css!!!
<!-- -hero-tournament-style.html -->
<dom-module id="-hero-tournament-style">
<template>
<!-- Start Style -->
<style>.blank{display:none}
</style><!-- End Style -->
</template>
</dom-module>
Now, you can refer that file anywhere!!! Remember your first element, the original one ("hero-tournament.html")? Do the following to it:
<!-- import the module -->
<link rel="import" href="../path-to-my-element/.html">
<dom-module id="hero-tournament">
<template>
<!-- include the style module by name -->
<style include="hero-tournament-styles"></style>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'hero-tournament',
});
})();
</script>
</dom-module>
Some last notes:
Using SASS Imports
Using Sass imports is easy, just need to watch out for the following:
In the gulpfile there is a variable called: "includePaths". It's an array in which nodeSass will look for all the imports. Failing to specify your import in any of the mentioned places, will prevent your file from injecting and compiling. By default, in the script there is a 'app/style' directory which will look for it.
Folder structure
Folder structure is important, and it can be adapted as your liking.
This assumes that your elements are inside an "app" folder brother to your gulpfile (In the same hierarchy):
-gulpfile.js
/app
/element
/hero-tournament
-hero-tournament.html
-hero-tournament-styles.html
-hero-tournament-styles.scss
/maybe-other-folder
If you want to change your folder structure, change the "basePath" variable. Be sure to check for leading "/" so you don't mess up your structure!
How do I run my gulpfile?
It's easy:
Call the "watchSass" method for watching, or "injectSass" for using it once.
gulp watchSass
gulp injectSass
More information in the github page!!!
In Polymer 2.0 it's also possible to just import a stylesheet inside the element's template like that:
<dom-module id="your-module-name">
<template>
<style><!-- you can also add additional styling in here --></style>
<link rel="stylesheet" href="link_to_stylesheet.css">
<!-- your template in here -->
</template>
<script>
//your element class + registration here
</script>
</dom-module>
Inside of the stylesheet you can style your content just like in the style-tag. The styles only affect the element and its content.
If you want to use SASS, Stylus, LESS or anything like that, you just have to use a middleware (HOWTO: Stack Overflow) in Express that renders the SASS-Code into CSS on every request. I prefer this solution over GULP/GRUNT task, because I think it's way easier, because you don't always have to run the Task, because of the Middleware it's compiling automatically whenever it's needed.
I hope that helps you

Resources