2014-01-14 5 views
2

저는 Grunt에 익숙하지 않습니다. 재귀 템플릿에 몇 가지 문제가 있습니다. Gruntfile.js로, npm install grunt를 실행 한 다음 grunt print_build_dir을 실행그란트 : 재귀 템플릿은 어떻게 작동합니까?

var path = require('path'); 

module.exports = function(grunt) { 
    grunt.initConfig({ 
    // Stash path here so we can reference it from templates. 
    path: path, 
    argPrint: function(arg1, arg2) { return "arg1: " + arg1 + " arg2: " + arg2; }, 
    build: { 
     root_dir: __dirname, 
     build_dir: '<%= path.resolve(build.root_dir, "dev") %>', 
     vendor_dir: '<%= path.resolve(build.build_dir, "vendor") %>', 
     classes_dir: '<%= path.resolve(build.vendor_dir, "classes") %>', 
     test: '<%= argPrint(build.build_dir, "vendor") %>' 
    } 
    }); 

    grunt.registerTask('print_build_dir', 'Prints the build directory.', function() { 
    grunt.log.writeln(grunt.config("build.root_dir")); 
    grunt.log.writeln(grunt.config("build.build_dir")); 
    grunt.log.writeln(grunt.config("build.vendor_dir")); 
    grunt.log.writeln(grunt.config("build.classes_dir")); 
    grunt.log.writeln(grunt.config("build.test")); 
    }); 
}; 

팝 : 다음은 콘크리트, 최소한의 예입니다.

당신이 /Users/jvilk/Code/grunt-test에 있다면, 나는 출력이 될 것 기대하는 대신

$ grunt print_build_dir 
/Users/jvilk/Code/grunt-test 
/Users/jvilk/Code/grunt-test/dev 
/Users/jvilk/Code/grunt-test/dev/vendor 
/Users/jvilk/Code/grunt-test/dev/vendor/classes 
arg1: /Users/jvilk/Code/grunt-test/dev arg2: vendor 

을, 출력은 다음과 같습니다

$ grunt print_build_dir 
/Users/jvilk/Code/grunt-test 
/Users/jvilk/Code/grunt-test/dev 
/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/dev/vendor 
/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/dev/vendor/classes 
arg1: /Users/jvilk/Code/grunt-test/dev arg2: vendor 

여기 무슨 일이야? test 구성 속성에서 vendor_dir 속성에 대한 올바른 인수를 path.resolve에 수신해야합니다. 즉, path.resolve("/Users/jvilk/Code/grunt-test/dev", "vendor")으로 해결되지만, 왜 여분의 슬래시를 사용하여 build.root_dir의 값을 prepending하는지 완전히 혼란 스럽습니다. 재산.

어떤 도움이나 지침도 저와 고투의 두분 모두에게 크게 감사 할 것입니다. Gruntfile. 감사!

EDIT : 선제 적 부록으로서,이 특별한 예제를 실현하기 위해 템플릿을 사용할 필요가 없음을 알고 있습니다. path.resolve을 직접 사용할 수 있습니다. 그러나 예를 들어 Gruntfile이 아닌 경우 path.resolve에있는 디렉터리 이름 중 하나는 동적으로 설정된 속성이므로 템플릿을 사용해야합니다. 그렇게하지

'<%= argPrint(build.build_dir, "vendor") %>' -> 
    argPrint('<%= path.resolve(build.root_dir, "dev") %>', "vendor") -> 
    'arg1: <%= path.resolve(build.root_dir, "dev") %> arg2: vendor' -> 
     'arg1: /Users/jvilk/Code/grunt-test arg2: vendor' 

: 그것과 같이 확장으로

'<%= path.resolve(build.build_dir, "vendor") %>' -> 
    path.resolve('<%= path.resolve(build.root_dir, "dev") %>', "vendor") -> 
    '/Users/jvilk/Code/grunt-test/<%= path.resolve(build.root_dir, "dev") %>/vendor' -> 
     '/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/vendor' 

test 속성 일, 앤드류가 지적 하듯이, 템플릿 확장은 다음과 같은 방법으로 vendor_dir에서 작동 : EDIT2

왜 그들이이 디자인 결정을했는지 이해하지만, 나는 모든 문자열을 반복적으로 처리하는 함수에 이들을 모두 래핑하여 원하는 모든 템플릿을 에뮬레이트 할 수 있습니다. 모든 문자는 <%=이 없어 질 때까지 반복됩니다.

답변

2

첫째 날 시작하자 :이 런타임에 수동으로 CONFIGS을 확장를 제외하고 주위에 좋은 방법이 있는지 모르겠어요

__dirname => 
    '/Users/jvilk/Code/grunt-test' 

build.build_dir => 
    '<%= path.resolve(build.root_dir, "dev") %> => 
    __dirname + "dev" => 
     '/Users/jvilk/Code/grunt-test/dev' 

build.vendor_dir => 
    '<%= path.resolve(build.build_dir, "vendor") %>' => 
    '/Users/jvilk/Code/grunt-test/<%= path.resolve(build.root_dir, "dev") %>/vendor' => 
     '/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/dev/vendor' 

build.classes_dir => 
    '<%= path.resolve(build.vendor_dir, "classes") %>' => 
    '/Users/jvilk/Code/grunt-test/<%= path.resolve(build.build_dir, "vendor") %>'/classes' => 
     '/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/<%= path.resolve(build.root_dir, "dev") %>/vendor/classes' => 
     '/Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test//Users/jvilk/Code/grunt-test/dev/vendor/classes' 

: 그래서 상황에서 각 단계처럼 보인다 작동하는 샘플로

grunt.initConfig({ 
    path: path, 
    argPrint: function(arg1, arg2) { return "arg1: " + arg1 + " arg2: " + arg2; }, 
    resolvePath: function(from, to) { return path.resolve(grunt.config.process(from), to); }, 
    build: { 
     root_dir: __dirname, 
     build_dir: "<%= resolvePath(build.root_dir, 'dev')%>", 
     vendor_dir: "<%= resolvePath(build.build_dir, 'vendor') %>", 
     classes_dir: "<%= resolvePath(build.vendor_dir, 'classes') %>", 
     test: "<%= argPrint(build.build_dir, 'vendor') %>" 
    } 
    }); 

    grunt.registerTask('print_build_dir', 'Prints the build directory.', function() { 
    grunt.log.writeln(grunt.config.get("build.root_dir")); 
    grunt.log.writeln(grunt.config.get("build.build_dir")); 
    grunt.log.writeln(grunt.config.get("build.vendor_dir")); 
    grunt.log.writeln(grunt.config.get("build.classes_dir")); 
    grunt.log.writeln(grunt.config.get("build.test")); 
    }); 
}; 

이 당신이 기대하는 출력 :

/사용자/andrewtremblay/개발/꿀꿀 테스트

/사용자/andrewtremblay/개발/꿀꿀 테스트는/dev

/사용자/andrewtremblay/개발/grunt-test/dev/vendor/cl/012/devrew/개발/grunt-test/dev/vendor/

ARG1 당나귀 :/사용자/andrewtremblay/개발/꿀꿀 테스트/dev에 ARG2을 : 공급 업체 인되지 않은 값은 from에 전달되고 있던 내 ResolvePath 기능이을 테스트 할 때 내가 눈치 무엇

처리됨. 이 버그인지 아닌지 내가 아무 생각이 없다,하지만 난 대답은 path.resolve에게있다 생각하고 그것을 처리 가능한 변수를 전달하는 방법을 정의되지 않은 동작에 이르게

(대신 config.get('build.build_dir')의 출력을 사용하는이 config.getRaw('build.build_dir')의 결과를 사용했다) . (내 강조)

From the docs :

path.resolve([from ...], to)

to 절대 경로를 찾을 때까지 from 인수, 왼쪽 순서로 오른쪽 앞에 추가되어 이미 절대되지 않습니다. 의 경로를 모두 사용한 후에도 절대 경로가 없으면 현재 작업 디렉토리 도 사용됩니다. 결과 경로가 정규화되고 경로가 루트 디렉토리로 확인되지 않는 한 후행 슬래시가 제거됩니다.

그 이유는 (path.resolve이 config 개체를 처리하지 못했기 때문입니다) 작업 디렉토리가 계속 prepended 된 이유를 설명 할 수 있습니다.

+0

이것은 그 것이다. argPrint에 arg1의 디버그 프린트를 추가하고 원시 템플릿으로 호출되고 있음을 확인했습니다. 내 템플릿 모델링의 정신 모델이 잘못되었습니다. 나는 그것이 모든 설정 변수를 즉시 대체한다고 생각했지만 템플릿 대신 하나의 레벨을 처리하고이를 검증 한 다음 모든 템플릿을 완료 될 때까지 재귀 적으로 처리합니다. –

0

그런트가 getconfig에서 처리 할 때 템플릿 패턴을 찾으면 값을 처리합니다.

템플릿 패턴이없는 문자열을 찾을 때까지 템플릿을 처리하는 것처럼 보입니다.

grunt.config("build.build_dir", grunt.config("build.build_dir")) 
grunt.config("build.vendor_dir", grunt.config("build.vendor_dir")) 
grunt.config("build.classes_dir", grunt.config("build.classes_dir")) 
+0

이 템플릿 확장은 이해가되지 않습니다 ... vendor_dir과 test는 동일합니다 - 다른 함수를 호출합니다! '/ 사용자/jvilk/코드/꿀꿀 테스트/ARG1 :/사용자/jvilk/코드/꿀꿀 테스트/dev에 ARG2 : 는 확장이 양식은 test''에 대해 다음을 얻을 것 또한 vendor' , 외래 슬래시는 어디에서 오는가? 'root_dir'은'/ Users/jvilk/Code/grunt-test /'가 아닌'/ Users/jvilk/Code/grunt-test'입니다 ... 그 루트는 파일 경로처럼 보이기 때문에 이상한 basename 추출을하고 있습니다 ... ? 응답 해 주셔서 감사합니다. –

+1

argPrint의 차이점을 알지 못했습니다. 나는 앤드류의 대답이 그것을 설명한다고 생각한다. – doowb