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