【发布时间】:2014-04-22 21:29:31
【问题描述】:
在我的 gulpfile 中,我在字符串中有一个版本号。我想将版本号写入文件。在 Gulp 中有没有很好的方法来做到这一点,还是我应该看看更通用的 NodeJS API?
【问题讨论】:
-
确切要求..围绕版本号...我想用它来将其附加到资产 url 以进行缓存爆破
在我的 gulpfile 中,我在字符串中有一个版本号。我想将版本号写入文件。在 Gulp 中有没有很好的方法来做到这一点,还是我应该看看更通用的 NodeJS API?
【问题讨论】:
如果您想以类似 gulp 的方式执行此操作,您可以创建一个“假”乙烯基文件流,并照常致电 pipe。这是一个用于创建流的函数。 “stream”是一个核心模块,所以你不需要安装任何东西:
const Vinyl = require('vinyl')
function string_src(filename, string) {
var src = require('stream').Readable({ objectMode: true })
src._read = function () {
this.push(new Vinyl({
cwd: "",
base: "",
path: filename,
contents: Buffer.from(string, 'utf-8')
}))
this.push(null)
}
return src
}
你可以这样使用它:
gulp.task('version', function () {
var pkg = require('package.json')
return string_src("version", pkg.version)
.pipe(gulp.dest('build/'))
})
【讨论】:
_read 中的两行来处理多个文件字符串。在这种情况下,文件对象数组将是更好的sting_src 参数。
Buffer作为全局(nodejs.org/api/buffer.html)。
this.push(null) 对我抛出错误 stream.push() after EOF,不知道为什么。注释掉该行有效,但随后 gulp 无限期挂起。
它几乎是一个单行节点:
require('fs').writeFileSync('dist/version.txt', '1.2.3');
或者来自 package.json:
var pkg = require('./package.json');
var fs = require('fs');
fs.writeFileSync('dist/version.txt', 'Version: ' + pkg.version);
我使用它在一个易于访问的文件中指定构建日期,因此我在build 任务中的常用return gulp.src(...) 之前使用此代码:
require('fs').writeFileSync('dist/build-date.txt', new Date());
【讨论】:
writeFile 函数现在是异步的,需要回调。您可能希望使用“writeFileSync”或更好的响应式,并在文件实际写入磁盘时传递回调以执行某些操作。
.writeFileSync 行之后添加gulp.src('dist/version.txt').pipe(…)。
这也可以通过vinyl-source-stream 完成。请参阅 gulp 存储库中的 this document。
var gulp = require('gulp'),
source = require('vinyl-source-stream');
gulp.task('some-task', function() {
var stream = source('file.txt');
stream.end('some data');
stream.pipe(gulp.dest('output'));
});
【讨论】:
.pipe(),这可能是最干净的节点方式
process.nextTick(fn() { stream.end(); }吗?
process.nextTick 回调中结束了流,因为这是在 gulp 文档中完成的。似乎没有必要,所以我更新了答案。感谢您指出这一点。
根据 Gulp 的维护者的说法,将字符串写入文件的首选方法是使用带有任务回调的fs.writeFile。
var fs = require('fs');
var gulp = require('gulp');
gulp.task('taskname', function(cb){
fs.writeFile('filename.txt', 'contents', cb);
});
来源:https://github.com/gulpjs/gulp/issues/332#issuecomment-36970935
【讨论】:
你也可以使用gulp-file:
var gulp = require('gulp');
var file = require('gulp-file');
gulp.task('version', function () {
var pkg = require('package.json')
return gulp.src('src/**')
.pipe(file('version', pkg.version))
.pipe(gulp.dest('build/'))
});
或者不使用gulp.src():
gulp.task('version', function () {
var pkg = require('package.json')
return file('version', pkg.version, {src: true})
.pipe(gulp.dest('build/'))
});
【讨论】:
gulp-header 包可用于为带有标题横幅的文件添加前缀。
例如。这将在您的 javascript 文件的标题中注入一个横幅。
var header = require('gulp-header');
var pkg = require('./package.json');
var banner = ['/**',
' * <%= pkg.name %> - <%= pkg.description %>',
' * @version v<%= pkg.version %>',
' * @link <%= pkg.homepage %>',
' * @license <%= pkg.license %>',
' */',
''].join('\n');
gulp.src('./foo/*.js')
.pipe(header(banner, { pkg: pkg } ))
.pipe(gulp.dest('./dist/')
Gulp 是一个利用管道的流式构建系统。
如果你只是想用任意字符串写一个新文件,你可以使用内置的node fs对象。
【讨论】:
使用string-to-stream 和vinyl-source-stream 模块:
var str = require('string-to-stream');
var source = require('vinyl-source-stream');
var gulp = require('gulp');
str('1.4.27').pipe(source('version.txt')).pipe(gulp.dest('dist'));
【讨论】:
这是一个适用于 2019 年的答案。
插件:
var Vinyl = require('vinyl');
var through = require('through2');
var path = require('path');
// https://github.com/gulpjs/gulp/tree/master/docs/writing-a-plugin#modifying-file-content
function stringSrc(filename, string) {
/**
* @this {Transform}
*/
var transform = function(file, encoding, callback) {
if (path.basename(file.relative) === 'package.json') {
file.contents = Buffer.from(
JSON.stringify({
name: 'modified-package',
version: '1.0.0',
}),
);
}
// if you want to create multiple files, use this.push and provide empty callback() call instead
// this.push(file);
// callback();
callback(null, file);
};
return through.obj(transform);
}
在你的 gulp 管道中:
gulp.src([
...
])
.pipe(stringSrc('version.json', '123'))
.pipe(gulp.dest(destinationPath))
来源:https://github.com/gulpjs/gulp/tree/master/docs/writing-a-plugin#modifying-file-content
你通过.obj() 传递的函数参数是一个_transform 将对输入文件进行操作的函数。您还可以提供一个 如果您需要在 流的结尾。
在您的转换函数中调用 this.push(file) 0 或更多 传递转换/克隆文件的时间。你不需要打电话 this.push(file) 如果你向 callback() 函数提供所有输出。
仅在当前文件(流/缓冲区)时调用回调函数 完全消耗。如果遇到错误,将其作为 回调的第一个参数,否则将其设置为 null。如果你有 将所有输出数据传递给 this.push() 你可以省略第二个参数 到回调。
一般来说,gulp 插件会更新 file.contents 然后选择 要么:
调用 callback(null, file) 或调用 this.push(file)
【讨论】:
这也可以使用gulp-tap来实现
如果您确定了多个需要此标头的文件,这将特别有用。这是相关代码(也来自 gulp-tap 文档)
var gulp = require('gulp'),
tap = require('gulp-tap');
gulp.src("src/**")
.pipe(tap(function(file){
file.contents = Buffer.concat([
new Buffer('Some Version Header', 'utf8'),
file.contents
]);
}))
.pipe(gulp.dest('dist');
【讨论】: