183 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
* Licensed to the Apache Software Foundation (ASF) under one
 | 
						|
* or more contributor license agreements.  See the NOTICE file
 | 
						|
* distributed with this work for additional information
 | 
						|
* regarding copyright ownership.  The ASF licenses this file
 | 
						|
* to you under the Apache License, Version 2.0 (the
 | 
						|
* "License"); you may not use this file except in compliance
 | 
						|
* with the License.  You may obtain a copy of the License at
 | 
						|
*
 | 
						|
*   http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
*
 | 
						|
* Unless required by applicable law or agreed to in writing,
 | 
						|
* software distributed under the License is distributed on an
 | 
						|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | 
						|
* KIND, either express or implied.  See the License for the
 | 
						|
* specific language governing permissions and limitations
 | 
						|
* under the License.
 | 
						|
*/
 | 
						|
 | 
						|
var glob = require('glob');
 | 
						|
var fsExtra = require('fs-extra');
 | 
						|
var esprima = require('esprima');
 | 
						|
 | 
						|
function run(cb) {
 | 
						|
    glob('**/*.js', {
 | 
						|
        cwd: __dirname + '/../src/'
 | 
						|
    }, function (err, files) {
 | 
						|
        files.forEach(function (filePath) {
 | 
						|
            var code = parse(fsExtra.readFileSync(
 | 
						|
                __dirname + '/../src/' + filePath, 'utf-8'));
 | 
						|
            code = code.replace(/require\(([\'"])zrender\//g, 'require($1zrender/lib/');
 | 
						|
            fsExtra.outputFileSync(
 | 
						|
                __dirname + '/../lib/' + filePath,
 | 
						|
                code, 'utf-8');
 | 
						|
        });
 | 
						|
 | 
						|
        cb && cb();
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
if (require.main === module) {
 | 
						|
    run();
 | 
						|
}
 | 
						|
else {
 | 
						|
    module.exports = run;
 | 
						|
}
 | 
						|
 | 
						|
var MAGIC_DEPS = {
 | 
						|
    'exports': true,
 | 
						|
    'module': true,
 | 
						|
    'require': true
 | 
						|
};
 | 
						|
 | 
						|
var SIMPLIFIED_CJS = ['require', 'exports', 'module'];
 | 
						|
 | 
						|
// Convert AMD-style JavaScript string into node.js compatible module
 | 
						|
function parse(raw) {
 | 
						|
    var output = '';
 | 
						|
    var ast = esprima.parse(raw, {
 | 
						|
        range: true,
 | 
						|
        raw: true
 | 
						|
    });
 | 
						|
 | 
						|
    var defines = ast.body.filter(isDefine);
 | 
						|
 | 
						|
    if (defines.length > 1) {
 | 
						|
        throw new Error('Each file can have only a single define call. Found "' + defines.length + '"');
 | 
						|
    }
 | 
						|
    else if (!defines.length) {
 | 
						|
        return raw;
 | 
						|
    }
 | 
						|
 | 
						|
    var def = defines[0];
 | 
						|
    var args = def.expression['arguments'];
 | 
						|
    var factory = getFactory(args);
 | 
						|
    var useStrict = getUseStrict(factory);
 | 
						|
 | 
						|
    // do replacements in-place to avoid modifying the code more than needed
 | 
						|
    if (useStrict) {
 | 
						|
        output += useStrict.expression.raw + ';\n';
 | 
						|
    }
 | 
						|
    output += raw.substring(0, def.range[0]); // anything before define
 | 
						|
    output += getRequires(args, factory); // add requires
 | 
						|
    output += getBody(raw, factory.body, useStrict); // module body
 | 
						|
 | 
						|
    output += raw.substring(def.range[1], raw.length); // anything after define
 | 
						|
 | 
						|
    return output;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function getRequires(args, factory) {
 | 
						|
    var requires = [];
 | 
						|
    var deps = getDependenciesNames(args);
 | 
						|
    var params = factory.params.map(function (param, i) {
 | 
						|
        return {
 | 
						|
            name: param.name,
 | 
						|
            // simplified cjs doesn't have deps
 | 
						|
            dep: (deps.length) ? deps[i] : SIMPLIFIED_CJS[i]
 | 
						|
        };
 | 
						|
    });
 | 
						|
 | 
						|
    params.forEach(function (param) {
 | 
						|
        if (MAGIC_DEPS[param.dep] && !MAGIC_DEPS[param.name]) {
 | 
						|
            // if user remaped magic dependency we declare a var
 | 
						|
            requires.push('var ' + param.name + ' = ' + param.dep + ';');
 | 
						|
        }
 | 
						|
        else if (param.dep && !MAGIC_DEPS[param.dep]) {
 | 
						|
            // only do require for params that have a matching dependency also
 | 
						|
            // skip "magic" dependencies
 | 
						|
            requires.push('var ' + param.name + ' = require(\'' + param.dep + '\');');
 | 
						|
        }
 | 
						|
    });
 | 
						|
 | 
						|
    return requires.join('\n');
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function getDependenciesNames(args) {
 | 
						|
    var deps = [];
 | 
						|
    var arr = args.filter(function (arg) {
 | 
						|
        return arg.type === 'ArrayExpression';
 | 
						|
    })[0];
 | 
						|
 | 
						|
    if (arr) {
 | 
						|
        deps = arr.elements.map(function (el) {
 | 
						|
            return el.value;
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    return deps;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function isDefine(node) {
 | 
						|
    return node.type === 'ExpressionStatement'
 | 
						|
            && node.expression.type === 'CallExpression'
 | 
						|
            && node.expression.callee.type === 'Identifier'
 | 
						|
            && node.expression.callee.name === 'define';
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function getFactory(args) {
 | 
						|
    return args.filter(function (arg) {
 | 
						|
        return arg.type === 'FunctionExpression';
 | 
						|
    })[0];
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function getBody(raw, factoryBody, useStrict) {
 | 
						|
    var returnStatement = factoryBody.body.filter(function (node) {
 | 
						|
        return node.type === 'ReturnStatement';
 | 
						|
    })[0];
 | 
						|
 | 
						|
    var body = '';
 | 
						|
    var bodyStart = useStrict ? useStrict.expression.range[1] + 1 : factoryBody.range[0] + 1;
 | 
						|
 | 
						|
    if (returnStatement) {
 | 
						|
        body += raw.substring(bodyStart, returnStatement.range[0]);
 | 
						|
        // "return ".length === 7 so we add "6" to returnStatement start
 | 
						|
        body += 'module.exports =' + raw.substring(returnStatement.range[0] + 6, factoryBody.range[1] - 1);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        // if using exports or module.exports or just a private module we
 | 
						|
        // simply return the factoryBody content
 | 
						|
        body = raw.substring(bodyStart, factoryBody.range[1] - 1);
 | 
						|
    }
 | 
						|
 | 
						|
    return body;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function getUseStrict(factory) {
 | 
						|
    return factory.body.body.filter(isUseStrict)[0];
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
function isUseStrict(node) {
 | 
						|
    return node.type === 'ExpressionStatement'
 | 
						|
            && node.expression.type === 'Literal'
 | 
						|
            && node.expression.value === 'use strict';
 | 
						|
}
 |