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