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'); ...@@ -22,6 +22,7 @@ var through = require('through2');
var createBundle = require('./scripts/gulp/create-bundle'); var createBundle = require('./scripts/gulp/create-bundle');
var manifest = require('./scripts/gulp/manifest'); var manifest = require('./scripts/gulp/manifest');
var servePackage = require('./scripts/gulp/serve-package');
var vendorBundles = require('./scripts/gulp/vendor-bundles'); var vendorBundles = require('./scripts/gulp/vendor-bundles');
var IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production'; var IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';
...@@ -240,6 +241,19 @@ function triggerLiveReload(changedFiles) { ...@@ -240,6 +241,19 @@ function triggerLiveReload(changedFiles) {
debouncedLiveReload(); 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 * Generates the `build/boot.js` script which serves as the entry point for
* the Hypothesis client. * the Hypothesis client.
...@@ -247,8 +261,29 @@ function triggerLiveReload(changedFiles) { ...@@ -247,8 +261,29 @@ function triggerLiveReload(changedFiles) {
* @param {Object} manifest - Manifest mapping asset paths to cache-busted URLs * @param {Object} manifest - Manifest mapping asset paths to cache-busted URLs
*/ */
function generateBootScript(manifest) { 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') gulp.src('build/scripts/boot.bundle.js')
.pipe(replace('__MANIFEST__', JSON.stringify(manifest))) .pipe(replace('__MANIFEST__', JSON.stringify(manifest)))
.pipe(replace('__ASSET_ROOT__', defaultAssetRoot))
.pipe(replace('__SIDEBAR_APP_URL__', defaultSidebarAppUrl))
.pipe(rename('boot.js')) .pipe(rename('boot.js'))
.pipe(gulp.dest('build/')); .pipe(gulp.dest('build/'));
} }
...@@ -261,8 +296,6 @@ function generateManifest() { ...@@ -261,8 +296,6 @@ function generateManifest() {
gulp.src(MANIFEST_SOURCE_FILES) gulp.src(MANIFEST_SOURCE_FILES)
.pipe(manifest({name: 'manifest.json'})) .pipe(manifest({name: 'manifest.json'}))
.pipe(through.obj(function (file, enc, callback) { .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 // Trigger a reload of the client in the dev server at localhost:3000
var newManifest = JSON.parse(file.contents.toString()); var newManifest = JSON.parse(file.contents.toString());
var changed = changedAssets(prevManifest, newManifest); var changed = changedAssets(prevManifest, newManifest);
...@@ -286,9 +319,15 @@ gulp.task('watch-manifest', function () { ...@@ -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'); 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', gulp.task('build',
...@@ -299,7 +338,8 @@ gulp.task('build', ...@@ -299,7 +338,8 @@ gulp.task('build',
generateManifest); generateManifest);
gulp.task('watch', gulp.task('watch',
['start-live-reload-server', ['serve-package',
'serve-live-reload',
'watch-js', 'watch-js',
'watch-css', 'watch-css',
'watch-fonts', 'watch-fonts',
......
This diff is collapsed.
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
"eslint": "^3.0.1", "eslint": "^3.0.1",
"eslint-config-hypothesis": "^1.0.0", "eslint-config-hypothesis": "^1.0.0",
"exorcist": "^0.4.0", "exorcist": "^0.4.0",
"express": "^4.14.1",
"extend": "^2.0.0", "extend": "^2.0.0",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-batch": "^1.0.5", "gulp-batch": "^1.0.5",
......
...@@ -9,6 +9,11 @@ function changelogText() { ...@@ -9,6 +9,11 @@ function changelogText() {
return fs.readFileSync('./README.md', 'utf-8'); 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. * An HTTP and WebSocket server which enables live reloading of the client.
* *
...@@ -18,12 +23,11 @@ function changelogText() { ...@@ -18,12 +23,11 @@ function changelogText() {
* the client to live-reload. * the client to live-reload.
* *
* @param {number} port - The port that the test server should listen on. * @param {number} port - The port that the test server should listen on.
* @param {string} appServer - The URL of the Hypothesis service to load * @param {Config} config - Config for the server
* the client from.
* *
* @constructor * @constructor
*/ */
function LiveReloadServer(port, appServer) { function LiveReloadServer(port, config) {
var connections = []; var connections = [];
function listen() { function listen() {
...@@ -60,7 +64,7 @@ function LiveReloadServer(port, appServer) { ...@@ -60,7 +64,7 @@ function LiveReloadServer(port, appServer) {
}); });
var embedScript = document.createElement('script'); var embedScript = document.createElement('script');
embedScript.src = '${appServer}/embed.js'.replace('localhost', appHost); embedScript.src = '${config.clientUrl}';
document.body.appendChild(embedScript); document.body.appendChild(embedScript);
</script> </script>
</body> </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 @@ ...@@ -7,19 +7,15 @@
// already has it cached when it encounters the reference in the sidebar // already has it cached when it encounters the reference in the sidebar
// application. // application.
// Variables replaced by the build script
/* global __MANIFEST__ */ /* global __MANIFEST__ */
var boot = require('./boot'); var boot = require('./boot');
var settings = require('../shared/settings')(document); 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, { boot(document, {
assetRoot: settings.assetRoot || defaultAssetRoot, assetRoot: settings.assetRoot || '__ASSET_ROOT__',
manifest: __MANIFEST__, // Replaced by build script manifest: __MANIFEST__,
sidebarAppUrl: settings.sidebarAppUrl || 'https://hypothes.is/app.html', 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