Commit e743717c authored by Nick Stenning's avatar Nick Stenning Committed by GitHub

Merge pull request #229 from hypothesis/package-content-server

Add an express server which serves the package's contents.
parents 5b836627 3782856c
......@@ -22,6 +22,7 @@ var through = require('through2');
var createBundle = require('./scripts/gulp/create-bundle');
var manifest = require('./scripts/gulp/manifest');
var servePackage = require('./scripts/gulp/serve-package');
var vendorBundles = require('./scripts/gulp/vendor-bundles');
var IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';
......@@ -240,6 +241,19 @@ function triggerLiveReload(changedFiles) {
debouncedLiveReload();
}
/**
* Return the hostname that should be used when generating URLs to the package
* content server.
*
* Customizing this can be useful when testing the client on different devices
* than the one the package content server is running on.
*/
function packageServerHostname() {
return process.env.PACKAGE_SERVER_HOSTNAME || 'localhost';
}
var isFirstBuild = true;
/**
* Generates the `build/boot.js` script which serves as the entry point for
* the Hypothesis client.
......@@ -247,8 +261,29 @@ function triggerLiveReload(changedFiles) {
* @param {Object} manifest - Manifest mapping asset paths to cache-busted URLs
*/
function generateBootScript(manifest) {
var { version } = require('./package.json');
var defaultSidebarAppUrl = process.env.H_SERVICE_URL ?
`${process.env.H_SERVICE_URL}/app.html` : 'https://hypothes.is/app.html';
var defaultAssetRoot;
if (process.env.NODE_ENV === 'production') {
defaultAssetRoot = `https://cdn.hypothes.is/hypothesis/${version}/`;
} else {
defaultAssetRoot = `http://${packageServerHostname()}:3001/hypothesis/${version}/`;
}
if (isFirstBuild) {
gulpUtil.log(`Sidebar app URL: ${defaultSidebarAppUrl}`);
gulpUtil.log(`Client asset root URL: ${defaultAssetRoot}`);
isFirstBuild = false;
}
gulp.src('build/scripts/boot.bundle.js')
.pipe(replace('__MANIFEST__', JSON.stringify(manifest)))
.pipe(replace('__ASSET_ROOT__', defaultAssetRoot))
.pipe(replace('__SIDEBAR_APP_URL__', defaultSidebarAppUrl))
.pipe(rename('boot.js'))
.pipe(gulp.dest('build/'));
}
......@@ -261,8 +296,6 @@ function generateManifest() {
gulp.src(MANIFEST_SOURCE_FILES)
.pipe(manifest({name: 'manifest.json'}))
.pipe(through.obj(function (file, enc, callback) {
gulpUtil.log('Updated asset manifest');
// Trigger a reload of the client in the dev server at localhost:3000
var newManifest = JSON.parse(file.contents.toString());
var changed = changedAssets(prevManifest, newManifest);
......@@ -286,9 +319,15 @@ gulp.task('watch-manifest', function () {
}));
});
gulp.task('start-live-reload-server', function () {
gulp.task('serve-live-reload', ['serve-package'], function () {
var LiveReloadServer = require('./scripts/gulp/live-reload-server');
liveReloadServer = new LiveReloadServer(3000, 'http://localhost:5000');
liveReloadServer = new LiveReloadServer(3000, {
clientUrl: `http://${packageServerHostname()}:3001/hypothesis`,
});
});
gulp.task('serve-package', function () {
servePackage(3001, packageServerHostname());
});
gulp.task('build',
......@@ -299,7 +338,8 @@ gulp.task('build',
generateManifest);
gulp.task('watch',
['start-live-reload-server',
['serve-package',
'serve-live-reload',
'watch-js',
'watch-css',
'watch-fonts',
......
This diff is collapsed.
......@@ -43,6 +43,7 @@
"eslint": "^3.0.1",
"eslint-config-hypothesis": "^1.0.0",
"exorcist": "^0.4.0",
"express": "^4.14.1",
"extend": "^2.0.0",
"gulp": "^3.9.1",
"gulp-batch": "^1.0.5",
......
......@@ -9,6 +9,11 @@ function changelogText() {
return fs.readFileSync('./README.md', 'utf-8');
}
/**
* @typedef Config
* @property {string} clientUrl - The URL of the client's boot script
*/
/**
* An HTTP and WebSocket server which enables live reloading of the client.
*
......@@ -18,12 +23,11 @@ function changelogText() {
* the client to live-reload.
*
* @param {number} port - The port that the test server should listen on.
* @param {string} appServer - The URL of the Hypothesis service to load
* the client from.
* @param {Config} config - Config for the server
*
* @constructor
*/
function LiveReloadServer(port, appServer) {
function LiveReloadServer(port, config) {
var connections = [];
function listen() {
......@@ -60,7 +64,7 @@ function LiveReloadServer(port, appServer) {
});
var embedScript = document.createElement('script');
embedScript.src = '${appServer}/embed.js'.replace('localhost', appHost);
embedScript.src = '${config.clientUrl}';
document.body.appendChild(embedScript);
</script>
</body>
......
'use strict';
var { readFileSync } = require('fs');
var express = require('express');
var { log } = require('gulp-util');
var { version } = require('../../package.json');
/**
* An express server which serves the contents of the package.
*
* The server mirrors the URL structure of cdn.hypothes.is, an S3-backed domain
* which serves the client's assets in production.
*
* When developing the client, the Hypothesis service should be configured to
* use the URL of this service as the client URL, so that the boot script is
* returned by the service's '/embed.js' route and included in the '/app.html'
* app.
*/
function servePackage(port, hostname) {
var app = express();
var serveBootScript = function (req, res) {
var entryPath = require.resolve('../..');
var entryScript = readFileSync(entryPath).toString('utf-8');
res.send(entryScript);
};
// Set up URLs which serve the boot script and package content, mirroring
// cdn.hypothes.is' structure.
app.get('/hypothesis', serveBootScript);
app.get(`/hypothesis/${version}`, serveBootScript);
app.use(`/hypothesis/${version}/`, express.static('.'));
app.listen(port, function () {
log(`Package served at http://${hostname}:${port}/hypothesis`);
});
}
module.exports = servePackage;
......@@ -7,19 +7,15 @@
// already has it cached when it encounters the reference in the sidebar
// application.
// Variables replaced by the build script
/* global __MANIFEST__ */
var boot = require('./boot');
var settings = require('../shared/settings')(document);
// The `sidebarAppUrl` and `assetRoot` settings are set by the service which is
// serving the Hypothesis client to tell it where to load the sidebar and assets
// from.
var defaultAssetRoot = 'https://cdn.hypothes.is/hypothesis/__VERSION__/';
boot(document, {
assetRoot: settings.assetRoot || defaultAssetRoot,
manifest: __MANIFEST__, // Replaced by build script
sidebarAppUrl: settings.sidebarAppUrl || 'https://hypothes.is/app.html',
assetRoot: settings.assetRoot || '__ASSET_ROOT__',
manifest: __MANIFEST__,
sidebarAppUrl: settings.sidebarAppUrl || '__SIDEBAR_APP_URL__',
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment