| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 | /** * @fileOverview 负责合并amd modules为一个单文件。 */'use strict';var requirejs = require('requirejs'),    fs = require('fs'),    path = require('path');// convert relative path to absolute path.function convert( name, _path, contents ) {    var rDefine = /(define\s*\(\s*('|").*?\2\s*,\s*\[)([\s\S]*?)\]/ig,        rDeps = /('|")(.*?)\1/g,        root = _path.substr( 0, _path.length - name.length - 3 ),        dir = path.dirname( _path ),        m, m2, deps, dep, _path2;    contents = contents.replace( rDefine, function( m, m1, m2, m3 ) {        return m1 + m3.replace( rDeps, function( m, m1, m2 ) {            m2 = path.join( dir, m2 );            m2 = path.relative( root, m2 );            m2 = m2.replace(/\\/g, '/');            return m1 + m2 + m1;        }) + ']';    });    return contents;}module.exports = function( grunt ) {    grunt.registerMultiTask( 'build', '合并amd modules为一个单文件', function() {        var done = this.async(),            options = this.options({                banner: '',                footer: '',                process: null,                builtin: {                    dollar: false,                    promise: false                }            }),            pkg = grunt.config.get('pkg'),            dest = this.data.dest,            config, flag, custom;        config = {            baseUrl: 'src',            name: '',            out: '',            // We have multiple minify steps            optimize: 'none',            // Include dependencies loaded with require            findNestedDependencies: true,            // Avoid breaking semicolons inserted by r.js            skipSemiColonInsertion: true,            wrap: {                startFile: 'build/intro.js',                endFile: 'build/outro.js'            },            rawText: {},            onBuildWrite: function( name, _path ) {                var compiled = convert.apply( null, arguments );                if ( options.process ) {                    compiled = options.process( compiled, _path );                }                // 调整缩进                compiled = compiled.replace( /(^|\r\n|\r|\n)/g, '$1    ');                compiled = compiled.replace(/@version@/g, function() {                    return pkg.version;                });                return compiled;            },            paths: [],            include: []        };        options = grunt.util._.extend( options, this.data );        config.name = 'webuploader';        if ( options.builtin.dollar ) {            config.rawText.dollar = 'define([\n' +                    '    \'./dollar-builtin\'\n' +                    '], function( $ ) {\n' +                    '    return $;\n' +                    '});';        }        if ( options.builtin.promise ) {            config.rawText.promise = 'define([\n' +                    '    \'./promise-builtin\'\n' +                    '], function( $ ) {\n' +                    '    return $;\n' +                    '});';        }        if ( this.data.preset === 'custom' ) {            custom = [];            this.files.forEach(function( file ) {                var files = file.src,                    cwd = file.cwd || '';                files.filter(function( filepath ) {                    filepath = path.join( cwd, filepath );                    // Warn on and remove invalid source files (if nonull was set).                    if (!grunt.file.exists(filepath)) {                        grunt.log.warn('Source file "' + filepath + '" not found.');                        return false;                    } else {                        return true;                    }                }).forEach(function( filepath ) {                    custom.push( '\'' + filepath.replace( /\.\w+$/, '' ) + '\'' );                });            });            custom.unshift('\'./base\'');            custom = 'define([\n    ' + custom.join(',\n    ') + '\n], function( Base ) {\n    return Base;\n});';            config.rawText.webuploader = custom;        } else if (this.data.preset) {            config.rawText.webuploader = 'define([\n    ' + ['\'./preset/' +                    this.data.preset +'\''].join(',\n    ') +                    '\n], function( preset ) {\n    return preset;\n});';        } else {            config.name = this.data.name;        }        // 处理最终输出        config.out = function( compiled ) {            var arr = [],                banner = grunt.template.process(options.banner),                footer = grunt.template.process(options.footer),                sep = '\n\n';            banner && arr.push( banner );            if ( options.builtin.dollar ) {                compiled = compiled.replace('define([ \'jquery\' ], exports );', 'define([], exports);');            }            arr.push(compiled);            footer && arr.push( footer );            // Write concatenated source to file            grunt.file.write( dest, arr.join( sep ) );            process.nextTick(function() {                // requirejs有bug, callback不一定会执行,目前调试的结果是                // prim的promise实现有问题。                if ( flag ) return;                grunt.log.ok( "File '" + dest + "' created." );                done();                flag = true;            });        };        if (options.fis) {            config.wrap = {                startFile: 'build/fis/intro.js',                endFile: 'build/fis/outro.js'            }        }        requirejs.optimize( config, function( response ) {            // requirejs有bug, callback不一定会执行,目前调试的结果是            // prim的promise实现有问题。            if ( flag ) return;            grunt.verbose.writeln( response );            grunt.log.ok( "File '" + name + "' created." );            done();            flag = true;        }, function( err ) {            done( err );        });    });};
 |