You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					256 lines
				
				8.6 KiB
			
		
		
			
		
	
	
					256 lines
				
				8.6 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								#!/usr/bin/env node
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								* 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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const fsExtra = require('fs-extra');
							 | 
						||
| 
								 | 
							
								const fs = require('fs');
							 | 
						||
| 
								 | 
							
								const {resolve} = require('path');
							 | 
						||
| 
								 | 
							
								const config = require('./config.js');
							 | 
						||
| 
								 | 
							
								const commander = require('commander');
							 | 
						||
| 
								 | 
							
								const {build, watch, color} = require('zrender/build/helper');
							 | 
						||
| 
								 | 
							
								const ecLangPlugin = require('./rollup-plugin-ec-lang');
							 | 
						||
| 
								 | 
							
								const prePublish = require('./pre-publish');
							 | 
						||
| 
								 | 
							
								const recheckDEV = require('zrender/build/babel-plugin-transform-remove-dev').recheckDEV;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function run() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Tips for `commander`:
							 | 
						||
| 
								 | 
							
								     * (1) If arg xxx not specified, `commander.xxx` is undefined.
							 | 
						||
| 
								 | 
							
								     *     Otherwise:
							 | 
						||
| 
								 | 
							
								     *      If '-x, --xxx', `commander.xxx` can only be true/false, even if '--xxx yyy' input.
							 | 
						||
| 
								 | 
							
								     *      If '-x, --xxx <some>', the 'some' string is required, or otherwise error will be thrown.
							 | 
						||
| 
								 | 
							
								     *      If '-x, --xxx [some]', the 'some' string is optional, that is, `commander.xxx` can be boolean or string.
							 | 
						||
| 
								 | 
							
								     * (2) `node ./build/build.js --help` will print helper info and exit.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let descIndent = '                                 ';
							 | 
						||
| 
								 | 
							
								    let egIndent = '    ';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    commander
							 | 
						||
| 
								 | 
							
								        .usage('[options]')
							 | 
						||
| 
								 | 
							
								        .description([
							 | 
						||
| 
								 | 
							
								            'Build echarts and generate result files in directory `echarts/dist`.',
							 | 
						||
| 
								 | 
							
								            '',
							 | 
						||
| 
								 | 
							
								            '  For example:',
							 | 
						||
| 
								 | 
							
								            '',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --release'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Build all to `dist` folder.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --prepublish'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Only prepublish.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --removedev'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Remove __DEV__ code. If --min, __DEV__ always be removed.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --type ""'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Only generate `dist/echarts.js`.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --type common --min'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Only generate `dist/echarts.common.min.js`.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --type simple --min --lang en'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Only generate `dist/echarts-en.simple.min.js`.',
							 | 
						||
| 
								 | 
							
								            egIndent + 'node build/build.js --lang "my/lang.js" -i "my/index.js" -o "my/bundle.js"'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + '# Take `<cwd>/my/index.js` as input and generate `<cwd>/my/bundle.js`,'
							 | 
						||
| 
								 | 
							
								                + '\n' + descIndent + 'where `<cwd>/my/lang.js` is used as language file.',
							 | 
						||
| 
								 | 
							
								        ].join('\n'))
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '-w, --watch', [
							 | 
						||
| 
								 | 
							
								            'Watch modifications of files and auto-compile to dist file. For example,',
							 | 
						||
| 
								 | 
							
								            descIndent + '`echarts/dist/echarts.js`.'
							 | 
						||
| 
								 | 
							
								        ].join('\n'))
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--lang <language file path or shortcut>', [
							 | 
						||
| 
								 | 
							
								            'Use the specified file instead of `echarts/src/lang.js`. For example:',
							 | 
						||
| 
								 | 
							
								            descIndent + '`--lang en` will use `echarts/src/langEN.js`.',
							 | 
						||
| 
								 | 
							
								            descIndent + '`--lang my/langDE.js` will use `<cwd>/my/langDE.js`. -o must be specified in this case.',
							 | 
						||
| 
								 | 
							
								            descIndent + '`--lang /my/indexSW.js` will use `/my/indexSW.js`. -o must be specified in this case.'
							 | 
						||
| 
								 | 
							
								        ].join('\n'))
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--release',
							 | 
						||
| 
								 | 
							
								            'Build all for release'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--prepublish',
							 | 
						||
| 
								 | 
							
								            'Build all for release'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--removedev',
							 | 
						||
| 
								 | 
							
								            'Remove __DEV__ code. If --min, __DEV__ always be removed.'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--min',
							 | 
						||
| 
								 | 
							
								            'Whether to compress the output file, and remove error-log-print code.'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--type <type name>', [
							 | 
						||
| 
								 | 
							
								            'Can be "simple" or "common" or "" (default). For example,',
							 | 
						||
| 
								 | 
							
								            descIndent + '`--type ""` or `--type "common"`.'
							 | 
						||
| 
								 | 
							
								        ].join('\n'))
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--sourcemap',
							 | 
						||
| 
								 | 
							
								            'Whether output sourcemap.'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '--format <format>',
							 | 
						||
| 
								 | 
							
								            'The format of output bundle. Can be "umd", "amd", "iife", "cjs", "es".'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '-i, --input <input file path>',
							 | 
						||
| 
								 | 
							
								            'If input file path is specified, output file path must be specified too.'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .option(
							 | 
						||
| 
								 | 
							
								            '-o, --output <output file path>',
							 | 
						||
| 
								 | 
							
								            'If output file path is specified, input file path must be specified too.'
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								        .parse(process.argv);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let isWatch = !!commander.watch;
							 | 
						||
| 
								 | 
							
								    let isRelease = !!commander.release;
							 | 
						||
| 
								 | 
							
								    let isPrePublish = !!commander.prepublish;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let opt = {
							 | 
						||
| 
								 | 
							
								        lang: commander.lang,
							 | 
						||
| 
								 | 
							
								        min: commander.min,
							 | 
						||
| 
								 | 
							
								        type: commander.type || '',
							 | 
						||
| 
								 | 
							
								        input: commander.input,
							 | 
						||
| 
								 | 
							
								        output: commander.output,
							 | 
						||
| 
								 | 
							
								        format: commander.format,
							 | 
						||
| 
								 | 
							
								        sourcemap: commander.sourcemap,
							 | 
						||
| 
								 | 
							
								        removeDev: commander.removedev,
							 | 
						||
| 
								 | 
							
								        addBundleVersion: isWatch
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    validateIO(opt.input, opt.output);
							 | 
						||
| 
								 | 
							
								    validateLang(opt.lang, opt.output);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    normalizeParams(opt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Clear `echarts/dist`
							 | 
						||
| 
								 | 
							
								    if (isRelease) {
							 | 
						||
| 
								 | 
							
								        fsExtra.removeSync(getPath('./dist'));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (isWatch) {
							 | 
						||
| 
								 | 
							
								        watch(config.createECharts(opt));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (isPrePublish) {
							 | 
						||
| 
								 | 
							
								        prePublish();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (isRelease) {
							 | 
						||
| 
								 | 
							
								        let configs = [];
							 | 
						||
| 
								 | 
							
								        let configForCheck;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        [
							 | 
						||
| 
								 | 
							
								            {min: false},
							 | 
						||
| 
								 | 
							
								            {min: true},
							 | 
						||
| 
								 | 
							
								            {min: false, lang: 'en'},
							 | 
						||
| 
								 | 
							
								            {min: true, lang: 'en'}
							 | 
						||
| 
								 | 
							
								        ].forEach(function (opt) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            ['', 'simple', 'common'].forEach(function (type) {
							 | 
						||
| 
								 | 
							
								                let singleOpt = Object.assign({type}, opt);
							 | 
						||
| 
								 | 
							
								                normalizeParams(singleOpt);
							 | 
						||
| 
								 | 
							
								                let singleConfig = config.createECharts(singleOpt);
							 | 
						||
| 
								 | 
							
								                configs.push(singleConfig);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (singleOpt.min && singleOpt.type === '') {
							 | 
						||
| 
								 | 
							
								                    configForCheck = singleConfig;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        configs.push(
							 | 
						||
| 
								 | 
							
								            config.createBMap(false),
							 | 
						||
| 
								 | 
							
								            config.createBMap(true),
							 | 
						||
| 
								 | 
							
								            config.createDataTool(false),
							 | 
						||
| 
								 | 
							
								            config.createDataTool(true)
							 | 
						||
| 
								 | 
							
								        );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        build(configs)
							 | 
						||
| 
								 | 
							
								            .then(function () {
							 | 
						||
| 
								 | 
							
								                checkCode(configForCheck);
							 | 
						||
| 
								 | 
							
								                prePublish();
							 | 
						||
| 
								 | 
							
								            }).catch(handleBuildError);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else {
							 | 
						||
| 
								 | 
							
								        let cfg = config.createECharts(opt);
							 | 
						||
| 
								 | 
							
								        build([cfg])
							 | 
						||
| 
								 | 
							
								            .then(function () {
							 | 
						||
| 
								 | 
							
								                if (opt.removeDev) {
							 | 
						||
| 
								 | 
							
								                    checkCode(cfg);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            })
							 | 
						||
| 
								 | 
							
								            .catch(handleBuildError);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function normalizeParams(opt) {
							 | 
						||
| 
								 | 
							
								    if (opt.sourcemap == null) {
							 | 
						||
| 
								 | 
							
								        opt.sourcemap = !(opt.min || opt.type);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (opt.removeDev == null) {
							 | 
						||
| 
								 | 
							
								        opt.removeDev = !!opt.min;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function handleBuildError(err) {
							 | 
						||
| 
								 | 
							
								    console.log(err);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function checkCode(singleConfig) {
							 | 
						||
| 
								 | 
							
								    // Make sure __DEV__ is eliminated.
							 | 
						||
| 
								 | 
							
								    let code = fs.readFileSync(singleConfig.output.file, {encoding: 'utf-8'});
							 | 
						||
| 
								 | 
							
								    if (!code) {
							 | 
						||
| 
								 | 
							
								        throw new Error(`${singleConfig.output.file} is empty`);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    recheckDEV(code);
							 | 
						||
| 
								 | 
							
								    console.log(color('fgGreen', 'dim')('Check code: correct.'));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function validateIO(input, output) {
							 | 
						||
| 
								 | 
							
								    if ((input != null && output == null)
							 | 
						||
| 
								 | 
							
								        || (input == null && output != null)
							 | 
						||
| 
								 | 
							
								    ) {
							 | 
						||
| 
								 | 
							
								        throw new Error('`input` and `output` must be both set.');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function validateLang(lang, output) {
							 | 
						||
| 
								 | 
							
								    if (!lang) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    let langInfo = ecLangPlugin.getLangFileInfo(lang);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (langInfo.isOuter && !output) {
							 | 
						||
| 
								 | 
							
								        throw new Error('`-o` or `--output` must be specified if using a file path in `--lang`.');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (!langInfo.absolutePath || !fs.statSync(langInfo.absolutePath).isFile()) {
							 | 
						||
| 
								 | 
							
								        throw new Error(`File ${langInfo.absolutePath} does not exist yet. Contribution is welcome!`);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @param {string} relativePath Based on echarts directory.
							 | 
						||
| 
								 | 
							
								 * @return {string} Absolute path.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function getPath(relativePath) {
							 | 
						||
| 
								 | 
							
								    return resolve(__dirname, '../', relativePath);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								run();
							 |