Gulp를 사용한 Concat 스크립트


192

예를 들어 Backbone 또는 기타 프로젝트에서 프로젝트를 빌드 중이고 특정 순서로 스크립트를로드해야합니다 (예 : underscore.js이전에로드해야 함) backbone.js.

순서대로 스크립트를 연결하려면 어떻게해야합니까?

// 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/'));
});

내에서 올바른 스크립트 순서가 source/index.html있지만 파일이 알파벳 순서로 구성되어 있기 때문에 gulp는 underscore.js이후 backbone.js에 연결 되며 내 스크립트의 순서는 source/index.html중요하지 않으므로 디렉토리의 파일을 찾습니다.

누구든지 이것에 대한 아이디어가 있습니까?

내가 가진 최고의 아이디어와 공급 업체 스크립트의 이름을 변경하는 것입니다 1, 2, 3그들에게 적절한 순서를 제공하지만,이 같은 내가 있는지 확실하지 않다.

더 많은 것을 알았을 때 Browserify가 훌륭한 솔루션이라는 것을 알았습니다. 처음에는 고통이 될 수 있지만 훌륭합니다.


4
현재 browserify를 사용하고 있다고 언급 할 수 있습니다. 그것은 작은 학습 곡선 IMO를 가지고 있습니다. 나는 처음에 어려움을 겪었지만 gulp browserify는 멋진 방법입니다! 코드를 모듈화 할 수 있습니다! shim에서 주문을 처리하므로 browserify를 사용할 때 연결하지 않아도됩니다.
Michael Joseph Aubry

솔루션 또는 링크에 대한 자세한 정보를 원하십니까?
Dmitri Zaitsev

kroltech.com/2013/12/… 여기에 훌륭한 프로젝트 관리를 시작하는 데 도움이되는 상용구 프로젝트 링크가 있습니다. 이 모든 것을 배우는 데 어려움을 겪은 후 프로젝트를 훨씬 잘 관리 할 수 ​​있습니다. 그는 github에 프로젝트가 있으며 browserify를 어떻게 사용하는지 볼 수 있습니다. 유튜브는 항상 도움이되고 소스 자체도 항상 과소 평가되었습니다 github.com/substack/node-browserify#usage
Michael Joseph Aubry

기본적으로 아이디어는 require프론트 엔드에서 구문과 같이 npm과 같은 구문을 사용할 수 있습니다. 물론 서버 측에서 npm을 사용한 경우 모듈이 필요한 방법을 볼 수 있지만 browserify를 사용하면 클라이언트 측 코드에서 수행 할 수 있습니다. 시작하려면 약간의 땜질이 필요하지만 주로 package.json 내부에 있으며 gulp.js 또는 grunt.js와 함께 사용하려는 경우에 중요합니다. gulp / grunt browserify 패키지를 설치하면 gulp/grunt browserify스크립트를 실행 하여 하나의 기본 스크립트로 만들 수 있습니다 . 약간의 학습 곡선이지만 IMO의 가치가 있습니다.
Michael Joseph Aubry

감사! 사실은 내가 훌륭한 문서를 건너 왔어요 medium.com/@dickeyxxx/... 당신이 정말로 필요로하지 않는 것이 좋은 점하기 browserify위한 Angular간단한 연결 작업 및 순서 : 중요하지 않습니다 모듈
드미트리 Zaitsev

답변:


199

AngularJS 앱을 만들 때 최근 Grunt와 비슷한 문제가 발생했습니다. 여기 질문 내가 게시는.

내가 한 일은 grunt 설정에서 파일을 명시 적으로 나열하는 것입니다. 구성 파일은 다음과 같습니다.

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

그런트는 어떤 파일이 중복되어 있는지 파악하고 포함하지 않을 수 있습니다. Gulp에서도 동일한 기술을 사용할 수 있습니다.


74
그런데 이것은 꿀꺽 꿀꺽에서도 잘 작동합니다. Gulp는 파일을 반복하지 않습니다.
OverZealous

1
멋진 사람들,이 두 걸작은 굉장합니다. 방금 마지막으로 gulp.js 파일을 설정하여 원하는 방식으로 작동하고 일부 HTML로 작성하고 파일을 저장 한 다음 버튼 하나만 누르면 최상의 프레임 워크와 모범 사례로 구축 된 사이트를 만들었습니다. 필요한 업데이트를 사용하지 않으면 업데이트도 쉬워집니다!
Michael Joseph Aubry

1
예! 최근 Grunt를 사용하기 시작했으며 정말 좋습니다. 백엔드 프레임 워크에 더 이상 JavaScript 애플리케이션을 임베드하지 않습니다.
채드 존슨

3
Gulp는 내 시도에서 파일을 복제하고 있었지만 gulp와 파일 시스템의 경우가 다르다는 것을 깨달았습니다. 정확한 경우 gulp는 파일을 복제하지 않습니다.
Chris

2
수동 주문은 심각한 프로젝트에서 악몽입니다. angularjs 및 기타를위한 특수 파일 분류 기가 있습니다.
zhekaus

135

한 덩어리의 파일 뒤에 오는 파일이 필요한 경우 도움이되는 또 다른 것은 다음 과 같이 글로브에서 특정 파일을 제외시키는 것입니다.

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

이것을 Chad Johnson의 답변에 설명 된대로 가장 먼저 필요한 파일을 지정하는 것과 결합 할 수 있습니다.


아아 실제로 게시물을 더 일찍 보았고 코드를 주입하는 데 도움이 src되었고 build구문을 사용하는 것을 보았습니다. 왜 필요한지 정확히 알지 못했기 때문에 해당 부분이 지워졌습니다. 지금 의미가 있습니다.
Michael Joseph Aubry

오, 알았으니 여기 요점은 저를 때렸어요 다른 방법으로 사용해서는 안됩니다. ['./source/js/*.js', './source/js/**/underscore.js', './source/js/**/!(underscore)*.js']
Michael Joseph Aubry

예, 이것은 단지 추가 도움이되었습니다. 다른 모든 것이로드 된 후 핵심 응용 프로그램 코드가 필요하거나 원할 때 가장 유용합니다. !(foobar)미리 특정 파일을 포함시킨 경우이 파일 을 사용할 이유가 없습니다 ( ).
OverZealous

내 모듈 정의가 이름에 '대시 없음'이있는 파일에있는 AngularJS 응용 프로그램의 경우이 Gulp glob 패턴이 작동했습니다. ['src/app/**/!(*-)*.js', 'src/app/**/*.js']
Sam T

17

gulp-order 플러그인을 사용했지만 스택 오버플로 post gulp-order 노드 모듈에서 병합 된 스트림으로 볼 수 있듯이 항상 성공하지는 않습니다 . Gulp 문서를 탐색 할 때 스트림 연결 모듈을 발견했습니다.이 모듈은 순서대로 연결 순서를 지정하는 데 매우 효과적이었습니다. https://github.com/gulpjs/gulp/blob/master/docs/recipes/using-multiple-sources-in-one-task.md

내가 사용한 방법의 예는 다음과 같습니다.

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);
});

stream-series 도 참조하십시오 . 객체 모드를 지정할 필요가 없으며 꿀꺽 꿀꺽 주입과 함께 작동합니다. 내 대답을 참조하십시오.
Codebling

꿀꺽 꿀꺽 플러그인의 절반은 일관되게 작동하지 않는 것 같습니다 (지시 한 순서와 같이), 꿀꺽 꿀꺽의 건축 개념이 훌륭하기 때문에 울부 짖는 것은 부끄러운 일입니다. 기본 노드 모듈이 더 유용하다는 것을 알았습니다.이 솔루션에 감사드립니다! 잘 작동합니다!
지미 호파

1
streamqueue, event-stream은 나에게는 효과가 없었지만 merge2는 예상대로 작동했습니다. npmjs.com/package/merge2
Alexander Shutau 2016 년

12

gulp-useref를 사용하면 색인 파일에 선언 된 모든 스크립트를 선언 된 순서대로 연결할 수 있습니다.

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에서 다음과 같이 생성하려는 빌드 파일의 이름을 선언해야합니다.

<!-- 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>

빌드 디렉토리에는 vendor.js, test.js 및 main.js를 포함하는 main.min.js에 대한 참조가 있습니다.


2
이것은 완벽 해요! 나는 질서를 정의하는 데 필요한 대답을 싫어했습니다! 그거 알아? 순서는 HTML 파일에 있습니다. 완벽한 솔루션.
Ali Ok

6

정렬 스트림은 또한 가진 파일의 특정 순서를 보장하기 위해 사용될 수있다 gulp.src. backbone.js항상 처리 할 마지막 파일로 두는 샘플 코드 :

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/'));
});

이 모듈이 가장 간단한 답변 인 것처럼 보이기 때문에이 모듈이 작동하기를 원하지만 필자의 경우 파일 이름을 매기고 매우 간단한 비교 함수를 사용하는 경우 작동하지 않습니다.
Jeremy John

5

파일 이름의 시작 부분에 숫자를 추가합니다.

0_normalize.scss
1_tikitaka.scss
main.scss

그것은 아무런 문제없이 꿀꺽 꿀꺽에서 작동합니다.


1
네, 이것이 조금 더 쉽다는 것을 알았습니다. 제작을 위해 모든 파일을 컴파일하는 경우 개발중인 파일의 이름을 바꾸지 않습니다.
Michael Joseph Aubry

2
방금 이것이 올바르게 작동하지 않는다는 것을 알았습니다. 1_xx, 2_xx, 10_xx, 11_xx를 사용해보십시오. Windows에서는 최소한 1_xx, 10_xx, 11_xx, 2_xx입니다
dbinott

17
개인적으로 나는 개발에서 파일 이름을 지정하는 것이 중요하지 않다는 진술에 완전히 동의하지 않습니다. 모든 개발은 컴퓨터 중심이 아닌 인간 중심적이어야합니다. 빌드 도구와 일치하도록 파일을 변경하면 빌드 도구의 목적이 무효화됩니다. 다른 방법이 아니라 프로젝트와 일치하도록 빌드를 변경하십시오.
Jon Hieb

2
@JonHieb 어떤 방식으로 파일 앞에 숫자를 붙이면 다음 개발자가 각 파일의 종속성을 알 수있게 도와줍니다. 폴더를 열고 1_foo.js, 2_bar.js, 3_baz.js를 보면 해당 파일을 순서대로 열고 1_foo.js에서 코드 읽기 시작을 읽습니다.
sqram

gulp.src가 비동기로 실행된다는 것을 알았습니다. 즉, dir에서 처리 할 파일이 더 많은 경우에는 일관되게 작동하지 않습니다.
Jeremy John

5

bower에서 가져온 각 패키지마다 스크립트를 다른 폴더에 구성하고 내 앱을위한 스크립트도 있습니다. 이 스크립트의 순서를 어딘가에 나열 할 것이므로 왜 gulp 파일에 나열하지 않습니까? 프로젝트의 새로운 개발자의 경우 모든 스크립트 엔드 포인트가 여기에 나열되어있는 것이 좋습니다. gulp-add-src로 이것을 할 수 있습니다 :

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']);

참고 : jQuery 및 Bootstrap은 데모 목적으로 추가되었습니다. CDN은 널리 사용되며 브라우저는 이미 다른 사이트에서 캐시 할 수 있기 때문에 CDN을 사용하는 것이 좋습니다.


3

stream-series을 사용해보십시오 . 인터리빙 대신 끝에 추가한다는 점을 제외하면 merge-stream / event-stream.merge () 와 같이 작동합니다 . streamqueue 와 같은 객체 모드를 지정할 필요가 없으므로 코드가 더 깨끗합니다.

var series = require('stream-series');

gulp.task('minifyInOrder', function() {
    return series(gulp.src('vendor/*'),gulp.src('extra'),gulp.src('house/*'))
        .pipe(concat('a.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dest'))
});

2

merge2 는 현재 작동하고 유지 관리되는 유일한 스트림 병합 도구처럼 보입니다.

2020 업데이트

API는 항상 변경되고 일부 라이브러리는 사용할 수 없게되거나 취약점을 포함하거나 해당 종속성이 취약점을 포함하며 수년간 수정되지 않았습니다. 텍스트 파일 조작을 위해 당신은 더 나은 사용하는 사용자 정의 NodeJS 스크립트와 같은 인기있는 라이브러리 거라고 globbyfs-extra기타 래퍼 꿀꺽, 그런트없이 다른 라이브러리와 함께합니다.

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

다른 방법은이 문제를 위해 특별히 만든 Gulp 플러그인을 사용하는 것입니다. https://www.npmjs.com/package/gulp-ng-module-sort

다음 .pipe(ngModuleSort())과 같이 추가하여 스크립트를 정렬 할 수 있습니다 .

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/));
});

다음의 디렉토리 규칙을 가정합니다.

|——— 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

도움이 되었기를 바랍니다!


1

나를 위해 파일을 재정렬하는 파이프에 natualSort () 및 angularFileSort ()가있었습니다. 나는 그것을 제거하고 이제는 잘 작동합니다.

$.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

난 그냥 gulp-angular-filesort를 사용합니다

function concatOrder() {

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

죄송합니다, 난 당신이 각도에 대해 묻지 않았다는 것을 깨달았습니다. 죄송합니다
Maccurt

0

나는 모두 gulp를 사용하는 코어 의존적 인 모듈 환경에 있습니다. 따라서 core다른 모듈보다 먼저 모듈을 추가해야합니다.

제가 한:

  1. 모든 스크립트를 src폴더로 이동
  2. 그냥 gulp-rename당신 core에 디렉토리_core
  3. gulp은의 순서를 유지하고 gulp.src있으며 내 concat src은 다음과 같습니다.

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

분명히 _목록에서 첫 번째 디렉토리로 사용됩니다 (자연 정렬?).

참고 (angularjs) : 그런 다음 gulp -angular-extender 를 사용 하여 모듈을 모듈에 동적으로 추가합니다 core. 다음과 같이 컴파일되었습니다.

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

여기서 Admin과 Products는 두 개의 모듈입니다.


0

써드 파티 라이브러리 종속성을 주문하려면 wiredep을 시도 하십시오 . 이 패키지는 기본적으로 bower.json의 각 패키지 종속성을 확인한 다음 연결합니다.


0

이 페이지에서 여러 솔루션을 시도했지만 아무것도 작동하지 않았습니다. 알파벳순으로 폴더 이름을 정렬하기 위해 일련의 번호가 매겨진 파일이 있었으므로 파이프로 연결할 때 concat()동일한 순서로 정렬됩니다. 즉, 글 로빙 입력의 순서를 유지하십시오. 쉬워요?

구체적인 개념 증명 코드 print는 다음과 같습니다 ( 주문을 진료소에 인쇄하는 것입니다).

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());
});

광기의 이유는 gulp.src무엇입니까? 그 결정 gulp.srcI가 이용할 수있을 때 비동기 실행되었다 sleep()(a 이용한 함수 .map적절히 스트림 출력을 주문 인덱스 증분 휴면 함께 참조).

src더 많은 파일이 포함 된 평균 dirs 의 비동기 결과는 처리하는 데 시간이 오래 걸리기 때문에 더 적은 파일이있는 dirs를 따릅니다.


1
동기식 (적어도 결정 론적 인) 대안을 찾았습니까?
ELLIOTTCABLE

0

내 gulp 설정에서 공급 업체 파일을 먼저 지정한 다음 (일반적인) 모든 것을 지정합니다. 그리고 벤더 js를 다른 사용자 정의 항목보다 먼저 배치합니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.