Commit bb3b8f817de15d336968354515649f7142cd5683

Authored by nebv
1 parent e83cb06b

feat: the production environment can be dynamically configured

.env.production
@@ -9,3 +9,7 @@ VITE_GLOB_API_URL=/api @@ -9,3 +9,7 @@ VITE_GLOB_API_URL=/api
9 9
10 # Interface prefix 10 # Interface prefix
11 VITE_GLOB_API_URL_PREFIX= 11 VITE_GLOB_API_URL_PREFIX=
  12 +
  13 +
  14 +# TODO use Cdn
  15 +VITE_USE_CDN = true
README.md
@@ -218,6 +218,7 @@ yarn clean:lib # 删除node_modules,兼容window系统 @@ -218,6 +218,7 @@ yarn clean:lib # 删除node_modules,兼容window系统
218 - [x] 图表库 218 - [x] 图表库
219 - [x] 数字动画 219 - [x] 数字动画
220 - [x] 首屏加载等待动画 220 - [x] 首屏加载等待动画
  221 +- [x] 抽取生产环境配置文件
221 222
222 ## 正在开发的功能 223 ## 正在开发的功能
223 224
@@ -228,7 +229,7 @@ yarn clean:lib # 删除node_modules,兼容window系统 @@ -228,7 +229,7 @@ yarn clean:lib # 删除node_modules,兼容window系统
228 - [ ] 主题配置 229 - [ ] 主题配置
229 - [ ] 黑暗主题 230 - [ ] 黑暗主题
230 - [ ] 打包 Gzip 231 - [ ] 打包 Gzip
231 -- [ ] 抽取生产环境配置文件 232 +- [ ] 打包 CDN
232 - [ ] 系统性能优化 233 - [ ] 系统性能优化
233 234
234 更多组件/功能/建议/bug/欢迎提交 pr 或者 issue 235 更多组件/功能/建议/bug/欢迎提交 pr 或者 issue
build/config/vite/cdn.ts 0 → 100644
  1 +const css = ['//cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.css'];
  2 +
  3 +// TODO use esm?
  4 +const js = [
  5 + '//cdn.bootcdn.net/ajax/libs/vue/3.0.0/vue.global.prod.js',
  6 + '//cdn.bootcdn.net/ajax/libs/vue-router/4.0.0-beta.13/vue-router.global.min.js',
  7 + '//cdn.bootcdn.net/ajax/libs/vuex/4.0.0-beta.4/vuex.global.prod.js',
  8 + '//cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.min.js',
  9 + '//cdn.bootcdn.net/ajax/libs/qs/6.9.4/qs.min.js',
  10 + '//cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.min.js',
  11 + // '//cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.min.js',
  12 + // '//cdn.bootcdn.net/ajax/libs/crypto-js/3.3.0/crypto-js.min.js',
  13 + // '//cdn.bootcdn.net/ajax/libs/vue-i18n/8.18.1/vue-i18n.min.js',
  14 +];
  15 +
  16 +export const externals = ['vue', 'vuex', 'vue-router', 'axios', 'qs', 'nprogress'];
  17 +
  18 +export const cdnConf = {
  19 + css,
  20 + js,
  21 +};
build/config/vite/env.ts deleted 100644 → 0
1 -import moment from 'moment';  
2 -// @ts-ignore  
3 -import pkg from '../../../package.json';  
4 -export function setupBasicEnv() {  
5 - // version  
6 - process.env.VITE_VERSION = (pkg as any).version;  
7 - // build time  
8 - process.env.VITE_APP_BUILD_TIME = moment().format('YYYY-MM-DD HH:mm:ss');  
9 - process.env.VITE_BUILD_SHORT_TIME = moment().format('MMDDHHmmss');  
10 -}  
build/constant.ts 0 → 100644
  1 +export const GLOB_CONFIG_FILE_NAME = '_app.config.js';
build/getShortName.ts 0 → 100644
  1 +export const getShortName = (env: any) => {
  2 + return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
  3 + .toUpperCase()
  4 + .replace(/\s/g, '');
  5 +};
build/jsc.js 0 → 100644
  1 +// js调用cli 兼容调用ts
  2 +
  3 +const { sh } = require('tasksfile');
  4 +const { argv } = require('yargs');
  5 +
  6 +let command = ``;
  7 +
  8 +Object.keys(argv).forEach((key) => {
  9 + if (!/^\$/.test(key) && key !== '_') {
  10 + // @ts-ignore
  11 + if (argv[key]) {
  12 + command += `--${key} `;
  13 + }
  14 + }
  15 +});
  16 +
  17 +// 执行任务名称
  18 +let taskList = argv._;
  19 +
  20 +let NODE_ENV = process.env.NODE_ENV || 'development';
  21 +
  22 +if (taskList.includes('build') || taskList.includes('report') || taskList.includes('preview')) {
  23 + NODE_ENV = 'production';
  24 +}
  25 +
  26 +if (taskList && Array.isArray(taskList) && taskList.length) {
  27 + sh(
  28 + `cross-env NODE_ENV=${NODE_ENV} ts-node --project ./build/tsconfig.json ./build/script/cli.ts ${taskList.join(
  29 + ' '
  30 + )} ${command}`,
  31 + {
  32 + async: true,
  33 + nopipe: true,
  34 + }
  35 + );
  36 +}
build/script/build.ts 0 → 100644
  1 +// #!/usr/bin/env node
  2 +
  3 +import { sh } from 'tasksfile';
  4 +import { argv } from 'yargs';
  5 +import { runBuildConfig } from './buildConf';
  6 +import { runUpdateHtml } from './updateHtml';
  7 +import { errorConsole, successConsole } from '../utils';
  8 +
  9 +export const runBuild = async () => {
  10 + try {
  11 + const argvList = argv._;
  12 + let cmd = `cross-env NODE_ENV=production vite build`;
  13 + await sh(cmd, {
  14 + async: true,
  15 + nopipe: true,
  16 + });
  17 +
  18 + // Generate configuration file
  19 + if (!argvList.includes('no-conf')) {
  20 + await runBuildConfig();
  21 + }
  22 + await runUpdateHtml();
  23 + successConsole('Vite Build successfully!');
  24 + } catch (error) {
  25 + errorConsole('Vite Build Error\n' + error);
  26 + process.exit(1);
  27 + }
  28 +};
build/script/buildConf.ts 0 → 100644
  1 +import { GLOB_CONFIG_FILE_NAME } from '../constant';
  2 +import fs, { writeFileSync } from 'fs-extra';
  3 +
  4 +import viteConfig from '../../vite.config';
  5 +import { errorConsole, successConsole, getCwdPath, getEnvConfig } from '../utils';
  6 +
  7 +const getShortName = (env: any) => {
  8 + return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
  9 + .toUpperCase()
  10 + .replace(/\s/g, '');
  11 +};
  12 +
  13 +function createConfig(
  14 + {
  15 + configName,
  16 + config,
  17 + configFileName = GLOB_CONFIG_FILE_NAME,
  18 + }: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} }
  19 +) {
  20 + try {
  21 + const windowConf = `window.${configName}`;
  22 + const outDir = viteConfig.outDir || 'dist';
  23 + const configStr = `${windowConf}=${JSON.stringify(config)};
  24 +
  25 + Object.freeze(${windowConf});
  26 + Object.defineProperty(window, "${configName}", {
  27 + configurable: false,
  28 + writable: false,
  29 + });
  30 + `;
  31 + fs.mkdirp(getCwdPath(outDir));
  32 + writeFileSync(getCwdPath(`${outDir}/${configFileName}`), configStr);
  33 +
  34 + successConsole('The configuration file is build successfully!');
  35 + } catch (error) {
  36 + errorConsole('Configuration file configuration file failed to package\n' + error);
  37 + }
  38 +}
  39 +
  40 +export function runBuildConfig() {
  41 + const config = getEnvConfig();
  42 + const configFileName = getShortName(config);
  43 + createConfig({ config, configName: configFileName });
  44 +}
build/script/changelog.ts
1 // #!/usr/bin/env node 1 // #!/usr/bin/env node
2 2
3 import { sh } from 'tasksfile'; 3 import { sh } from 'tasksfile';
4 -import chalk from 'chalk'; 4 +import { errorConsole, successConsole } from '../utils';
5 5
6 -const createChangeLog = async () => { 6 +export const runChangeLog = async () => {
7 try { 7 try {
8 let cmd = `conventional-changelog -p custom-config -i CHANGELOG.md -s -r 0 `; 8 let cmd = `conventional-changelog -p custom-config -i CHANGELOG.md -s -r 0 `;
9 - // if (shell.which('git')) {  
10 - // cmd += '&& git add CHANGELOG.md';  
11 - // }  
12 await sh(cmd, { 9 await sh(cmd, {
13 async: true, 10 async: true,
14 nopipe: true, 11 nopipe: true,
@@ -18,21 +15,10 @@ const createChangeLog = async () => { @@ -18,21 +15,10 @@ const createChangeLog = async () => {
18 async: true, 15 async: true,
19 nopipe: true, 16 nopipe: true,
20 }); 17 });
21 - console.log(  
22 - chalk.blue.bold('**************** ') +  
23 - chalk.green.bold('CHANGE_LOG generated successfully!') +  
24 - chalk.blue.bold(' ****************')  
25 - ); 18 + successConsole('CHANGE_LOG.md generated successfully!');
26 } catch (error) { 19 } catch (error) {
27 - console.log(  
28 - chalk.blue.red('**************** ') +  
29 - chalk.green.red('CHANGE_LOG generated error\n' + error) +  
30 - chalk.blue.red(' ****************')  
31 - ); 20 + errorConsole('CHANGE_LOG.md generated error\n' + error);
  21 +
32 process.exit(1); 22 process.exit(1);
33 } 23 }
34 }; 24 };
35 -createChangeLog();  
36 -module.exports = {  
37 - createChangeLog,  
38 -};  
build/script/cli.ts 0 → 100644
  1 +#!/usr/bin/env node
  2 +
  3 +import chalk from 'chalk';
  4 +import { argv } from 'yargs';
  5 +
  6 +import { runChangeLog } from './changelog';
  7 +import { runPostInstall } from './postinstall';
  8 +import { runPreview } from './preview';
  9 +import { runPreserve } from './preserve';
  10 +import { runBuild } from './build';
  11 +
  12 +const task = (argv._ || [])[0];
  13 +
  14 +console.log('Run Task: ' + chalk.cyan(task));
  15 +
  16 +switch (task) {
  17 + // change log
  18 + case 'log':
  19 + runChangeLog();
  20 + break;
  21 +
  22 + case 'build':
  23 + runBuild();
  24 + break;
  25 +
  26 + case 'preserve':
  27 + runPreserve();
  28 + break;
  29 +
  30 + case 'postinstall':
  31 + runPostInstall();
  32 + break;
  33 +
  34 + case 'preview':
  35 + runPreview();
  36 + break;
  37 +
  38 + // TODO
  39 + case 'gzip':
  40 + break;
  41 + default:
  42 + break;
  43 +}
  44 +
  45 +export default {};
build/script/hm.ts 0 → 100644
  1 +// 百度统计代码 用于站点部署
  2 +// 只在build:site开启
  3 +export const hmScript = `<script>
  4 +var _hmt = _hmt || [];
  5 +(function() {
  6 + var hm = document.createElement("script");
  7 + hm.src = "https://hm.baidu.com/hm.js?384d6046e02f6ac4ea075357bd0e9b43";
  8 + var s = document.getElementsByTagName("script")[0];
  9 + s.parentNode.insertBefore(hm, s);
  10 +})();
  11 +</script>
  12 +`;
build/script/postinstall.ts
@@ -2,9 +2,14 @@ import { exec, which } from &#39;shelljs&#39;; @@ -2,9 +2,14 @@ import { exec, which } from &#39;shelljs&#39;;
2 2
3 function ignoreCaseGit() { 3 function ignoreCaseGit() {
4 try { 4 try {
5 - if (which('git')) { 5 + if (which('git').code === 0) {
6 exec('git config core.ignorecase false '); 6 exec('git config core.ignorecase false ');
7 } 7 }
8 - } catch (error) {} 8 + } catch (error) {
  9 + console.log(error);
  10 + }
  11 +}
  12 +
  13 +export function runPostInstall() {
  14 + ignoreCaseGit();
9 } 15 }
10 -ignoreCaseGit();  
build/script/preserve.ts
1 -// 是否需要更新依赖,防止package.json更新了依赖,其他人获取代码后没有install 1 +// Do you need to update the dependencies to prevent package.json from updating the dependencies, and no install after others get the code
2 2
3 import path from 'path'; 3 import path from 'path';
4 import fs from 'fs-extra'; 4 import fs from 'fs-extra';
5 import { isEqual } from 'lodash'; 5 import { isEqual } from 'lodash';
6 -import chalk from 'chalk';  
7 import { sh } from 'tasksfile'; 6 import { sh } from 'tasksfile';
  7 +import { successConsole, errorConsole } from '../utils';
8 8
9 const resolve = (dir: string) => { 9 const resolve = (dir: string) => {
10 return path.resolve(process.cwd(), dir); 10 return path.resolve(process.cwd(), dir);
11 }; 11 };
12 12
  13 +const reg = /[\u4E00-\u9FA5\uF900-\uFA2D]/;
  14 +
13 let NEED_INSTALL = false; 15 let NEED_INSTALL = false;
14 16
15 -fs.mkdirp(resolve('build/.cache'));  
16 -function checkPkgUpdate() {  
17 - const pkg = require('../../package.json');  
18 - const { dependencies, devDependencies } = pkg;  
19 - const depsFile = resolve('build/.cache/deps.json');  
20 - if (!fs.pathExistsSync(depsFile)) {  
21 - NEED_INSTALL = true;  
22 - return; 17 +export async function runPreserve() {
  18 + const cwdPath = process.cwd();
  19 + if (reg.test(cwdPath)) {
  20 + errorConsole(
  21 + 'Do not include Chinese, Japanese or Korean in the full path of the project directory, please modify the directory name and run again!'
  22 + );
  23 + errorConsole('项目目录全路径请勿包含中文、日文、韩文,请修改目录名后再次重新运行!');
  24 + process.exit(1);
23 } 25 }
24 - const depsJson = require('../.cache/deps.json');  
25 26
26 - if (!isEqual(depsJson, { dependencies, devDependencies })) {  
27 - NEED_INSTALL = true;  
28 - }  
29 -}  
30 -checkPkgUpdate(); 27 + fs.mkdirp(resolve('build/.cache'));
  28 + function checkPkgUpdate() {
  29 + const pkg = require('../../package.json');
  30 + const { dependencies, devDependencies } = pkg;
  31 + const depsFile = resolve('build/.cache/deps.json');
  32 + if (!fs.pathExistsSync(depsFile)) {
  33 + NEED_INSTALL = true;
  34 + return;
  35 + }
  36 + const depsJson = require('../.cache/deps.json');
31 37
32 -(async () => { 38 + if (!isEqual(depsJson, { dependencies, devDependencies })) {
  39 + NEED_INSTALL = true;
  40 + }
  41 + }
  42 + checkPkgUpdate();
33 if (NEED_INSTALL) { 43 if (NEED_INSTALL) {
34 - console.log(  
35 - chalk.blue.bold('**************** ') +  
36 - chalk.red.bold('检测到依赖变化,正在安装依赖(Tip: 项目首次运行也会执行)!') +  
37 - chalk.blue.bold(' ****************') 44 + // no error
  45 + successConsole(
  46 + 'A dependency change is detected, and the dependency is being installed to ensure that the dependency is consistent! (Tip: The project will be executed for the first time)!'
38 ); 47 );
39 try { 48 try {
40 - // 从代码执行貌似不会自动读取.npmrc 所以手动加上源地址  
41 - // await run('yarn install --registry=https://registry.npm.taobao.org ', {  
42 - await sh('yarn install ', { 49 + await sh('npm run bootstrap ', {
43 async: true, 50 async: true,
44 nopipe: true, 51 nopipe: true,
45 }); 52 });
46 - console.log(  
47 - chalk.blue.bold('**************** ') +  
48 - chalk.green.bold('依赖安装成功,正在运行!') +  
49 - chalk.blue.bold(' ****************')  
50 - ); 53 +
  54 + successConsole('Dependency installation is successful, start running the project!');
51 55
52 const pkg = require('../../package.json'); 56 const pkg = require('../../package.json');
53 const { dependencies, devDependencies } = pkg; 57 const { dependencies, devDependencies } = pkg;
@@ -64,4 +68,4 @@ checkPkgUpdate(); @@ -64,4 +68,4 @@ checkPkgUpdate();
64 } 68 }
65 } catch (error) {} 69 } catch (error) {}
66 } 70 }
67 -})(); 71 +}
build/script/preview.ts
@@ -11,7 +11,7 @@ import { getIPAddress } from &#39;../utils&#39;; @@ -11,7 +11,7 @@ import { getIPAddress } from &#39;../utils&#39;;
11 const BUILD = 1; 11 const BUILD = 1;
12 const NO_BUILD = 2; 12 const NO_BUILD = 2;
13 13
14 -// 启动服务器 14 +// start server
15 const startApp = () => { 15 const startApp = () => {
16 const port = 9680; 16 const port = 9680;
17 portfinder.basePort = port; 17 portfinder.basePort = port;
@@ -23,7 +23,6 @@ const startApp = () =&gt; { @@ -23,7 +23,6 @@ const startApp = () =&gt; {
23 if (err) { 23 if (err) {
24 throw err; 24 throw err;
25 } else { 25 } else {
26 - // const publicPath = process.env.BASE_URL;  
27 app.listen(port, function () { 26 app.listen(port, function () {
28 const empty = ' '; 27 const empty = ' ';
29 const common = `The preview program is already running: 28 const common = `The preview program is already running:
@@ -36,7 +35,7 @@ const startApp = () =&gt; { @@ -36,7 +35,7 @@ const startApp = () =&gt; {
36 }); 35 });
37 }; 36 };
38 37
39 -const preview = async () => { 38 +export const runPreview = async () => {
40 const prompt = inquirer.prompt({ 39 const prompt = inquirer.prompt({
41 type: 'list', 40 type: 'list',
42 message: 'Please select a preview method', 41 message: 'Please select a preview method',
@@ -61,7 +60,3 @@ const preview = async () =&gt; { @@ -61,7 +60,3 @@ const preview = async () =&gt; {
61 } 60 }
62 startApp(); 61 startApp();
63 }; 62 };
64 -  
65 -(() => {  
66 - preview();  
67 -})();  
build/script/updateHtml.ts 0 → 100644
  1 +import { readFileSync, writeFileSync, existsSync } from 'fs-extra';
  2 +import viteConfig, { htmlConfig } from '../../vite.config';
  3 +import { getCwdPath, successConsole, errorConsole } from '../utils';
  4 +import { GLOB_CONFIG_FILE_NAME } from '../constant';
  5 +import { hmScript } from './hm';
  6 +const pkg = require('../../package.json');
  7 +
  8 +const { title, addHm, cdnConf, useCdn } = htmlConfig;
  9 +
  10 +function injectTitle(html: string, htmlTitle: string) {
  11 + if (/<\/title>/.test(html)) {
  12 + return html.replace(/<\/title>/, `${htmlTitle}</title>`);
  13 + }
  14 + return html;
  15 +}
  16 +
  17 +function injectConfigScript(html: string) {
  18 + const tag = `\t\t<script src='${viteConfig.base || './'}${GLOB_CONFIG_FILE_NAME}?v=${
  19 + pkg.version
  20 + }-${new Date().getTime()}'></script>`;
  21 +
  22 + if (/<\/head>/.test(html)) {
  23 + return html.replace(/<\/head>/, `${tag}\n\t\t</head>`);
  24 + }
  25 + return html;
  26 +}
  27 +
  28 +function injectHmScript(html: string) {
  29 + if (/<head>/.test(html)) {
  30 + return html.replace(/<head>/, `<head>\n${hmScript}`);
  31 + }
  32 + return html;
  33 +}
  34 +
  35 +function injectCdnCss(html: string) {
  36 + if (!cdnConf) return html;
  37 + const { css } = cdnConf;
  38 + if (!css || css.length === 0) return html;
  39 +
  40 + let cdnCssTag = '';
  41 + for (const cssLink of css) {
  42 + cdnCssTag += `<link rel="stylesheet" href="${cssLink}">`;
  43 + }
  44 + if (/<\/head>/.test(html)) {
  45 + return html.replace(/<\/head>/, `${cdnCssTag}\n\t\t</head>`);
  46 + }
  47 + return html;
  48 +}
  49 +
  50 +function injectCdnjs(html: string) {
  51 + if (!cdnConf) return html;
  52 + const { js } = cdnConf;
  53 + if (!js || js.length === 0) return html;
  54 +
  55 + let cdnJsTag = '';
  56 + for (const src of js) {
  57 + // TODO
  58 + // <script type="importmap">
  59 + // { "imports": {
  60 + // "vue": "https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.0/vue.esm-browser.js",
  61 + // "vue-router": "https://cdnjs.cloudflare.com/ajax/libs/vue-router/4.0.0-alpha.13/vue-router.esm.js",
  62 + // "vuex": "https://cdnjs.cloudflare.com/ajax/libs/vuex/4.0.0-beta.2/vuex.esm-browser.js"
  63 + // } }
  64 + // </script>
  65 + cdnJsTag += `\t<script type="text/javascript" src="${src}"></script>\n`;
  66 + }
  67 + if (/<\/body>/.test(html)) {
  68 + return html.replace(/<\/body>/, `${cdnJsTag}\n</body>`);
  69 + }
  70 + return html;
  71 +}
  72 +
  73 +export async function runUpdateHtml() {
  74 + const outDir = viteConfig.outDir || 'dist';
  75 + const indexPath = getCwdPath(outDir, 'index.html');
  76 + if (!existsSync(`${indexPath}`)) {
  77 + return;
  78 + }
  79 + try {
  80 + let processedHtml = '';
  81 + const rawHtml = readFileSync(indexPath, 'utf-8');
  82 + processedHtml = rawHtml;
  83 + processedHtml = injectTitle(processedHtml, title);
  84 + processedHtml = injectConfigScript(processedHtml);
  85 + if (addHm) {
  86 + processedHtml = injectHmScript(processedHtml);
  87 + }
  88 + if (useCdn) {
  89 + processedHtml = injectCdnCss(processedHtml);
  90 + processedHtml = injectCdnjs(processedHtml);
  91 + }
  92 +
  93 + writeFileSync(indexPath, processedHtml);
  94 + successConsole('Update Html Successfully!');
  95 + } catch (error) {
  96 + errorConsole('Update Html Error\n' + error);
  97 + }
  98 +}
build/utils.ts
1 import fs from 'fs'; 1 import fs from 'fs';
  2 +import path from 'path';
2 import { networkInterfaces } from 'os'; 3 import { networkInterfaces } from 'os';
3 import dotenv from 'dotenv'; 4 import dotenv from 'dotenv';
  5 +import chalk from 'chalk';
  6 +
4 export const isFunction = (arg: unknown): arg is (...args: any[]) => any => 7 export const isFunction = (arg: unknown): arg is (...args: any[]) => any =>
5 typeof arg === 'function'; 8 typeof arg === 'function';
6 export const isRegExp = (arg: unknown): arg is RegExp => 9 export const isRegExp = (arg: unknown): arg is RegExp =>
@@ -72,6 +75,8 @@ export interface ViteEnv { @@ -72,6 +75,8 @@ export interface ViteEnv {
72 VITE_USE_MOCK: boolean; 75 VITE_USE_MOCK: boolean;
73 VITE_PUBLIC_PATH: string; 76 VITE_PUBLIC_PATH: string;
74 VITE_PROXY: [string, string][]; 77 VITE_PROXY: [string, string][];
  78 + VITE_GLOB_APP_TITLE: string;
  79 + VITE_USE_CDN: boolean;
75 } 80 }
76 81
77 export function loadEnv(): ViteEnv { 82 export function loadEnv(): ViteEnv {
@@ -100,3 +105,49 @@ export function loadEnv(): ViteEnv { @@ -100,3 +105,49 @@ export function loadEnv(): ViteEnv {
100 } 105 }
101 return ret; 106 return ret;
102 } 107 }
  108 +
  109 +export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.production']) {
  110 + let envConfig = {};
  111 + confFiles.forEach((item) => {
  112 + try {
  113 + const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
  114 +
  115 + envConfig = { ...envConfig, ...env };
  116 + } catch (error) {}
  117 + });
  118 + Object.keys(envConfig).forEach((key) => {
  119 + const reg = new RegExp(`^(${match})`);
  120 + if (!reg.test(key)) {
  121 + Reflect.deleteProperty(envConfig, key);
  122 + }
  123 + });
  124 + return envConfig;
  125 +}
  126 +
  127 +export function successConsole(message: any) {
  128 + console.log(
  129 + chalk.blue.bold('**************** ') +
  130 + chalk.green.bold('✨ ' + message) +
  131 + chalk.blue.bold(' ****************')
  132 + );
  133 +}
  134 +
  135 +export function errorConsole(message: any) {
  136 + console.log(
  137 + chalk.blue.bold('**************** ') +
  138 + chalk.red.bold('✨ ' + message) +
  139 + chalk.blue.bold(' ****************')
  140 + );
  141 +}
  142 +
  143 +export function warnConsole(message: any) {
  144 + console.log(
  145 + chalk.blue.bold('**************** ') +
  146 + chalk.yellow.bold('✨ ' + message) +
  147 + chalk.blue.bold(' ****************')
  148 + );
  149 +}
  150 +
  151 +export function getCwdPath(...dir: string[]) {
  152 + return path.resolve(process.cwd(), ...dir);
  153 +}
getEnvConfig.ts deleted 100644 → 0
1 -import type { GlobEnvConfig } from './src/types/config';  
2 -  
3 -export const getGlobEnvConfig = (): GlobEnvConfig => {  
4 - const env = import.meta.env;  
5 - return (env as unknown) as GlobEnvConfig;  
6 -};  
index.html
@@ -2,9 +2,14 @@ @@ -2,9 +2,14 @@
2 <html lang="en"> 2 <html lang="en">
3 <head> 3 <head>
4 <meta charset="UTF-8" /> 4 <meta charset="UTF-8" />
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  6 + <meta name="renderer" content="webkit" />
  7 + <meta
  8 + name="viewport"
  9 + content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
  10 + />
  11 + <title></title>
5 <link rel="icon" href="/favicon.ico" /> 12 <link rel="icon" href="/favicon.ico" />
6 - <meta name="viewport" content="width=device-width, initial-scale=1.0" />  
7 - <title>Vue Vben admin 2.0</title>  
8 </head> 13 </head>
9 <body> 14 <body>
10 <div id="app"> 15 <div id="app">
@@ -43,7 +48,7 @@ @@ -43,7 +48,7 @@
43 .app-loading { 48 .app-loading {
44 width: 100%; 49 width: 100%;
45 height: 100%; 50 height: 100%;
46 - background: rgba(255, 255, 255, 0, 3); 51 + background: rgba(255, 255, 255, 0, 1);
47 } 52 }
48 53
49 .app-loading .app-loading-wrap { 54 .app-loading .app-loading-wrap {
package.json
@@ -3,21 +3,22 @@ @@ -3,21 +3,22 @@
3 "version": "2.0.0-beta.6", 3 "version": "2.0.0-beta.6",
4 "scripts": { 4 "scripts": {
5 "bootstrap": "yarn install", 5 "bootstrap": "yarn install",
6 - "serve": "ts-node --project ./build/tsconfig.json ./build/script/preserve && cross-env NODE_ENV=development vite",  
7 - "build": "cross-env NODE_ENV=production vite build ",  
8 - "report": "cross-env REPORT=true yarn build ",  
9 - "build:no-cache": "yarn clean:cache && yarn build",  
10 - "preview": "ts-node --project ./build/tsconfig.json ./build/script/preview",  
11 - "log": "ts-node --project ./build/tsconfig.json ./build/script/changelog",  
12 - "gen:gz": "ts-node --project build/tsconfig.build.json ./build/gzip/index.ts ",  
13 - "clean:cache": "npx rimraf node_modules/.cache/ && npx rimraf node_modules/.vite_opt_cache", 6 + "serve": "node ./build/jsc.js preserve && cross-env NODE_ENV=development vite",
  7 + "build": "node ./build/jsc.js build",
  8 + "build:site": "cross-env SITE=true npm run build ",
  9 + "build:no-cache": "yarn clean:cache && npm run build",
  10 + "report": "cross-env REPORT=true npm run build ",
  11 + "preview": "node ./build/jsc.js preview",
  12 + "log": "node ./build/jsc.js log",
  13 + "gen:gz": "node ./build/jsc.js gzip",
  14 + "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite_opt_cache",
14 "clean:lib": "npx rimraf node_modules", 15 "clean:lib": "npx rimraf node_modules",
15 "ls-lint": "npx ls-lint", 16 "ls-lint": "npx ls-lint",
16 "lint:eslint": "eslint --fix --ext \"src/**/*.{vue,less,css,scss}\"", 17 "lint:eslint": "eslint --fix --ext \"src/**/*.{vue,less,css,scss}\"",
17 "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", 18 "lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
18 - "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",  
19 - "reinstall": "npx rimraf node_modules && npx rimraf yarn.lock && npx rimraf package.lock.json && yarn run bootstrap",  
20 - "postinstall": "ts-node --project ./build/tsconfig.json ./build/script/postinstall" 19 + "lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
  20 + "reinstall": "rimraf node_modules && rimraf yarn.lock && rimraf package.lock.json && npm run bootstrap",
  21 + "postinstall": "node ./build/jsc.js postinstall"
21 }, 22 },
22 "dependencies": { 23 "dependencies": {
23 "@iconify/iconify": "^2.0.0-rc.1", 24 "@iconify/iconify": "^2.0.0-rc.1",
@@ -53,6 +54,7 @@ @@ -53,6 +54,7 @@
53 "@types/qrcode": "^1.3.5", 54 "@types/qrcode": "^1.3.5",
54 "@types/rollup-plugin-visualizer": "^2.6.0", 55 "@types/rollup-plugin-visualizer": "^2.6.0",
55 "@types/shelljs": "^0.8.8", 56 "@types/shelljs": "^0.8.8",
  57 + "@types/yargs": "^15.0.8",
56 "@types/zxcvbn": "^4.4.0", 58 "@types/zxcvbn": "^4.4.0",
57 "@typescript-eslint/eslint-plugin": "^4.4.0", 59 "@typescript-eslint/eslint-plugin": "^4.4.0",
58 "@typescript-eslint/parser": "^4.4.0", 60 "@typescript-eslint/parser": "^4.4.0",
@@ -90,7 +92,8 @@ @@ -90,7 +92,8 @@
90 "vite": "^1.0.0-rc.4", 92 "vite": "^1.0.0-rc.4",
91 "vite-plugin-mock": "^1.0.2", 93 "vite-plugin-mock": "^1.0.2",
92 "vite-plugin-purge-icons": "^0.4.1", 94 "vite-plugin-purge-icons": "^0.4.1",
93 - "vue-eslint-parser": "^7.1.0" 95 + "vue-eslint-parser": "^7.1.0",
  96 + "yargs": "^16.0.3"
94 }, 97 },
95 "repository": { 98 "repository": {
96 "type": "git", 99 "type": "git",
src/components/Form/src/BasicForm.vue
@@ -283,7 +283,19 @@ @@ -283,7 +283,19 @@
283 const element = values[key]; 283 const element = values[key];
284 if (fields.includes(key) && element !== undefined && element !== null) { 284 if (fields.includes(key) && element !== undefined && element !== null) {
285 // 时间 285 // 时间
286 - (formModel as any)[key] = itemIsDateType(key) ? moment(element) : element; 286 + if (itemIsDateType(key)) {
  287 + if (Array.isArray(element)) {
  288 + const arr: any[] = [];
  289 + for (const ele of element) {
  290 + arr.push(moment(ele));
  291 + }
  292 + (formModel as any)[key] = arr;
  293 + } else {
  294 + (formModel as any)[key] = moment(element);
  295 + }
  296 + } else {
  297 + (formModel as any)[key] = element;
  298 + }
287 if (formEl) { 299 if (formEl) {
288 formEl.validateFields([key]); 300 formEl.validateFields([key]);
289 } 301 }
src/components/Menu/src/BasicMenu.tsx
@@ -209,7 +209,7 @@ export default defineComponent({ @@ -209,7 +209,7 @@ export default defineComponent({
209 : {}; 209 : {};
210 return ( 210 return (
211 <Menu 211 <Menu
212 - forceSubMenuRender={props.isAppMenu} 212 + // forceSubMenuRender={props.isAppMenu}
213 selectedKeys={selectedKeys} 213 selectedKeys={selectedKeys}
214 defaultSelectedKeys={defaultSelectedKeys} 214 defaultSelectedKeys={defaultSelectedKeys}
215 mode={mode} 215 mode={mode}
src/components/Table/src/hooks/useTableScroll.ts
@@ -77,7 +77,7 @@ export function useTableScroll(refProps: ComputedRef&lt;BasicTableProps&gt;, tableElRe @@ -77,7 +77,7 @@ export function useTableScroll(refProps: ComputedRef&lt;BasicTableProps&gt;, tableElRe
77 if (el) { 77 if (el) {
78 headerHeight = (el as HTMLElement).offsetHeight; 78 headerHeight = (el as HTMLElement).offsetHeight;
79 } 79 }
80 - tableHeightRef.value = 80 + const tHeight =
81 bottomIncludeBody - 81 bottomIncludeBody -
82 (resizeHeightOffset || 0) - 82 (resizeHeightOffset || 0) -
83 paddingHeight - 83 paddingHeight -
@@ -86,8 +86,7 @@ export function useTableScroll(refProps: ComputedRef&lt;BasicTableProps&gt;, tableElRe @@ -86,8 +86,7 @@ export function useTableScroll(refProps: ComputedRef&lt;BasicTableProps&gt;, tableElRe
86 footerHeight - 86 footerHeight -
87 headerHeight; 87 headerHeight;
88 useTimeout(() => { 88 useTimeout(() => {
89 - tableHeightRef.value =  
90 - tableHeightRef.value! > maxHeight! ? (maxHeight as number) : tableHeightRef.value; 89 + tableHeightRef.value = tHeight > maxHeight! ? (maxHeight as number) : tableHeightRef.value;
91 cb && cb(); 90 cb && cb();
92 }, 0); 91 }, 0);
93 } 92 }
src/hooks/core/useSetting.ts
1 -import type { ProjectConfig, GlobConfig, SettingWrap } from '/@/types/config'; 1 +import type { ProjectConfig, GlobConfig, SettingWrap, GlobEnvConfig } from '/@/types/config';
2 2
3 import getProjectSetting from '/@/settings/projectSetting'; 3 import getProjectSetting from '/@/settings/projectSetting';
4 4
5 -import { getGlobEnvConfig } from '../../../getEnvConfig'; 5 +import { getGlobEnvConfig, isDevMode } from '/@/utils/env';
  6 +import { getShortName } from '../../../build/getShortName';
  7 +
  8 +const ENV_NAME = getShortName(import.meta.env);
  9 +const ENV = ((isDevMode()
  10 + ? getGlobEnvConfig()
  11 + : window[ENV_NAME as any]) as unknown) as GlobEnvConfig;
6 const { 12 const {
  13 + VITE_GLOB_APP_TITLE,
7 VITE_GLOB_API_URL, 14 VITE_GLOB_API_URL,
8 VITE_GLOB_APP_SHORT_NAME, 15 VITE_GLOB_APP_SHORT_NAME,
9 - VITE_GLOB_APP_TITLE,  
10 VITE_GLOB_API_URL_PREFIX, 16 VITE_GLOB_API_URL_PREFIX,
11 -} = getGlobEnvConfig(); 17 +} = ENV;
12 18
13 export const useSetting = (): SettingWrap => { 19 export const useSetting = (): SettingWrap => {
14 // Take global configuration 20 // Take global configuration
@@ -19,7 +25,9 @@ export const useSetting = (): SettingWrap =&gt; { @@ -19,7 +25,9 @@ export const useSetting = (): SettingWrap =&gt; {
19 urlPrefix: VITE_GLOB_API_URL_PREFIX, 25 urlPrefix: VITE_GLOB_API_URL_PREFIX,
20 }; 26 };
21 const projectSetting: Readonly<ProjectConfig> = getProjectSetting; 27 const projectSetting: Readonly<ProjectConfig> = getProjectSetting;
22 - 28 + console.log('======================');
  29 + console.log(glob);
  30 + console.log('======================');
23 return { 31 return {
24 globSetting: glob as Readonly<GlobConfig>, 32 globSetting: glob as Readonly<GlobConfig>,
25 projectSetting, 33 projectSetting,
src/hooks/web/useECharts.ts
@@ -59,19 +59,17 @@ export function useECharts( @@ -59,19 +59,17 @@ export function useECharts(
59 59
60 function resize() { 60 function resize() {
61 const chartInstance = unref(chartInstanceRef); 61 const chartInstance = unref(chartInstanceRef);
62 - if (!chartInstance) {  
63 - return;  
64 - } 62 + if (!chartInstance) return;
65 chartInstance.resize(); 63 chartInstance.resize();
66 } 64 }
  65 +
67 tryOnUnmounted(() => { 66 tryOnUnmounted(() => {
68 const chartInstance = unref(chartInstanceRef); 67 const chartInstance = unref(chartInstanceRef);
69 - if (!chartInstance) {  
70 - return;  
71 - } 68 + if (!chartInstance) return;
72 chartInstance.dispose(); 69 chartInstance.dispose();
73 chartInstanceRef.value = null; 70 chartInstanceRef.value = null;
74 }); 71 });
  72 +
75 return { 73 return {
76 setOptions, 74 setOptions,
77 echarts, 75 echarts,
src/utils/env.ts
  1 +import type { GlobEnvConfig } from '/@/types/config';
  2 +
  3 +export const getGlobEnvConfig = (): GlobEnvConfig => {
  4 + const env = import.meta.env;
  5 + return (env as unknown) as GlobEnvConfig;
  6 +};
  7 +
1 /** 8 /**
2 * @description: 开发模式 9 * @description: 开发模式
3 */ 10 */
src/utils/helper/envHelper.ts
1 import { isDevMode, getEnv } from '/@/utils/env'; 1 import { isDevMode, getEnv } from '/@/utils/env';
2 import { useSetting } from '/@/hooks/core/useSetting'; 2 import { useSetting } from '/@/hooks/core/useSetting';
3 - 3 +import moment from 'moment';
4 import pkg from '../../../package.json'; 4 import pkg from '../../../package.json';
5 const { globSetting } = useSetting(); 5 const { globSetting } = useSetting();
6 6
7 // Generate cache key according to version 7 // Generate cache key according to version
8 export const getStorageShortName = () => { 8 export const getStorageShortName = () => {
  9 + const shortTime = moment().format('MMDDHHmmss');
9 return `${globSetting.shortName}__${getEnv()}${ 10 return `${globSetting.shortName}__${getEnv()}${
10 - isDevMode() ? `__${(pkg as any).version}` : '__' + process.env.VITE_BUILD_SHORT_TIME 11 + `__${pkg.version}` + (isDevMode() ? '' : `__${shortTime}`)
11 }__`.toUpperCase(); 12 }__`.toUpperCase();
12 }; 13 };
vite.config.ts
@@ -4,14 +4,26 @@ import type { UserConfig, Plugin as VitePlugin } from &#39;vite&#39;; @@ -4,14 +4,26 @@ import type { UserConfig, Plugin as VitePlugin } from &#39;vite&#39;;
4 4
5 import visualizer from 'rollup-plugin-visualizer'; 5 import visualizer from 'rollup-plugin-visualizer';
6 import { modifyVars } from './build/config/glob/lessModifyVars'; 6 import { modifyVars } from './build/config/glob/lessModifyVars';
7 -import { setupBasicEnv } from './build/config/vite/env'; 7 +import {
  8 + // externals,
  9 + cdnConf,
  10 +} from './build/config/vite/cdn';
  11 +
8 import { createProxy } from './build/config/vite/proxy'; 12 import { createProxy } from './build/config/vite/proxy';
9 import { createMockServer } from 'vite-plugin-mock'; 13 import { createMockServer } from 'vite-plugin-mock';
10 import PurgeIcons from 'vite-plugin-purge-icons'; 14 import PurgeIcons from 'vite-plugin-purge-icons';
  15 +
11 import { isDevFn, isReportMode, isProdFn, loadEnv } from './build/utils'; 16 import { isDevFn, isReportMode, isProdFn, loadEnv } from './build/utils';
  17 +const pkg = require('./package.json');
12 18
13 -setupBasicEnv();  
14 -const { VITE_USE_MOCK, VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = loadEnv(); 19 +const {
  20 + VITE_USE_MOCK,
  21 + VITE_PORT,
  22 + VITE_PUBLIC_PATH,
  23 + VITE_PROXY,
  24 + VITE_GLOB_APP_TITLE,
  25 + // VITE_USE_CDN,
  26 +} = loadEnv();
15 27
16 function pathResolve(dir: string) { 28 function pathResolve(dir: string) {
17 return resolve(__dirname, '.', dir); 29 return resolve(__dirname, '.', dir);
@@ -95,9 +107,9 @@ const viteConfig: UserConfig = { @@ -95,9 +107,9 @@ const viteConfig: UserConfig = {
95 alias: { 107 alias: {
96 '/@/': pathResolve('src'), 108 '/@/': pathResolve('src'),
97 }, 109 },
98 - // define: {  
99 - // __ENV__: 'value',  
100 - // }, 110 + define: {
  111 + __VERSION__: pkg.version,
  112 + },
101 // css预处理 113 // css预处理
102 cssPreprocessOptions: { 114 cssPreprocessOptions: {
103 less: { 115 less: {
@@ -122,8 +134,35 @@ const viteConfig: UserConfig = { @@ -122,8 +134,35 @@ const viteConfig: UserConfig = {
122 plugins: [PurgeIcons(), ...vitePlugins], 134 plugins: [PurgeIcons(), ...vitePlugins],
123 rollupOutputOptions: {}, 135 rollupOutputOptions: {},
124 rollupInputOptions: { 136 rollupInputOptions: {
  137 + // TODO
  138 + // external: VITE_USE_CDN ? externals : [],
125 plugins: rollupPlugins, 139 plugins: rollupPlugins,
126 }, 140 },
127 }; 141 };
128 142
  143 +// 用于打包部署站点使用。实际项目可以删除
  144 +const isSite = process.env.SITE === 'true';
  145 +// 扩展配置, 往打包后的html注入内容
  146 +// 只针对生产环境
  147 +// TODO 目前只是简单手动注入实现,后续vite应该会提供配置项
  148 +export const htmlConfig: {
  149 + title: string;
  150 + addHm?: boolean;
  151 + cdnConf?: {
  152 + css?: string[];
  153 + js?: string[];
  154 + };
  155 + useCdn: boolean;
  156 +} = {
  157 + // html title
  158 + title: VITE_GLOB_APP_TITLE,
  159 + // 百度统计,不需要可以删除
  160 + addHm: isSite,
  161 + // 使用cdn打包
  162 + // TODO Cdn esm使用方式需要只能支持google,暂时关闭,后续查询更好的方式
  163 + useCdn: false,
  164 + // useCdn: VITE_USE_CDN,
  165 + // cdn列表
  166 + cdnConf,
  167 +};
129 export default viteConfig; 168 export default viteConfig;
yarn.lock
@@ -801,6 +801,18 @@ @@ -801,6 +801,18 @@
801 resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" 801 resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
802 integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== 802 integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
803 803
  804 +"@types/yargs-parser@*":
  805 + version "15.0.0"
  806 + resolved "https://registry.npm.taobao.org/@types/yargs-parser/download/@types/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
  807 + integrity sha1-yz+fdBhp4gzOMw/765JxWQSDiC0=
  808 +
  809 +"@types/yargs@^15.0.8":
  810 + version "15.0.8"
  811 + resolved "https://registry.npm.taobao.org/@types/yargs/download/@types/yargs-15.0.8.tgz?cache=0&sync_timestamp=1602182032636&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fyargs%2Fdownload%2F%40types%2Fyargs-15.0.8.tgz#7644904cad7427eb704331ea9bf1ee5499b82e23"
  812 + integrity sha1-dkSQTK10J+twQzHqm/HuVJm4LiM=
  813 + dependencies:
  814 + "@types/yargs-parser" "*"
  815 +
804 "@types/zrender@*": 816 "@types/zrender@*":
805 version "4.0.0" 817 version "4.0.0"
806 resolved "https://registry.npmjs.org/@types/zrender/-/zrender-4.0.0.tgz#a6806f12ec4eccaaebd9b0d816f049aca6188fbd" 818 resolved "https://registry.npmjs.org/@types/zrender/-/zrender-4.0.0.tgz#a6806f12ec4eccaaebd9b0d816f049aca6188fbd"
@@ -1634,6 +1646,15 @@ cliui@^6.0.0: @@ -1634,6 +1646,15 @@ cliui@^6.0.0:
1634 strip-ansi "^6.0.0" 1646 strip-ansi "^6.0.0"
1635 wrap-ansi "^6.2.0" 1647 wrap-ansi "^6.2.0"
1636 1648
  1649 +cliui@^7.0.0:
  1650 + version "7.0.1"
  1651 + resolved "https://registry.npm.taobao.org/cliui/download/cliui-7.0.1.tgz#a4cb67aad45cd83d8d05128fc9f4d8fbb887e6b3"
  1652 + integrity sha1-pMtnqtRc2D2NBRKPyfTY+7iH5rM=
  1653 + dependencies:
  1654 + string-width "^4.2.0"
  1655 + strip-ansi "^6.0.0"
  1656 + wrap-ansi "^7.0.0"
  1657 +
1637 clone-regexp@^2.1.0: 1658 clone-regexp@^2.1.0:
1638 version "2.2.0" 1659 version "2.2.0"
1639 resolved "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f" 1660 resolved "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f"
@@ -2406,7 +2427,7 @@ esbuild@^0.7.1: @@ -2406,7 +2427,7 @@ esbuild@^0.7.1:
2406 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.7.14.tgz#9de555e75669187c2315317fbf489b229b1a4cbb" 2427 resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.7.14.tgz#9de555e75669187c2315317fbf489b229b1a4cbb"
2407 integrity sha512-w2CEVeRcUhCGYMHnNNwb8q+9w42scL7RcNzJm85gZVzNBE3AF0sLq5YP/IdaTBJIFBphIKG3bGbwRH+zsgH/ig== 2428 integrity sha512-w2CEVeRcUhCGYMHnNNwb8q+9w42scL7RcNzJm85gZVzNBE3AF0sLq5YP/IdaTBJIFBphIKG3bGbwRH+zsgH/ig==
2408 2429
2409 -escalade@^3.1.0: 2430 +escalade@^3.0.2, escalade@^3.1.0:
2410 version "3.1.0" 2431 version "3.1.0"
2411 resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" 2432 resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e"
2412 integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== 2433 integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig==
@@ -2912,7 +2933,7 @@ gensync@^1.0.0-beta.1: @@ -2912,7 +2933,7 @@ gensync@^1.0.0-beta.1:
2912 resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" 2933 resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
2913 integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== 2934 integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
2914 2935
2915 -get-caller-file@^2.0.1: 2936 +get-caller-file@^2.0.1, get-caller-file@^2.0.5:
2916 version "2.0.5" 2937 version "2.0.5"
2917 resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 2938 resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
2918 integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 2939 integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
@@ -7004,6 +7025,15 @@ wrap-ansi@^6.2.0: @@ -7004,6 +7025,15 @@ wrap-ansi@^6.2.0:
7004 string-width "^4.1.0" 7025 string-width "^4.1.0"
7005 strip-ansi "^6.0.0" 7026 strip-ansi "^6.0.0"
7006 7027
  7028 +wrap-ansi@^7.0.0:
  7029 + version "7.0.0"
  7030 + resolved "https://registry.npm.taobao.org/wrap-ansi/download/wrap-ansi-7.0.0.tgz?cache=0&sync_timestamp=1587574502741&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwrap-ansi%2Fdownload%2Fwrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
  7031 + integrity sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM=
  7032 + dependencies:
  7033 + ansi-styles "^4.0.0"
  7034 + string-width "^4.1.0"
  7035 + strip-ansi "^6.0.0"
  7036 +
7007 wrappy@1: 7037 wrappy@1:
7008 version "1.0.2" 7038 version "1.0.2"
7009 resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 7039 resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -7041,6 +7071,11 @@ y18n@^4.0.0: @@ -7041,6 +7071,11 @@ y18n@^4.0.0:
7041 resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 7071 resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
7042 integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 7072 integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
7043 7073
  7074 +y18n@^5.0.1:
  7075 + version "5.0.2"
  7076 + resolved "https://registry.npm.taobao.org/y18n/download/y18n-5.0.2.tgz?cache=0&sync_timestamp=1601576683926&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fy18n%2Fdownload%2Fy18n-5.0.2.tgz#48218df5da2731b4403115c39a1af709c873f829"
  7077 + integrity sha1-SCGN9donMbRAMRXDmhr3Cchz+Ck=
  7078 +
7044 yallist@^3.0.2: 7079 yallist@^3.0.2:
7045 version "3.1.1" 7080 version "3.1.1"
7046 resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" 7081 resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
@@ -7067,6 +7102,11 @@ yargs-parser@^18.1.2, yargs-parser@^18.1.3: @@ -7067,6 +7102,11 @@ yargs-parser@^18.1.2, yargs-parser@^18.1.3:
7067 camelcase "^5.0.0" 7102 camelcase "^5.0.0"
7068 decamelize "^1.2.0" 7103 decamelize "^1.2.0"
7069 7104
  7105 +yargs-parser@^20.0.0:
  7106 + version "20.2.1"
  7107 + resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-20.2.1.tgz?cache=0&sync_timestamp=1601576684570&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-20.2.1.tgz#28f3773c546cdd8a69ddae68116b48a5da328e77"
  7108 + integrity sha1-KPN3PFRs3Ypp3a5oEWtIpdoyjnc=
  7109 +
7070 yargs@^13.2.4: 7110 yargs@^13.2.4:
7071 version "13.3.2" 7111 version "13.3.2"
7072 resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" 7112 resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
@@ -7100,6 +7140,19 @@ yargs@^15.0.0, yargs@^15.1.0: @@ -7100,6 +7140,19 @@ yargs@^15.0.0, yargs@^15.1.0:
7100 y18n "^4.0.0" 7140 y18n "^4.0.0"
7101 yargs-parser "^18.1.2" 7141 yargs-parser "^18.1.2"
7102 7142
  7143 +yargs@^16.0.3:
  7144 + version "16.0.3"
  7145 + resolved "https://registry.npm.taobao.org/yargs/download/yargs-16.0.3.tgz?cache=0&sync_timestamp=1600660006050&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs%2Fdownload%2Fyargs-16.0.3.tgz#7a919b9e43c90f80d4a142a89795e85399a7e54c"
  7146 + integrity sha1-epGbnkPJD4DUoUKol5XoU5mn5Uw=
  7147 + dependencies:
  7148 + cliui "^7.0.0"
  7149 + escalade "^3.0.2"
  7150 + get-caller-file "^2.0.5"
  7151 + require-directory "^2.1.1"
  7152 + string-width "^4.2.0"
  7153 + y18n "^5.0.1"
  7154 + yargs-parser "^20.0.0"
  7155 +
7103 ylru@^1.2.0: 7156 ylru@^1.2.0:
7104 version "1.2.1" 7157 version "1.2.1"
7105 resolved "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" 7158 resolved "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"