Gulp ile concat komut dosyaları


192

Örneğin, Omurga veya başka bir şey üzerinde bir proje oluşturduğunuzu ve komut dosyalarını belirli bir sırayla yüklemeniz gerekiyor, örneğin underscore.jsdaha önce yüklenmesi gerekiyor backbone.js.

Senaryoları sıraya koyacak şekilde birleştirmeyi nasıl başarabilirim?

// JS concat, strip debugging and minify
gulp.task('scripts', function() {
    gulp.src(['./source/js/*.js', './source/js/**/*.js'])
    .pipe(concat('script.js'))
    .pipe(stripDebug())
    .pipe(uglify())
    .pipe(gulp.dest('./build/js/'));
});

Benim doğru komut dizisi var source/index.html, ama dosyalar alfabetik sıraya göre organize olduğundan, gulp underscore.jssonra concat olacak backbone.jsve benim içinde komut dizisi source/index.htmlönemli değil, dizindeki dosyalara bakar.

Peki bu konuda bir fikri olan var mı?

Ben iyi bir fikir ile satıcı komut dosyalarını yeniden adlandırmak için 1, 2, 3onlara doğru sipariş vermek için, ama böyle ben olmadığından emin değilim.

Daha fazla öğrendiğim gibi Browserify'nin harika bir çözüm olduğunu gördüm, ilk başta acı olabilir ama harika.


4
Bugünlerde browserify kullandığımı söyleyebilirim. Kendi küçük öğrenme eğrisi IMO'su var. İlk başta mücadele ettim ama gulp browserify gitmek için harika bir yol! Kodunuzun modüler olmasına izin vermek! Siparişi bir şim içinde ele alırsınız, bu nedenle browserify kullanılırken birleştirme gerekmez.
Michael Joseph Aubry

Çözümünüz veya bağlantınız için daha fazla ayrıntı vermek ister misiniz?
Dmitri Zaitsev

kroltech.com/2013/12/… burada iyi bir proje yönetimine başlamama yardımcı olan bir kazan plakası projesine bir link var. Tüm bunları öğrendikten sonra projelerimi daha iyi yönetebilirim. Github projesi var ve nasıl browserify kullandığını görebilirsiniz. Youtube her zaman yardımcı olur ve elbette kaynağın kendisi her zaman hafife alınır github.com/substack/node-browserify#usage
Michael Joseph Aubry

Temel olarak fikir, requireön uçta npm gibi sözdizimi kullanabilmektir , çünkü sunucu tarafında npm kullandıysanız, modüllere nasıl ihtiyaç duyabileceğinizi görürsünüz, ancak browserify bunu istemci tarafı kodunda yapmanızı sağlar, Başlamak için biraz titreme gerektirir, ancak çoğunlukla paketin içinde. json ve gulp.js veya grunt.js ile kullanmak istiyorsanız. Eğer gulp / grunt browserify paketini kurarsanız gulp/grunt browserify, betiğinizi tek bir ana betiğe dönüştürebilirsiniz, bu hafif bir öğrenme eğrisidir, ancak IMO'ya değer.
Michael Joseph Aubry

Teşekkürler! Aslında harika bir makale ile karşılaştım medium.com/@dickeyxxx/… , basit birleştirme ve siparişin önemli olmadığı modüller browserifyiçin gerçekten ihtiyacınız olmadığına dair iyi bir noktaya değindimAngular :)
Dmitri Zaitsev

Yanıtlar:


199

AngularJS uygulamamı oluştururken son zamanlarda Grunt ile benzer bir sorun yaşadım. İşte gönderdiğim bir soru .

Ne yaptığım açıkça grunt yapılandırma sırasıyla dosyaları listelemektir. Yapılandırma dosyası şu şekilde görünecektir:

[
  '/path/to/app.js',
  '/path/to/mymodule/mymodule.js',
  '/path/to/mymodule/mymodule/*.js'
]

Grunt, hangi dosyaların kopya olduğunu ve bunları içermediğini anlayabilir. Aynı teknik Gulp ile de çalışacaktır.


74
Bu arada, yudum altında da işe yarıyor. Gulp dosyaları da tekrarlamaz.
OverZealous

1
Harika çocuklar, bu iki şaheser harika. Sonunda gulp.js dosyamı istediğim şekilde çalışacak şekilde ayarladım, bazı html'de yazdım, dosyayı kaydettim ve bir düğmeye dokunarak en iyi çerçeveler ve iyi uygulamalarla oluşturulmuş bir siteyi patlattım. Artı güncellemeler kolay olacak, ihtiyacınız olanlardan birini kullanmıyorsanız!
Michael Joseph Aubry

1
Evet! Son zamanlarda Grunt kullanmaya başladım ve harika. Artık JavaScript uygulamalarını arka uç çerçevelerine gömmek yok.
Chad Johnson

3
Gulp denememde dosyaları kopyalıyordu, ama gulp dosya sistemine karşı farklı bir dava olduğunu fark ettim, bu yüzden dikkat et! Tam olarak, gulp dosyaları kopyalamaz.
Chris

2
Manuel sipariş ciddi bir projenin kabusu. Özel dosya sıralayıcıları vardır - angularjs ve diğerleri için.
zhekaus

135

Bir dosya bloğundan sonra gelmek için bazı dosyalara ihtiyacınız varsa yardımcı olan başka bir şey, belirli dosyaları globunuzdan hariç tutmaktır.

[
  '/src/**/!(foobar)*.js', // all files that end in .js EXCEPT foobar*.js
  '/src/js/foobar.js',
]

Bunu Chad Johnson'ın cevabında açıklandığı gibi önce gelmesi gereken dosyalar belirleyerek birleştirebilirsiniz.


Ah Aslında daha erken görmüşse ve bu benim için kod enjekte bana yardımcı oldu srcve benim için buildben emin tam olmadığım için gerekli neden o bölümü silme sona erdi şimdi mantıklı, yani sözdizimi kullanılarak gördüm I.
Michael Joseph Aubry

Oh tamam yani buradaki amacın bana vurdu, foobar.js'yi kalıcı kılmaz mı? Etrafında başka bir yol olmamalı. ['./source/js/*.js', './source/js/**/underscore.js', './source/js/**/!(underscore)*.js']
Michael Joseph Aubry

Evet, bu daha fazla yardımcı oldu. Her şey yüklendikten sonra temel uygulama kodunuza ihtiyacınız olduğunda veya gelmesini istediğinizde en kullanışlıdır. !(foobar)Önceden belirli bir dosyayı eklediyseniz ( ) kullanmanız için hiçbir neden yoktur .
OverZealous

Modül tanımlarımın adında 'tire' bulunmayan dosyalarda bulunduğu AngularJS uygulaması için bu Gulp glob kalıbı çalıştı; ['src/app/**/!(*-)*.js', 'src/app/**/*.js']
Sam T

17

Ben gulp sipariş eklentisi kullandım ama birleştirilmiş akışları ile yığın taşma sonrası gulp sipariş düğüm modülü görebileceğiniz gibi her zaman başarılı değildir . Gulp belgelerine göz atarken, benim durumumda birleştirme sırasını belirlemek için oldukça iyi çalışmış olan streamque modülüne rastladım. https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md

Nasıl kullandığımın örneği aşağıda

var gulp         = require('gulp');
var concat       = require('gulp-concat');
var handleErrors = require('../util/handleErrors');
var streamqueue  = require('streamqueue');

gulp.task('scripts', function() {
    return streamqueue({ objectMode: true },
        gulp.src('./public/angular/config/*.js'),
        gulp.src('./public/angular/services/**/*.js'),
        gulp.src('./public/angular/modules/**/*.js'),
        gulp.src('./public/angular/primitives/**/*.js'),
        gulp.src('./public/js/**/*.js')
    )
        .pipe(concat('app.js'))
        .pipe(gulp.dest('./public/build/js'))
        .on('error', handleErrors);
});

Ayrıca bkz . Yayın serileri . Nesne modunu belirtmenizi gerektirmez ve gulp-inject ile çalışır. Cevabımı gör.
Kodlama

yudum eklentilerinin yarısı tutarlı bir şekilde çalışmıyor (işaret ettiğiniz gibi sipariş), bu ağlayan bir utanç çünkü muhteşem mimari mimari konsepti muhteşem, sadece birçok insan eklentilerini kötü bir şekilde uyguluyor ve koruyor ... Altta yatan düğüm modüllerinin daha yararlı olduğunu düşünüyorum, bu yüzden bu çözüm için teşekkür ederim! Harika çalışıyor!
Jimmy Hoffa

1
streamqueue, event-stream benim için çalışmadı, ancak merge2 beklendiği gibi çalıştı npmjs.com/package/merge2
Alexander Shutau

12

Gulp-useref ile dizin dosyanızda bildirilen her komut dosyasını, bildirdiğiniz sırayla birleştirebilirsiniz.

https://www.npmjs.com/package/gulp-useref

var $ = require('gulp-load-plugins')();
gulp.task('jsbuild', function () {
  var assets = $.useref.assets({searchPath: '{.tmp,app}'});
  return gulp.src('app/**/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});

HTML'de, oluşturmak istediğiniz derleme dosyasının adını şu şekilde bildirmeniz gerekir:

<!-- build:js js/main.min.js -->
    <script src="js/vendor/vendor.js"></script>
    <script src="js/modules/test.js"></script>
    <script src="js/main.js"></script>

Derleme dizininizde vendor.js, test.js ve main.js dosyasını içeren main.min.js referansına sahip olacaksınız.


2
Bu harika! Düzeni tanımlamak için gereken cevaplardan nefret ettim! Biliyor musun? Sıra: HTML dosyasında. Mükemmel çözüm.
Ali Ok

6

Sort-akışı da sahip dosyaların belirli düzen sağlamak için kullanılabilir gulp.src. backbone.jsHer zaman işlenecek son dosya olarak yerleştiren örnek kod :

var gulp = require('gulp');
var sort = require('sort-stream');
gulp.task('scripts', function() {
gulp.src(['./source/js/*.js', './source/js/**/*.js'])
  .pipe(sort(function(a, b){
    aScore = a.path.match(/backbone.js$/) ? 1 : 0;
    bScore = b.path.match(/backbone.js$/) ? 1 : 0;
    return aScore - bScore;
  }))
  .pipe(concat('script.js'))
  .pipe(stripDebug())
  .pipe(uglify())
  .pipe(gulp.dest('./build/js/'));
});

Keşke bu modülün çalışmasını isterdim çünkü benim için en basit cevap gibi görünüyor, ancak benim durumumda, dosya adlarını ve çok basit bir karşılaştırma işlevini sayılıyorum, bu işe yaramıyor.
Jeremy John

5

Sadece dosya adının başına rakamlar ekliyorum:

0_normalize.scss
1_tikitaka.scss
main.scss

Sorunsuz bir şekilde yırtıcı olarak çalışır.


1
Evet, bunu biraz daha kolay buluyorum, yani tüm dosyalarınızı üretim için derliyorsanız, geliştirme sırasında dosyalarınızı adlandırdığınız şey fark etmez.
Michael Joseph Aubry

2
Az önce bunun doğru çalışmadığını öğrendim. 1_xx, 2_xx, 10_xx, 11_xx kullanmayı deneyin. En azından Windows altında, 1_xx, 10_xx, 11_xx, 2_xx olacak
dbinott

17
Şahsen, dosyalarınızı geliştirme aşamasında ne adlandırdığınızın önemli olmadığı ifadesine tamamen katılmıyorum. Tüm gelişim bilgisayar odaklı değil, önce insan odaklı olmalıdır. Dosyalarınızı derleme aracınızla eşleşecek şekilde değiştirmek derleme aracının amacını bozar. Yapınızı projenizle eşleşecek şekilde değiştirin, tersi yönde değil.
Jon Hieb

2
@JonHieb Bir şekilde, dosyalarınızı bir sayı ile ön ek yapmak, bir sonraki geliştiricinin her dosyanın bağımlılıklarını bilmesine yardımcı olur, değil mi? Bir klasörü açar ve 1_foo.js, 2_bar.js, 3_baz.js'yi görürsem, bu dosyaları bu sırayla açacağım ve 1_foo.js adresindeki kodu okumaya başlayacağım
sqram

Ben gulp.src zaman uyumsuz çalışır, yani bir dir işlemek için daha fazla dosya olduğu durumlarda bu sürekli çalışmadığı anlamına bulduk.
Jeremy John

5

Senaryolarımı bower'dan aldığım her paket için farklı klasörlerde organize ettim, ayrıca uygulamam için kendi script'im Bu betiklerin sırasını bir yerde listeleyeceğiniz için, neden sadece gulp dosyanızda listelemiyorsunuz? Projenizdeki yeni geliştiriciler için, tüm komut dosyası uç noktalarınızın burada listelenmesi güzel. Bunu gulp-add-src ile yapabilirsiniz :

gulpfile.js

var gulp = require('gulp'),
    less = require('gulp-less'),
    minifyCSS = require('gulp-minify-css'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    addsrc = require('gulp-add-src'),
    sourcemaps = require('gulp-sourcemaps');

// CSS & Less
gulp.task('css', function(){
    gulp.src('less/all.less')
        .pipe(sourcemaps.init())
        .pipe(less())
        .pipe(minifyCSS())
        .pipe(sourcemaps.write('source-maps'))
        .pipe(gulp.dest('public/css'));
});

// JS
gulp.task('js', function() {
    gulp.src('resources/assets/bower/jquery/dist/jquery.js')
    .pipe(addsrc.append('resources/assets/bower/bootstrap/dist/js/bootstrap.js'))
    .pipe(addsrc.append('resources/assets/bower/blahblah/dist/js/blah.js'))
    .pipe(addsrc.append('resources/assets/js/my-script.js'))
    .pipe(sourcemaps.init())
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write('source-maps'))
    .pipe(gulp.dest('public/js'));
});

gulp.task('default',['css','js']);

Not: Siparişin gösterilmesi amacıyla jQuery ve Bootstrap eklendi. Çok yaygın olarak kullanıldıkları ve tarayıcıların bunları zaten diğer sitelerden önbelleğe alabildikleri için CDN'leri kullanmak muhtemelen daha iyidir.



2

merge2 şu anda çalışan ve bakımı yapılmış tek düzenli akış birleştirme aracı gibi görünüyor.

2020 Güncellemesi

API'ler her zaman değişiyor, bazı kütüphaneler kullanılamıyor veya güvenlik açıkları içeriyor veya bağımlılıkları yıllarca düzeltilmeyen güvenlik açıkları içeriyor. Metin dosyaları manipülasyonları için, özel NodeJS komut dosyalarını ve Gulp, Grunt vb. Sarmalayıcıları olmayan diğer kitaplıklar gibi globbyve bunlarla fs-extrabirlikte popüler kitaplıkları kullanmanız daha iyi olur .

import globby from 'globby';
import fs from 'fs-extra';

async function bundleScripts() {
    const rootPaths = await globby('./source/js/*.js');
    const otherPaths = (await globby('./source/**/*.js'))
        .filter(f => !rootFiles.includes(f));
    const paths = rootPaths.concat(otherPaths);

    const files = Promise.all(
        paths.map(
            // Returns a Promise
            path => fs.readFile(path, {encoding: 'utf8'})
        )
    );

    let bundle = files.join('\n');
    bundle = uglify(bundle);
    bundle = whatever(bundle);
    bundle = bundle.replace(/\/\*.*?\*\//g, '');

    await fs.outputFile('./build/js/script.js', bundle, {encoding: 'utf8'});
}

bundleScripts.then(() => console.log('done');

1

Alternatif bir yöntem, bu sorun için özel olarak oluşturulan bir Gulp eklentisi kullanmaktır. https://www.npmjs.com/package/gulp-ng-module-sort

Komut dosyalarınızı aşağıdaki .pipe(ngModuleSort())gibi bir ekleyerek sıralamanızı sağlar :

var ngModuleSort = require('gulp-ng-module-sort');
var concat = require('gulp-concat');

gulp.task('angular-scripts', function() {
    return gulp.src('./src/app/**/*.js')
        .pipe(ngModuleSort())
        .pipe(concat('angularAppScripts.js))
        .pipe(gulp.dest('./dist/));
});

Bir dizin kuralını varsayarsak:

|——— src/
|   |——— app/
|       |——— module1/
|           |——— sub-module1/
|               |——— sub-module1.js
|           |——— module1.js
|       |——— module2/
|           |——— sub-module2/
|               |——— sub-module2.js
|           |——— sub-module3/
|               |——— sub-module3.js
|           |——— module2.js
|   |——— app.js

Bu yardımcı olur umarım!


1

Benim için borularda dosyaları yeniden sıralayan natualSort () ve angularFileSort () vardı. Kaldırdım ve şimdi benim için iyi çalışıyor

$.inject( // app/**/*.js files
    gulp.src(paths.jsFiles)
      .pipe($.plumber()), // use plumber so watch can start despite js errors
      //.pipe($.naturalSort())
      //.pipe($.angularFilesort()),
    {relative: true}))

1

Ben sadece gulp-açısal-filesort

function concatOrder() {

    return gulp.src('./build/src/app/**/*.js')
        .pipe(sort())
        .pipe(plug.concat('concat.js'))
        .pipe(gulp.dest('./output/'));
}

ayy, açısal, üzgünüm sormadığını fark ettim
Maccurt

0

Ben tüm yudum kullanarak çekirdek bağımlıları olan bir modül ortamında. Bu nedenle, coremodülün diğerlerinden önce eklenmesi gerekir.

Ben ne yaptım:

  1. Tüm komut dosyalarını bir srcklasöre taşıma
  2. Sadece gulp-renamesenin coredizin_core
  3. yutmak senin sırasını gulp.srckoruyor, benim concat srcşöyle görünür:

    concat: ['./client/src/js/*.js', './client/src/js/**/*.js', './client/src/js/**/**/*.js']

Açıkça _listeden ilk dizin olarak alacaktır (doğal sıralama?).

Not (angularjs): Modülleri modüle dinamik olarak eklemek için gulp -angular-extender kullanıyorum core. Derlenmiş gibi görünüyor:

angular.module('Core', ["ui.router","mm.foundation",(...),"Admin","Products"])

Yönetici ve Ürünler iki modüldür.


0

üçüncü taraf kitaplık bağımlılıkları sipariş etmek istiyorsanız, wiredep'i deneyin . Bu paket temel olarak bower.json'daki her paket bağımlılığını kontrol eder ve sonra bunları sizin için kablolar.


0

Bu sayfadan birkaç çözüm denedim, ancak hiçbiri işe yaramadı. Alfabetik katlama adı ile sipariş edilmesini istediğim bir dizi numaralı dosyam vardı, bu yüzden concat()aynı sırada sıralanırlardı. Yani, globbing girdisinin sırasını koruyun. Kolay değil mi?

İşte benim özel kavram kanıtı kodum ( printsadece klibe yazdırılan sırayı görmek için):

var order = require('gulp-order');
var gulp = require('gulp');
var print = require('gulp-print').default;

var options = {};

options.rootPath = {
  inputDir: process.env.INIT_CWD + '/Draft',
  inputGlob: '/**/*.md',
};

gulp.task('default', function(){
  gulp.src(options.rootPath.inputDir + options.rootPath.inputGlob, {base: '.'})
    .pipe(order([options.rootPath.inputDir + options.rootPath.inputGlob]))
    .pipe(print());
});

Deliliğin sebebi gulp.src? Akış çıktısını düzgün bir şekilde sipariş gulp.srcetmek için bir sleep()işlevi ( .mapindeks tarafından artırılan bir uyku zamanı kullanarak) kullanabildiğimde zaman uyumsuz çalıştığını belirledim .

Arasında zaman uyumsuz ortaya attığı, srcİşlenmesi uzun sürdü çünkü daha dosyalarla ortalama dirs, daha az dosyalarla dirs sonra geldi.


1
Eşzamanlı (en azından deterministik) bir alternatif buldunuz mu?
ELLIOTTCABLE

0

Benim yutturmaca kurulumda, önce satıcı dosyalarını ve sonra (daha genel) her şeyi, ikinci olarak belirtiyorum. Ve başarıyla satıcı js diğer özel şeylerden önce koyar.

gulp.src([
  // vendor folder first
  path.join(folder, '/vendor/**/*.js'),
  // custom js after vendor
  path.join(folder, '/**/*.js')
])    

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.