separate main manifest generation from sub manifests

in dev mode always pull manifest on each request
add manifest build to gulp build task
add react bundle to manifest generation
This commit is contained in:
Berkeley Martinez
2015-08-28 15:54:40 -07:00
parent 64b63d73db
commit 6c48395868
11 changed files with 144 additions and 58 deletions

2
.gitignore vendored
View File

@@ -30,7 +30,7 @@ coverage
.remote-sync.json
server/*.bundle.js
public/js/*.bundle.js
public/js/bundle*
*.map

View File

@@ -6,6 +6,8 @@ var Rx = require('rx'),
// utils
plumber = require('gulp-plumber'),
notify = require('gulp-notify'),
reduce = require('gulp-reduce-file'),
sortKeys = require('sort-keys'),
debug = require('debug')('freecc:gulp'),
// react app
@@ -38,9 +40,10 @@ var paths = {
serverIgnore: [
'gulpfile.js',
'public/',
'!public/js/bundle.js',
'!public/js/bundle*',
'node_modules/',
'client/'
'client/',
'server/rev-manifest.json'
],
publicJs: './public/js',
@@ -70,7 +73,7 @@ var paths = {
less: './client/less/main.less',
manifest: 'server/',
manifest: 'server/manifests/',
node: {
src: './client',
@@ -87,13 +90,6 @@ var paths = {
]
};
var manifestName = 'rev-manifest.json';
var manifestOptions = {
path: paths.manifest + manifestName,
base: path.join(__dirname, paths.manifest),
merge: true
};
var webpackOptions = {
devtool: 'inline-source-map'
};
@@ -111,38 +107,6 @@ function errorHandler() {
this.emit('end');
}
gulp.task('pack-client', function() {
return gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign(
{},
webpackConfig,
webpackOptions
)))
.pipe(gulp.dest(webpackConfig.output.path));
});
gulp.task('pack-watch', function() {
return gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign(
{},
webpackConfig,
webpackOptions,
{ watch: true }
)))
.pipe(gulp.dest(webpackConfig.output.path));
});
gulp.task('pack-node', function() {
return gulp.src(webpackConfigNode.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(webpackConfigNode))
.pipe(gulp.dest(webpackConfigNode.output.path));
});
gulp.task('pack', ['pack-client', 'pack-node']);
gulp.task('serve', function(cb) {
var called = false;
nodemon({
@@ -174,7 +138,16 @@ gulp.task('serve', function(cb) {
});
});
gulp.task('sync', ['serve', 'js', 'less', 'dependents'], function() {
var syncDepenedents = [
'serve',
'js',
'less',
'dependents',
'pack-client',
'build-manifest'
];
gulp.task('sync', syncDepenedents, function() {
sync.init(null, {
proxy: 'http://localhost:3000',
logLeval: 'debug',
@@ -199,7 +172,51 @@ gulp.task('lint-json', function() {
gulp.task('test-challenges', ['lint-json']);
gulp.task('less', ['js'], function() {
gulp.task('pack-client', function() {
return gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign(
{},
webpackConfig,
webpackOptions
)))
.pipe(gulp.dest(webpackConfig.output.path))
.pipe(rev())
// copy files to public
.pipe(gulp.dest(paths.css))
// create and merge manifest
.pipe(rev.manifest('react-manifest.json'))
.pipe(gulp.dest(paths.manifest));
});
gulp.task('pack-watch', function() {
return gulp.src(webpackConfig.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(Object.assign(
{},
webpackConfig,
webpackOptions,
{ watch: true }
)))
.pipe(gulp.dest(webpackConfig.output.path))
.pipe(rev())
// copy files to public
.pipe(gulp.dest(webpackConfig.output.path))
// create manifest
.pipe(rev.manifest('react-manifest.json'))
.pipe(gulp.dest(paths.manifest));
});
gulp.task('pack-node', function() {
return gulp.src(webpackConfigNode.entry)
.pipe(plumber({ errorHandler: errorHandler }))
.pipe(webpack(webpackConfigNode))
.pipe(gulp.dest(webpackConfigNode.output.path));
});
gulp.task('pack', ['pack-client', 'pack-node']);
gulp.task('less', function() {
return gulp.src(paths.less)
.pipe(plumber({ errorHandler: errorHandler }))
// copile
@@ -212,7 +229,7 @@ gulp.task('less', ['js'], function() {
// copy files to public
.pipe(gulp.dest(paths.css))
// create and merge manifest
.pipe(rev.manifest(manifestOptions))
.pipe(rev.manifest('css-manifest.json'))
.pipe(gulp.dest(paths.manifest));
});
@@ -225,7 +242,7 @@ gulp.task('js', function() {
// copy revisioned assets to dest
.pipe(gulp.dest(paths.publicJs))
// create manifest file
.pipe(rev.manifest(manifestOptions))
.pipe(rev.manifest('js-manifest.json'))
// copy manifest file to dest
.pipe(gulp.dest(paths.manifest));
});
@@ -234,7 +251,7 @@ gulp.task('js', function() {
// sandbox depends on plugin
gulp.task('dependents', ['js'], function() {
var manifest = gulp.src(
path.join(__dirname, paths.manifest, manifestName)
path.join(__dirname, paths.manifest, 'js-manifest.json')
);
return gulp.src(paths.dependents)
@@ -242,17 +259,58 @@ gulp.task('dependents', ['js'], function() {
.pipe(revReplace({ manifest: manifest }))
.pipe(rev())
.pipe(gulp.dest(paths.publicJs))
.pipe(rev.manifest(manifestOptions))
.pipe(rev.manifest('dependents-manifest.json'))
.pipe(gulp.dest(paths.manifest));
});
gulp.task('build', ['less', 'js', 'dependents']);
function collector(file, memo) {
return Object.assign({}, JSON.parse(file.contents), memo);
}
gulp.task('watch', ['less', 'js', 'dependents', 'serve', 'sync'], function() {
function done(manifest) {
return sortKeys(manifest);
}
function buildManifest() {
return gulp.src(paths.manifest + '*.json')
.pipe(reduce('rev-manifest.json', collector, done, {}))
.pipe(gulp.dest('server/'));
}
var buildDependents = ['less', 'js', 'dependents'];
gulp.task('build-manifest', buildDependents, function() {
return buildManifest();
});
gulp.task('build-manifest-watch', function() {
return buildManifest();
});
gulp.task('build', [
'less',
'js',
'dependents',
'pack-client',
'build-manifest'
]);
var watchDependents = [
'less',
'js',
'dependents',
'serve',
'sync',
'build-manifest'
];
gulp.task('watch', watchDependents, function() {
gulp.watch(paths.less, ['less']);
gulp.watch(paths.js, ['js']);
gulp.watch(paths.challenges, ['test-challenges']);
gulp.watch(paths.dependents.concat(paths.js), ['js', 'dependents']);
gulp.watch(paths.js, ['js', 'dependents']);
gulp.watch(paths.dependents, ['dependents']);
gulp.watch(paths.manifest + '/*.json', ['build-manifest-watch']);
});
gulp.task('default', ['less', 'serve', 'sync', 'watch', 'pack-watch']);

View File

@@ -7,9 +7,8 @@
},
"scripts": {
"build": "gulp build",
"build-production": "webpack",
"start": "babel-node server/server.js",
"prestart-production": "bower cache clean && bower install && gulp build && npm run build-production",
"prestart-production": "bower cache clean && bower install && gulp build",
"start-production": "node pm2Start",
"lint": "eslint --ext=.js,.jsx .",
"test": "mocha --compilers js:babel/register"
@@ -60,6 +59,7 @@
"github-api": "~0.7.0",
"gulp-less": "^3.0.3",
"gulp-minify-css": "~0.5.1",
"gulp-reduce-file": "0.0.1",
"gulp-rev": "^6.0.1",
"gulp-rev-replace": "^0.4.2",
"gulp-webpack": "^1.5.0",
@@ -101,6 +101,7 @@
"request": "~2.53.0",
"rx": "^2.5.3",
"sanitize-html": "~1.6.1",
"sort-keys": "^1.1.1",
"source-map-support": "^0.3.2",
"thundercats": "^2.1.0",
"thundercats-react": "^0.1.0",

View File

@@ -0,0 +1,3 @@
{
"main.css": "main-6645810137.css"
}

View File

@@ -0,0 +1,3 @@
{
"commonFramework.js": "commonFramework-f2a3a38931.js"
}

View File

@@ -0,0 +1,5 @@
{
"iFrameScripts.js": "iFrameScripts-fee9f17adb.js",
"main.js": "main-c4d88948ff.js",
"plugin.js": "plugin-4564d5d4ec.js"
}

View File

@@ -0,0 +1,3 @@
{
"bundle.js": "bundle-5c9b5836a9.js"
}

View File

@@ -1,13 +1,26 @@
import manifest from '../rev-manifest.json';
const __DEV__ = process.env.NODE_ENV === 'development';
export default function({ globalPrepend = '' } = {}) {
function rev(scopedPrepend, asset) {
function rev(manifest, scopedPrepend, asset) {
return `${globalPrepend}${scopedPrepend}/${ manifest[asset] || asset }`;
}
const boundRev = rev.bind(null, manifest);
return function(req, res, next) {
res.locals.rev = rev;
// in dev environment, we reread the manifest on every call
// this means we do not need to restart server on every change to
// client code
if (__DEV__) {
const manifest = require('../rev-manifest.json');
res.locals.rev = rev.bind(null, manifest);
return next();
}
// in production we take use the initially loaded manifest
// since this should not change in production
res.locals.rev = boundRev;
next();
};
}

View File

@@ -11,4 +11,4 @@ html(ng-app='profileValidation', lang='en')
include partials/flash
#fcc!= markup
script!= state
script(src='/js/bundle.js')
script(src=rev('/js', 'bundle.js'))

View File

@@ -3,7 +3,7 @@ script(src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstra
link(rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Lato:400|Inconsolata")
link(rel='stylesheet', href='/bower_components/font-awesome/css/font-awesome.min.css')
link(rel='stylesheet', href=rev('/css', 'main.css'))
link(rel='stylesheet', href='/css/lib/Vimeo.css')
link(rel='stylesheet', href='/css/Vimeo.css')
// End **REQUIRED** includes
include meta