我正在尝试使用 Grunt 作为我的 webapp 的构建工具。
我想至少有两个设置:
I. 开发设置 - 从单独的文件加载脚本,不连接,
所以我的 index.html 看起来像:
<!DOCTYPE html> <html> <head> <script src="js/module1.js" /> <script src="js/module2.js" /> <script src="js/module3.js" /> ... </head> <body></body> </html>
二、 生产设置- 将我的脚本压缩并连接到一个文件中,
相应地使用 index.html:
<!DOCTYPE html> <html> <head> <script src="js/MyApp-all.min.js" /> </head> <body></body> </html>
问题是, 我怎样才能让 grunt 使这些 index.html 取决于我运行时的grunt dev配置grunt prod?
grunt dev
grunt prod
或者,也许我正在朝错误的方向挖掘,并且总是更容易生成MyApp- all.min.js,但将我的所有脚本(连接)或从单独文件异步加载这些脚本的加载器脚本放入其中?
MyApp- all.min.js
你们是怎么做到的,伙计们?
我想出了我自己的解决方案。还没有完善,但我想我会朝那个方向前进。
从本质上讲,我正在使用grunt.template.process()从模板生成我index.html的模板,该模板分析当前配置并生成我的原始源文件列表或带有缩小代码的单个文件的链接。下面的示例适用于 js 文件,但同样的方法可以扩展到 css 和任何其他可能的文本文件。
index.html
grunt.js :
grunt.js
/*global module:false*/ module.exports = function(grunt) { var // js files jsFiles = [ 'src/module1.js', 'src/module2.js', 'src/module3.js', 'src/awesome.js' ]; // Import custom tasks (see index task below) grunt.loadTasks( "build/tasks" ); // Project configuration. grunt.initConfig({ pkg: '<json:package.json>', meta: { banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + '<%= grunt.template.today("yyyy-mm-dd") %> */' }, jsFiles: jsFiles, // file name for concatenated js concatJsFile: '<%= pkg.name %>-all.js', // file name for concatenated & minified js concatJsMinFile: '<%= pkg.name %>-all.min.js', concat: { dist: { src: ['<banner:meta.banner>'].concat(jsFiles), dest: 'dist/<%= concatJsFile %>' } }, min: { dist: { src: ['<banner:meta.banner>', '<config:concat.dist.dest>'], dest: 'dist/<%= concatJsMinFile %>' } }, lint: { files: ['grunt.js'].concat(jsFiles) }, // options for index.html builder task index: { src: 'index.tmpl', // source template file dest: 'index.html' // destination file (usually index.html) } }); // Development setup grunt.registerTask('dev', 'Development build', function() { // set some global flags that all tasks can access grunt.config('isDebug', true); grunt.config('isConcat', false); grunt.config('isMin', false); // run tasks grunt.task.run('lint index'); }); // Production setup grunt.registerTask('prod', 'Production build', function() { // set some global flags that all tasks can access grunt.config('isDebug', false); grunt.config('isConcat', true); grunt.config('isMin', true); // run tasks grunt.task.run('lint concat min index'); }); // Default task grunt.registerTask('default', 'dev'); };
index.js (the index task) :
index.js (the index task)
module.exports = function( grunt ) { grunt.registerTask( "index", "Generate index.html depending on configuration", function() { var conf = grunt.config('index'), tmpl = grunt.file.read(conf.src); grunt.file.write(conf.dest, grunt.template.process(tmpl)); grunt.log.writeln('Generated \'' + conf.dest + '\' from \'' + conf.src + '\''); }); }
最后, index.tmpl 带有生成逻辑:
index.tmpl
<doctype html> <head> <% var jsFiles = grunt.config('jsFiles'), isConcat = grunt.config('isConcat'); if(isConcat) { print('<script type="text/javascript" src="' + grunt.config('concat.dist.dest') + '"></script>\n'); } else { for(var i = 0, len = jsFiles.length; i < len; i++) { print('<script type="text/javascript" src="' + jsFiles[i] + '"></script>\n'); } } %> </head> <html> </html>
UPD。 发现基于 grunt 的Yeoman内置了usemin任务,与 Yeoman 的构建系统集成。它根据 index.html 开发版本中的信息以及其他环境设置生成 index.html 的生产版本。有点复杂但看起来很有趣。