Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
The tiny-lr package is a lightweight LiveReload server for use during development. It allows developers to automatically refresh the browser when files are changed, improving the development workflow by providing immediate feedback.
Start a LiveReload server
This feature allows you to start a LiveReload server on a specified port (35729 in this case). The server listens for changes and notifies the browser to reload.
const tinylr = require('tiny-lr');
const server = tinylr();
server.listen(35729, function() {
console.log('... Listening on %s ...', 35729);
});
Trigger a reload
This feature allows you to manually trigger a reload by notifying the server of file changes. In this example, the server is notified that 'index.html' has changed, prompting a reload in the browser.
const tinylr = require('tiny-lr');
const server = tinylr();
server.listen(35729, function() {
console.log('... Listening on %s ...', 35729);
});
// Simulate a file change
server.changed({ body: { files: ['index.html'] } });
The livereload package provides similar functionality to tiny-lr by enabling automatic browser refreshes when files change. It is more feature-rich and supports a wider range of use cases, including integration with various build tools and task runners.
Browser-sync is a powerful tool for synchronizing file changes, interactions, and scroll positions across multiple devices. It offers more advanced features compared to tiny-lr, such as UI for controlling the server, and is often used in more complex development environments.
This script manages a tiny LiveReload server implementation.
It exposes an HTTP server and express middleware, with a very basic REST Api to notify the server of a particular change.
It doesn't have any watch ability, it must be done at the build process or application level.
Instead, it exposes a very simple API to notify the server that some changes have been made, then broadcasted to every livereload client connected.
# notify a single change
curl http://localhost:35729/changed?files=style.css
# notify using a longer path
curl http://localhost:35729/changed?files=js/app.js
# notify multiple changes, comma or space delimited
curl http://localhost:35729/changed?files=index.html,style.css,docs/docco.css
Or you can bulk the information into a POST request, with body as a JSON array of files.
curl -X POST http://localhost:35729/changed -d '{ "files": ["style.css", "app.js"] }'
# from a JSON file
node -pe 'JSON.stringify({ files: ["some.css", "files.css"] })' > files.json
curl -X POST -d @files.json http://localhost:35729
As for the livereload client, you need to install the browser extension: http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions- (note: you need to listen on port 35729 to be able to use with your brower extension)
or add the livereload script tag manually: http://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually- (and here you can choose whatever port you want)
This package exposes a bin
you can decide to install globally, but it's not recommended.
tiny-lr --help
Usage: tiny-lr [options]
Options:
-h, --help - Show help usage
-v, --version - Show package version
-p, --port - Port to listen on (default: 35729)
--pid - Path to the generated PID file (default: ./tiny-lr.pid)
The best way to integrate the runner in your workflow is to add it as a reload
step within your build tool. This build tool can then use the internal binary
linked by npm in node_modules/.bin/tiny-lr
to not rely on global installs (or
use the server programmtically).
You can start the server using the binary provided, or use your own start script.
var tinylr = require('tiny-lr');
// standard LiveReload port
var port = 35729;
// tinylr(opts) => new tinylr.Server(opts);
tinylr().listen(port, function() {
console.log('... Listening on %s ...', port);
})
You can define your own route and listen for specific request:
var server = tinylr();
server.on('GET /myplace', function(req, res) {
res.write('Mine');
res.end();
})
And stop the server manually:
server.close();
This will close any websocket connection established and emit a close event.
To use as a connect / express middleware, tiny-lr needs query / bodyParser middlewares prior in the stack (to handle POST requests)
Any handled requests ends at the tinylr level, not found and errors are nexted to the rest of the stack.
var port = process.env.LR_PORT || process.env.PORT || 35729;
var path = require('path');
var express = require('express');
var tinylr = require('tiny-lr');
var body = require('body-parser');
var app = express();
// This binds both express app and tinylr on the same port
app
.use(body())
.use(tinylr.middleware({ app: app }))
.use(express.static(path.resolve('./')))
.listen(port, function() {
console.log('listening on %d', port);
});
The port you listen on is important, and tinylr should always listen on
the LiveReload standard one: 35729
. Otherwise, you won't be able to rely
on the browser extensions, though you can still use the manual snippet
approach.
You can also start two different servers, one on your app port, the other listening on the LiveReload port.
Head over to https://github.com/gruntjs/grunt-contrib-watch
See tinylr.mk
file.
Include this file into your project Makefile to bring in the following targets:
Then define your "empty" targets, and the list of files you want to monitor.
CSS_DIR = app/styles
CSS_FILES = $(shell find $(CSS_DIR) -name '*.css')
# include the livereload targets
include node_modules/tiny-lr/tinylr.mk
$(CSS_DIR): $(CSS_FILES)
@echo CSS files changed: $?
@touch $@
curl -X POST http://localhost:35729/changed -d '{ "files": "$?" }'
reload-css: livereload $(CSS_DIR)
.PHONY: reload-css
The pattern is always the same:
touch
the directory to update its mtimelivereload
and the list of files to "watch" as prerequisitesYou can chain multiple "reload" targets in a single one:
reload: reload-js reload-css reload-img reload-EVERYTHING
Combine this with visionmedia/watch and you have a livereload environment.
watch make reload
# add a -q flag to the watch command to suppress most of the annoying output
watch -q reload
The -q
flag only outputs STDERR, you can in your Makefile redirect the
output of your commands to >&2
to see them in watch -q
mode.
npm test
var url = parse(this.request.url);
var server = this.app;
var ws = this.ws = new WebSocket('ws://' + url.host + '/livereload');
ws.onopen = function(event) {
var hello = {
command: 'hello',
protocols: ['http://livereload.com/protocols/official-7']
};
ws.send(JSON.stringify(hello));
};
ws.onmessage = function(event) {
assert.deepEqual(event.data, JSON.stringify({
command: 'hello',
protocols: ['http://livereload.com/protocols/official-7'],
serverName: 'tiny-lr'
}));
assert.ok(Object.keys(server.clients).length);
done();
};
properly cleans up established connection on exit.
var ws = this.ws;
ws.onclose = done.bind(null, null);
request(this.server)
.get('/kill')
.expect(200, function() {
console.log('server shutdown');
});
# tiny-lr
## GET /
respond with nothing, but respond.
request(this.server)
.get('/')
.expect('Content-Type', /json/)
.expect('{"tinylr":"Welcome","version":"0.0.1"}')
.expect(200, done);
unknown route respond with proper 404 and error message.
request(this.server)
.get('/whatev')
.expect('Content-Type', /json/)
.expect('{"error":"not_found","reason":"no such route"}')
.expect(404, done);
## GET /changed
with no clients, no files.
request(this.server)
.get('/changed')
.expect('Content-Type', /json/)
.expect(/"clients":\[\]/)
.expect(/"files":\[\]/)
.expect(200, done);
with no clients, some files.
request(this.server)
.get('/changed?files=gonna.css,test.css,it.css')
.expect('Content-Type', /json/)
.expect('{"clients":[],"files":["gonna.css","test.css","it.css"]}')
.expect(200, done);
## POST /changed
with no clients, no files.
request(this.server)
.post('/changed')
.expect('Content-Type', /json/)
.expect(/"clients":\[\]/)
.expect(/"files":\[\]/)
.expect(200, done);
with no clients, some files.
var data = { clients: [], files: ['cat.css', 'sed.css', 'ack.js'] };
request(this.server)
.post('/changed')
.send({ files: data.files })
.expect('Content-Type', /json/)
.expect(JSON.stringify(data))
.expect(200, done);
## GET /livereload.js
respond with livereload script.
request(this.server)
.get('/livereload.js')
.expect(/LiveReload/)
.expect(200, done);
## GET /kill
shutdown the server.
var server = this.server;
request(server)
.get('/kill')
.expect(200, function(err) {
if(err) return done(err);
assert.ok(!server._handle);
done();
});
Tiny-lr is a LiveReload implementation. They really made frontend editing better for a lot of us. They have a LiveReload App on the Mac App Store you might want to check out.
To all contributors
@FGRibreau / pid.js gist) for the background friendly bin wrapper
FAQs
Tiny LiveReload server, background-friendly
The npm package tiny-lr receives a total of 454,041 weekly downloads. As such, tiny-lr popularity was classified as popular.
We found that tiny-lr demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.