gulp-inline-ng2-template icon indicating copy to clipboard operation
gulp-inline-ng2-template copied to clipboard

Not working correctly with Watchify

Open Yimiprod opened this issue 8 years ago • 8 comments

After modifying a build for ionic2 to include gulp-inline-ng2-template i stumble upon a strange bug case, the transform with ng2TemplateParser isn't applied if browserify/watchify/gulpWatch is used.

I'm not sure from where the problem come from so i post it to your knowledge.

var gulp = require('gulp'),
    gulpWatch = require('gulp-watch'),
    browserify = require('browserify'),
    watchify = require('watchify'),
    tsify = require('tsify'),
    pretty = require('prettysize'),
    merge = require('lodash.merge'),
    source = require('vinyl-source-stream'),
    buffer = require('vinyl-buffer'),
    sourcemaps = require('gulp-sourcemaps'),
    uglify = require('gulp-uglify'),
    stream = require('stream'),
    ng2TemplateParser = require('gulp-inline-ng2-template/parser')
    through = require('through2');

var defaultOptions = {
  watch: false,
  src: ['./app/app.ts', './typings/index.d.ts'],
  outputPath: 'www/build/js/',
  outputFile: 'app.bundle.js',
  minify: false,
  browserifyOptions: {
    cache: {},
    packageCache: {},
    debug: true,
    base: '/app',
    useRelativePaths: true,
    supportNonExistentFiles: false
  },
  watchifyOptions: {
    verbose: true
  },
  tsifyOptions: {},
  uglifyOptions: {},
  onError: function(err){
    console.error(err.toString());
    this.emit('end');
  },
  onLog: function(log){
    console.log((log = log.split(' '), log[0] = pretty(log[0]), log.join(' ')));
  }
}

module.exports = function(options) {
  options = merge(defaultOptions, options);

  var b = browserify(options.src, options.browserifyOptions)
    .plugin(tsify, options.tsifyOptions)
    .transform(function(file) {
      return through(function (buf, enc, next) {
        ng2TemplateParser({contents: buf, path: file}, options.browserifyOptions)((err, result) => {
          this.push(result);
          process.nextTick(next);
        });
      });
    });

  if (options.watch) {
    watchify(b, options.watchifyOptions);
    b.on('update', bundle);
    b.on('log', options.onLog);
    gulpWatch('app/**/*.html', bundle);
  }

  return bundle();

  function bundle() {
    return b.bundle()
      .on('error', options.onError)
      .pipe(source(options.outputFile))
      .pipe(buffer())
      .pipe(gulp.dest(options.outputPath));
  }
}

Yimiprod avatar Aug 05 '16 09:08 Yimiprod

I have a working and dirty solution for ionic2.

Here is my code :

function templateInliner(file) {
    return through(function (buf, enc, next) {
        ng2TemplateParser({ contents: buf, path: file }, inlinerOptions)((err, result) => {
            this.push(result);
            process.nextTick(next);
        });
    }); 
}

var buildBrowserify = function (options) {
    options = merge(defaultOptions, options);
    var b = browserify(options.src, options.browserifyOptions)
      .plugin(tsify, options.tsifyOptions);

    if (options.watch) {
        b = watchify(b, options.watchifyOptions);
        b.on('update', bundle);
        b.on('log', options.onLog);
    }

    b = b.transform(templateInliner);

    return bundle();

    function bundle() {
        var debug = options.browserifyOptions.debug;
        return b
          .bundle()
          .on('error', options.onError)
          .pipe(source(options.outputFile))
          .pipe(buffer())
          .pipe(debug ? sourcemaps.init({ loadMaps: true }) : noop())
          .pipe(options.minify ? uglify(options.uglifyOptions) : noop())
          .pipe(debug ? sourcemaps.write('./', { includeContent: true, sourceRoot: '../../../' }) : noop())
          .pipe(gulp.dest(options.outputPath));
    }

    function noop() {
        return new stream.PassThrough({ objectMode: true });
    }
}

hope this helps

MiniGab avatar Aug 05 '16 14:08 MiniGab

It look a lot like my last version I posted on the forum ionic2 but thanks :D The only problem with this version is there no watching of the templates. But it work in this form.

Yimiprod avatar Aug 05 '16 15:08 Yimiprod

Can we close ?

ludohenin avatar Aug 09 '16 10:08 ludohenin

Surely this should still be open as the issue still persists (templates not being watched)?

mogusbi avatar Sep 20 '16 12:09 mogusbi

Here is my solution to trigger rebuilds when indirect dependencies change:

// ng2inlinetransform.js
var ng2TemplateParser = require('gulp-inline-ng2-template/parser');
var through = require('through2');

module.exports = function (file) {
	return through(function (buf, enc, next) {
		var stream = this
		var fileProcessorFn = function (path, ext, file, callback) {
			try {
				// emitting the file for watchify to pick it up as dependency and triggering rebuild on change
				// https://github.com/substack/watchify/issues/215
				stream.emit('file', path)
				callback(null, file);
			}
			catch (err) {
				callback(err);
			}
		}

		// rest is done as documented
		// https://github.com/ludohenin/gulp-inline-ng2-template#browserify-transform-example
		var options = {
			target: 'es6',
			useRelativePaths: true,
			templateProcessor: fileProcessorFn,
			styleProcessor: fileProcessorFn
		};

		ng2TemplateParser({contents: buf, path: file}, options)((err, result) => {
			this.push(result);
			process.nextTick(next);
		});
	});
}

Colorfulstan avatar Dec 07 '16 09:12 Colorfulstan

This should not have been close before being at least explained in the README.md. The fact that I found this was dump luck. Colorfulstan answer is by far the most descriptive, as it can easily be applied to the style method as well.

daKuleMune avatar May 12 '17 23:05 daKuleMune

Would you please make a PR for that ?

ludohenin avatar May 24 '17 12:05 ludohenin

Sure although if I fork this project, I have noticed that small scale this project is fine, but once you have a decent project size the builds can take 40+ seconds and 10 seconds to do a single file update. So I would like to see what I can do to optimize the build time. Doing manual copies of the file contents only added a second to the full build time, so there is something used here that is not scaling very well, but that is a different issue, so I will see about making a bug for that and implementing both in a fork.

daKuleMune avatar Jun 22 '17 04:06 daKuleMune