Как вставить содержимое в файл во время сборки gulp?

Мне удалось выполнить мою задачу, используя плагин gulp под названием gulp-insert следующим образом:

gulp.task('compile-js', function () {
  // Minify and bundle client scripts.
  var scripts = gulp.src([
    srcDir + '/routes/**/*.js',
    srcDir + '/shared/js/**/*.js'
  ])
    // Sort angular files so the module definition appears
    // first in the bundle.
    .pipe(gulpAngularFilesort())
    // Add angular dependency injection annotations before
    // minifying the bundle.
    .pipe(gulpNgAnnotate())
    // Begin building source maps for easy debugging of the
    // bundled code.
    .pipe(gulpSourcemaps.init())
    .pipe(gulpConcat('bundle.js'))
    // Buffer the bundle.js file and replace the appConfig
    // placeholder string with a stringified config object.
    .pipe(gulpInsert.transform(function (contents) {
      return contents.replace("'{{{appConfigObj}}}'", JSON.stringify(config));
    }))
    .pipe(gulpUglify())
    // Finish off sourcemap tracking and write the map to the
    // bottom of the bundle file.
    .pipe(gulpSourcemaps.write())
    .pipe(gulp.dest(buildDir + '/shared/js'));

  return scripts.pipe(gulpLivereload());
});

Что я делаю, так это чтение нашего файла конфигурации приложения, который управляется модулем config на npm. Получение нашего конфигурационного файла из кода на стороне сервера происходит с помощью var config = require('config');, но мы одностраничное приложение и часто нуждаемся в доступе к настройкам конфигурации на стороне клиента. Для этого я помещаю объект конфигурации в службу Angular.

Здесь Angular служба до gulp построит.

angular.module('app')
  .factory('appConfig', function () {
    return '{{{appConfigObj}}}';
  });

Заполнитель находится в строке, чтобы он был действительным JavaScript для некоторых других плагинов gulp, которые обрабатывают файл в первую очередь. Утилита gulpInsert позволяет мне вставлять такую ​​конфигурацию.

.pipe(gulpInsert.transform(function (contents) {
  return contents.replace("'{{{appConfigObj}}}'", JSON.stringify(config));
}))

Это работает, но чувствует себя немного взломанным. Не говоря уже о том, что он должен буферизировать весь связанный файл, чтобы я мог выполнить операцию. Есть ли более элегантный способ сделать то же самое? Предпочтительно тот, который позволяет потоку беспрепятственно течь без буферизации всего пакета в конце? Спасибо!

Ответ 1

Вы отметили gulp-replace-task?

Что-то вроде

[...]
.pipe(gulpSourcemaps.init())
.pipe(replace({
  patterns: [{
    match: '{{{appConfigObj}}}',
    replacement: config
  }],
  usePrefix: false
})
.pipe(gulpUglify())
[...]

Ответ 2

По общему признанию, это тоже немного взломано, но, может быть, немного лучше... Я использую envify и gulp-env в проекте React. Вы могли бы сделать что-то вроде этого.

gulpfile.js:

var config = require('config');
var envify = require('envify');

gulp.task('env', function () {
    env({
        vars: {
            APP_CONFIG: JSON.stringify(config)
        }
    });
});

gulp.task('compile-js', ['env'], function () {
  // ... replace `gulp-insert` with `envify`
});

factory:

angular.module('app')
  .factory('appConfig', function () {
    return process.env.APP_CONFIG;
  });