From 6bd858fac520ba494e31a615140fa12ce4b18790 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E5=98=89=E6=B6=B5?= <chenjiahan@youzan.com>
Date: Fri, 6 Dec 2019 11:30:01 +0800
Subject: [PATCH] feat(cli): speed up gen style deps

---
 packages/vant-cli/package.json                |   2 -
 .../src/compiler/gen-style-deps-map.ts        | 144 +++------
 packages/vant-cli/src/compiler/get-deps.ts    |  73 +++++
 packages/vant-cli/yarn.lock                   | 274 +-----------------
 vant.config.js                                |  41 +--
 5 files changed, 151 insertions(+), 383 deletions(-)
 create mode 100644 packages/vant-cli/src/compiler/get-deps.ts

diff --git a/packages/vant-cli/package.json b/packages/vant-cli/package.json
index b4e3b9723..ec4d5b13b 100644
--- a/packages/vant-cli/package.json
+++ b/packages/vant-cli/package.json
@@ -27,7 +27,6 @@
     "vue-template-compiler": "^2.6.10"
   },
   "devDependencies": {
-    "@types/dependency-tree": "^6.1.0",
     "@types/eslint": "^6.1.3",
     "@types/fs-extra": "^8.0.1",
     "@types/html-webpack-plugin": "^3.2.1",
@@ -74,7 +73,6 @@
     "css-loader": "^3.2.0",
     "csso": "^4.0.2",
     "decamelize": "^3.2.0",
-    "dependency-tree": "^7.1.0",
     "eslint": "^6.7.1",
     "gh-pages": "2.0.1",
     "html-webpack-plugin": "3.2.0",
diff --git a/packages/vant-cli/src/compiler/gen-style-deps-map.ts b/packages/vant-cli/src/compiler/gen-style-deps-map.ts
index 1b46d8d51..26c90b07a 100644
--- a/packages/vant-cli/src/compiler/gen-style-deps-map.ts
+++ b/packages/vant-cli/src/compiler/gen-style-deps-map.ts
@@ -1,81 +1,21 @@
-/**
- * Build style entry of all components
- */
-
-import dependencyTree from 'dependency-tree';
 import { join } from 'path';
-import { compileJs } from './compile-js';
-import { compileSfc } from './compile-sfc';
 import { CSS_LANG } from '../common/css';
-import { SRC_DIR, DIST_DIR, STYPE_DEPS_JSON_FILE } from '../common/constant';
-import { copySync, existsSync, readdirSync } from 'fs-extra';
-import {
-  isDir,
-  isSfc,
-  isScript,
-  getComponents,
-  smartOutputFile
-} from '../common';
-
-interface DependencyObj {
-  [k: string]: DependencyObj;
-}
+import { existsSync } from 'fs-extra';
+import { getDeps, clearDepsCache, fillExt } from './get-deps';
+import { getComponents, smartOutputFile } from '../common';
+import { SRC_DIR, STYPE_DEPS_JSON_FILE } from '../common/constant';
 
 const components = getComponents();
-const TEMP_DIR = join(DIST_DIR, 'temp');
-
-function compileTempDir(dir: string): Promise<unknown> {
-  const files = readdirSync(dir);
-
-  return Promise.all(
-    files.map(filename => {
-      const filePath = join(dir, filename);
-
-      if (isDir(filePath)) {
-        if (filePath.includes('/test') || filePath.includes('/demo')) {
-          return Promise.resolve();
-        }
-
-        return compileTempDir(filePath);
-      }
-
-      if (filename.includes('index')) {
-        if (isSfc(filePath)) {
-          return compileSfc(filePath, { skipStyle: true });
-        }
-
-        if (isScript(filePath)) {
-          return compileJs(filePath);
-        }
-      }
-
-      return Promise.resolve();
-    })
-  );
-}
 
 function matchPath(path: string, component: string): boolean {
   return path
-    .replace(TEMP_DIR, '')
+    .replace(SRC_DIR, '')
     .split('/')
     .includes(component);
 }
 
-function search(tree: DependencyObj, component: string, checkList: string[]) {
-  Object.keys(tree).forEach(key => {
-    search(tree[key], component, checkList);
-    components
-      .filter(item => matchPath(key, item))
-      .forEach(item => {
-        if (!checkList.includes(item) && item !== component) {
-          checkList.push(item);
-        }
-      });
-  });
-}
-
 function getStylePath(component: string) {
-  return join(TEMP_DIR, `${component}/index.${CSS_LANG}`);
+  return join(SRC_DIR, `${component}/index.${CSS_LANG}`);
 }
 
 function checkStyleExists(component: string) {
@@ -83,18 +23,31 @@ function checkStyleExists(component: string) {
 }
 
 // analyze component dependencies
-function analyzeDeps(component: string) {
+function analyzeComponentDeps(component: string) {
   const checkList: string[] = [];
+  const componentEntry = fillExt(join(SRC_DIR, component, 'index'));
+  const record = new Set();
 
-  search(
-    dependencyTree({
-      directory: TEMP_DIR,
-      filename: join(TEMP_DIR, component, 'index.js'),
-      filter: path => !~path.indexOf('node_modules')
-    }),
-    component,
-    checkList
-  );
+  function search(filePath: string) {
+    record.add(filePath);
+
+    getDeps(filePath).forEach(key => {
+      if (record.has(key)) {
+        return;
+      }
+
+      search(key);
+      components
+        .filter(item => matchPath(key, item))
+        .forEach(item => {
+          if (!checkList.includes(item) && item !== component) {
+            checkList.push(item);
+          }
+        });
+    });
+  }
+
+  search(componentEntry);
 
   return checkList.filter(checkStyleExists);
 }
@@ -142,28 +95,27 @@ function getSequence(depsMap: DepsMap) {
 
 export async function genStyleDepsMap() {
   return new Promise(resolve => {
+    clearDepsCache();
+
     const map = {} as DepsMap;
 
-    copySync(SRC_DIR, TEMP_DIR);
-    compileTempDir(TEMP_DIR).then(() => {
-      components.filter(checkStyleExists).forEach(component => {
-        map[component] = analyzeDeps(component);
-      });
-
-      const sequence = getSequence(map);
-
-      Object.keys(map).forEach(key => {
-        map[key] = map[key].sort(
-          (a, b) => sequence.indexOf(a) - sequence.indexOf(b)
-        );
-      });
-
-      smartOutputFile(
-        STYPE_DEPS_JSON_FILE,
-        JSON.stringify({ map, sequence }, null, 2)
-      );
-
-      resolve();
+    components.filter(checkStyleExists).forEach(component => {
+      map[component] = analyzeComponentDeps(component);
     });
+
+    const sequence = getSequence(map);
+
+    Object.keys(map).forEach(key => {
+      map[key] = map[key].sort(
+        (a, b) => sequence.indexOf(a) - sequence.indexOf(b)
+      );
+    });
+
+    smartOutputFile(
+      STYPE_DEPS_JSON_FILE,
+      JSON.stringify({ map, sequence }, null, 2)
+    );
+
+    resolve();
   });
 }
diff --git a/packages/vant-cli/src/compiler/get-deps.ts b/packages/vant-cli/src/compiler/get-deps.ts
new file mode 100644
index 000000000..3b49d9e87
--- /dev/null
+++ b/packages/vant-cli/src/compiler/get-deps.ts
@@ -0,0 +1,73 @@
+import { join } from 'path';
+import { SCRIPT_EXTS } from '../common/constant';
+import { readFileSync, existsSync } from 'fs-extra';
+
+let depsMap: Record<string, string[]> = {};
+let existsCache: Record<string, boolean> = {};
+
+// https://regexr.com/47jlq
+const IMPORT_RE = /import\s+?(?:(?:(?:[\w*\s{},]*)\s+from\s+?)|)(?:(?:".*?")|(?:'.*?'))[\s]*?(?:;|$|)/g;
+
+function matchImports(code: string): string[] {
+  return code.match(IMPORT_RE) || [];
+}
+
+function exists(filePath: string) {
+  if (!(filePath in existsCache)) {
+    existsCache[filePath] = existsSync(filePath);
+  }
+
+  return existsCache[filePath];
+}
+
+export function fillExt(filePath: string) {
+  for (let i = 0; i < SCRIPT_EXTS.length; i++) {
+    const completePath = `${filePath}${SCRIPT_EXTS[i]}`;
+    if (exists(completePath)) {
+      return completePath;
+    }
+  }
+
+  for (let i = 0; i < SCRIPT_EXTS.length; i++) {
+    const completePath = `${filePath}/index${SCRIPT_EXTS[i]}`;
+    if (exists(completePath)) {
+      return completePath;
+    }
+  }
+
+  return '';
+}
+
+function getPathByImport(code: string, filePath: string) {
+  const divider = code.includes('"') ? '"' : "'";
+  const relativePath = code.split(divider)[1];
+
+  if (relativePath.includes('.')) {
+    return fillExt(join(filePath, '..', relativePath));
+  }
+
+  return null;
+}
+
+export function clearDepsCache() {
+  depsMap = {};
+  existsCache = {};
+}
+
+export function getDeps(filePath: string) {
+  if (depsMap[filePath]) {
+    return depsMap[filePath];
+  }
+
+  const code = readFileSync(filePath, 'utf-8');
+  const imports = matchImports(code);
+  const paths = imports
+    .map(item => getPathByImport(item, filePath))
+    .filter(item => !!item) as string[];
+
+  depsMap[filePath] = paths;
+
+  paths.forEach(getDeps);
+
+  return paths;
+}
diff --git a/packages/vant-cli/yarn.lock b/packages/vant-cli/yarn.lock
index a99272703..744b7dd88 100644
--- a/packages/vant-cli/yarn.lock
+++ b/packages/vant-cli/yarn.lock
@@ -1252,11 +1252,6 @@
   dependencies:
     "@types/node" "*"
 
-"@types/dependency-tree@^6.1.0":
-  version "6.1.0"
-  resolved "https://registry.yarnpkg.com/@types/dependency-tree/-/dependency-tree-6.1.0.tgz#12d30efd39b6caad29928d7ab3c39149feff09a5"
-  integrity sha512-x9b+ZZ9GSCGJq/0Hza0UMiNyxhUB3O2FOcSIDu95O+tmFQ/AhAY6bMhmktUsnPDOucBlQ6dPLUsdEZoejLNtdg==
-
 "@types/eslint-visitor-keys@^1.0.0":
   version "1.0.0"
   resolved "https://registry.npm.taobao.org/@types/eslint-visitor-keys/download/@types/eslint-visitor-keys-1.0.0.tgz?cache=0&sync_timestamp=1572470950582&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Feslint-visitor-keys%2Fdownload%2F%40types%2Feslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
@@ -1600,7 +1595,7 @@
     "@typescript-eslint/typescript-estree" "2.7.0"
     eslint-visitor-keys "^1.1.0"
 
-"@typescript-eslint/typescript-estree@2.7.0", "@typescript-eslint/typescript-estree@^2.4.0":
+"@typescript-eslint/typescript-estree@2.7.0":
   version "2.7.0"
   resolved "https://registry.npm.taobao.org/@typescript-eslint/typescript-estree/download/@typescript-eslint/typescript-estree-2.7.0.tgz#34fd98c77a07b40d04d5b4203eddd3abeab909f4"
   integrity sha1-NP2Yx3oHtA0E1bQgPt3Tq+q5CfQ=
@@ -2094,11 +2089,6 @@ anymatch@~3.1.1:
     normalize-path "^3.0.0"
     picomatch "^2.0.4"
 
-app-module-path@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.npm.taobao.org/app-module-path/download/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5"
-  integrity sha1-ZBqlXft9am8KgUHEucCqULbCTdU=
-
 aproba@^1.0.3, aproba@^1.1.1:
   version "1.2.0"
   resolved "https://registry.npm.taobao.org/aproba/download/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -2233,16 +2223,6 @@ assign-symbols@^1.0.0:
   resolved "https://registry.npm.taobao.org/assign-symbols/download/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
   integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
 
-ast-module-types@^2.3.1, ast-module-types@^2.3.2, ast-module-types@^2.4.0, ast-module-types@^2.5.0:
-  version "2.5.0"
-  resolved "https://registry.npm.taobao.org/ast-module-types/download/ast-module-types-2.5.0.tgz#44b8bcd51684329a77f2af6b2587df9ea6b4d5ff"
-  integrity sha1-RLi81RaEMpp38q9rJYffnqa01f8=
-
-ast-module-types@^2.6.0:
-  version "2.6.0"
-  resolved "https://registry.npm.taobao.org/ast-module-types/download/ast-module-types-2.6.0.tgz#f9f367fd273bbe01e52f2c51b5f46b65801d5d7f"
-  integrity sha1-+fNn/Sc7vgHlLyxRtfRrZYAdXX8=
-
 astral-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npm.taobao.org/astral-regex/download/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
@@ -3140,7 +3120,7 @@ commander@2.17.x:
   resolved "https://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
   integrity sha1-vXerfebelCBc6sxy8XFtKfIKd78=
 
-commander@^2.13.0, commander@^2.16.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1, commander@~2.20.3:
+commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3:
   version "2.20.3"
   resolved "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=
@@ -3734,16 +3714,6 @@ depd@~1.1.2:
   resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
   integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
 
-dependency-tree@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.npm.taobao.org/dependency-tree/download/dependency-tree-7.1.0.tgz#7110af9a94ded4785c17d69e48b6968c214d9a49"
-  integrity sha1-cRCvmpTe1HhcF9aeSLaWjCFNmkk=
-  dependencies:
-    commander "^2.19.0"
-    debug "^4.1.1"
-    filing-cabinet "^2.3.1"
-    precinct "^6.2.0"
-
 deprecated-obj@1.0.1:
   version "1.0.1"
   resolved "https://registry.npm.taobao.org/deprecated-obj/download/deprecated-obj-1.0.1.tgz#d7051278d2c141dc672ac3410d06642e990003b7"
@@ -3795,83 +3765,6 @@ detect-repo-changelog@1.0.1:
     lodash.find "^4.6.0"
     pify "^2.3.0"
 
-detective-amd@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.npm.taobao.org/detective-amd/download/detective-amd-3.0.0.tgz#40c8e21e229df8bca1ee2d4b952a7b67b01e2a5a"
-  integrity sha1-QMjiHiKd+Lyh7i1LlSp7Z7AeKlo=
-  dependencies:
-    ast-module-types "^2.3.1"
-    escodegen "^1.8.0"
-    get-amd-module-type "^3.0.0"
-    node-source-walk "^4.0.0"
-
-detective-cjs@^3.1.1:
-  version "3.1.1"
-  resolved "https://registry.npm.taobao.org/detective-cjs/download/detective-cjs-3.1.1.tgz#18da3e39a002d2098a1123d45ce1de1b0d9045a0"
-  integrity sha1-GNo+OaAC0gmKESPUXOHeGw2QRaA=
-  dependencies:
-    ast-module-types "^2.4.0"
-    node-source-walk "^4.0.0"
-
-detective-es6@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.npm.taobao.org/detective-es6/download/detective-es6-2.1.0.tgz#7848feaec92279d82f7b3a98d8e1f5d93483a0f7"
-  integrity sha1-eEj+rskiedgvezqY2OH12TSDoPc=
-  dependencies:
-    node-source-walk "^4.0.0"
-
-detective-less@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.npm.taobao.org/detective-less/download/detective-less-1.0.2.tgz#a68af9ca5f69d74b7d0aa190218b211d83b4f7e3"
-  integrity sha1-por5yl9p10t9CqGQIYshHYO09+M=
-  dependencies:
-    debug "^4.0.0"
-    gonzales-pe "^4.2.3"
-    node-source-walk "^4.0.0"
-
-detective-postcss@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.npm.taobao.org/detective-postcss/download/detective-postcss-3.0.1.tgz#511921951f66135e17d0ece2e7604c6e4966c9c6"
-  integrity sha1-URkhlR9mE14X0Ozi52BMbklmycY=
-  dependencies:
-    debug "^4.1.1"
-    is-url "^1.2.4"
-    postcss "^7.0.2"
-    postcss-values-parser "^1.5.0"
-
-detective-sass@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.npm.taobao.org/detective-sass/download/detective-sass-3.0.1.tgz#496b819efd1f5c4dd3f0e19b43a8634bdd6927c4"
-  integrity sha1-SWuBnv0fXE3T8OGbQ6hjS91pJ8Q=
-  dependencies:
-    debug "^4.1.1"
-    gonzales-pe "^4.2.3"
-    node-source-walk "^4.0.0"
-
-detective-scss@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.npm.taobao.org/detective-scss/download/detective-scss-2.0.1.tgz#06f8c21ae6dedad1fccc26d544892d968083eaf8"
-  integrity sha1-BvjCGube2tH8zCbVRIktloCD6vg=
-  dependencies:
-    debug "^4.1.1"
-    gonzales-pe "^4.2.3"
-    node-source-walk "^4.0.0"
-
-detective-stylus@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npm.taobao.org/detective-stylus/download/detective-stylus-1.0.0.tgz#50aee7db8babb990381f010c63fabba5b58e54cd"
-  integrity sha1-UK7n24uruZA4HwEMY/q7pbWOVM0=
-
-detective-typescript@^5.1.1:
-  version "5.7.0"
-  resolved "https://registry.npm.taobao.org/detective-typescript/download/detective-typescript-5.7.0.tgz#513a000e08bcfa0b5656fc7e499a554659b9dda8"
-  integrity sha1-UToADgi8+gtWVvx+SZpVRlm53ag=
-  dependencies:
-    "@typescript-eslint/typescript-estree" "^2.4.0"
-    ast-module-types "^2.5.0"
-    node-source-walk "^4.2.0"
-    typescript "^3.6.4"
-
 diff-sequences@^24.9.0:
   version "24.9.0"
   resolved "https://registry.npm.taobao.org/diff-sequences/download/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
@@ -4192,7 +4085,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
   resolved "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
 
-escodegen@^1.8.0, escodegen@^1.9.1:
+escodegen@^1.9.1:
   version "1.12.0"
   resolved "https://registry.npm.taobao.org/escodegen/download/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541"
   integrity sha1-92Pa+ECvFyuzorbdchnA4X9/9UE=
@@ -4699,11 +4592,6 @@ file-entry-cache@^5.0.1:
   dependencies:
     flat-cache "^2.0.1"
 
-file-exists-dazinatorfork@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.npm.taobao.org/file-exists-dazinatorfork/download/file-exists-dazinatorfork-1.0.2.tgz#cd8d0d85f63e39dc81eceb0b687c44a2cca95c47"
-  integrity sha1-zY0NhfY+OdyB7OsLaHxEosypXEc=
-
 filename-reserved-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npm.taobao.org/filename-reserved-regex/download/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4"
@@ -4726,24 +4614,6 @@ filenamify@^1.0.0:
     strip-outer "^1.0.0"
     trim-repeated "^1.0.0"
 
-filing-cabinet@^2.3.1:
-  version "2.3.3"
-  resolved "https://registry.npm.taobao.org/filing-cabinet/download/filing-cabinet-2.3.3.tgz#77882b25ef0859c321a871b440823bc2ed590995"
-  integrity sha1-d4grJe8IWcMhqHG0QII7wu1ZCZU=
-  dependencies:
-    app-module-path "^2.2.0"
-    commander "^2.13.0"
-    debug "^4.1.1"
-    enhanced-resolve "^4.1.0"
-    is-relative-path "^1.0.2"
-    module-definition "^3.0.0"
-    module-lookup-amd "^6.1.0"
-    resolve "^1.11.1"
-    resolve-dependency-path "^2.0.0"
-    sass-lookup "^3.0.0"
-    stylus-lookup "^3.0.1"
-    typescript "^3.0.3"
-
 fill-range@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
@@ -4805,13 +4675,6 @@ find-up@^3.0.0:
   dependencies:
     locate-path "^3.0.0"
 
-find@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.npm.taobao.org/find/download/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8"
-  integrity sha1-QILo/I2DIPGjgrXk9SG5vFB3XLg=
-  dependencies:
-    traverse-chain "~0.1.0"
-
 flat-cache@^2.0.1:
   version "2.0.1"
   resolved "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
@@ -4833,11 +4696,6 @@ flatted@^2.0.0:
   resolved "https://registry.npm.taobao.org/flatted/download/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08"
   integrity sha1-aeV8qo8OrLwoHS4stFjUb9tEngg=
 
-flatten@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.npm.taobao.org/flatten/download/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b"
-  integrity sha1-wSg6yfJ7Noq8HjbR/3sEUBowNWs=
-
 flush-write-stream@^1.0.0:
   version "1.1.1"
   resolved "https://registry.npm.taobao.org/flush-write-stream/download/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8"
@@ -4981,14 +4839,6 @@ gauge@~2.7.3:
     strip-ansi "^3.0.1"
     wide-align "^1.1.0"
 
-get-amd-module-type@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.npm.taobao.org/get-amd-module-type/download/get-amd-module-type-3.0.0.tgz#bb334662fa04427018c937774570de495845c288"
-  integrity sha1-uzNGYvoEQnAYyTd3RXDeSVhFwog=
-  dependencies:
-    ast-module-types "^2.3.2"
-    node-source-walk "^4.0.0"
-
 get-caller-file@^1.0.1:
   version "1.0.3"
   resolved "https://registry.npm.taobao.org/get-caller-file/download/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
@@ -6083,11 +5933,6 @@ is-regular-file@^1.0.1:
   resolved "https://registry.npm.taobao.org/is-regular-file/download/is-regular-file-1.1.1.tgz#ffcf9cae56ec63bc55b17d6fed1af441986dab66"
   integrity sha1-/8+crlbsY7xVsX1v7Rr0QZhtq2Y=
 
-is-relative-path@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.npm.taobao.org/is-relative-path/download/is-relative-path-1.0.2.tgz#091b46a0d67c1ed0fe85f1f8cfdde006bb251d46"
-  integrity sha1-CRtGoNZ8HtD+hfH4z93gBrslHUY=
-
 is-ssh@^1.3.0:
   version "1.3.1"
   resolved "https://registry.npm.taobao.org/is-ssh/download/is-ssh-1.3.1.tgz#f349a8cadd24e65298037a522cf7520f2e81a0f3"
@@ -6122,11 +5967,6 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0:
   resolved "https://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
 
-is-url@^1.2.4:
-  version "1.2.4"
-  resolved "https://registry.npm.taobao.org/is-url/download/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
-  integrity sha1-BKTfRtKMTP89c9Af8Gq+sxihqlI=
-
 is-whitespace-character@^1.0.0:
   version "1.0.3"
   resolved "https://registry.npm.taobao.org/is-whitespace-character/download/is-whitespace-character-1.0.3.tgz#b3ad9546d916d7d3ffa78204bca0c26b56257fac"
@@ -7493,34 +7333,6 @@ mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1:
   dependencies:
     minimist "0.0.8"
 
-module-definition@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.npm.taobao.org/module-definition/download/module-definition-3.2.0.tgz#a1741d5ddf60d76c60d5b1f41ba8744ba08d3ef4"
-  integrity sha1-oXQdXd9g12xg1bH0G6h0S6CNPvQ=
-  dependencies:
-    ast-module-types "^2.4.0"
-    node-source-walk "^4.0.0"
-
-module-definition@^3.3.0:
-  version "3.3.0"
-  resolved "https://registry.npm.taobao.org/module-definition/download/module-definition-3.3.0.tgz#aae06d68c99c5f93841e59b8a4469b974956d4d4"
-  integrity sha1-quBtaMmcX5OEHlm4pEabl0lW1NQ=
-  dependencies:
-    ast-module-types "^2.6.0"
-    node-source-walk "^4.0.0"
-
-module-lookup-amd@^6.1.0:
-  version "6.2.0"
-  resolved "https://registry.npm.taobao.org/module-lookup-amd/download/module-lookup-amd-6.2.0.tgz#70600008b3f26630fde9ef9ae6165ac69de6ecbb"
-  integrity sha1-cGAACLPyZjD96e+a5hZaxp3m7Ls=
-  dependencies:
-    commander "^2.8.1"
-    debug "^4.1.0"
-    file-exists-dazinatorfork "^1.0.2"
-    find "^0.3.0"
-    requirejs "^2.3.5"
-    requirejs-config-file "^3.1.1"
-
 move-concurrently@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -7714,13 +7526,6 @@ node-releases@^1.1.40:
   dependencies:
     semver "^6.3.0"
 
-node-source-walk@^4.0.0, node-source-walk@^4.2.0:
-  version "4.2.0"
-  resolved "https://registry.npm.taobao.org/node-source-walk/download/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c"
-  integrity sha1-wu/nMeqLqcA8ViqgqdmE5U8nvCw=
-  dependencies:
-    "@babel/parser" "^7.0.0"
-
 nopt@^4.0.1, nopt@~4.0.1:
   version "4.0.1"
   resolved "https://registry.npm.taobao.org/nopt/download/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
@@ -8649,15 +8454,6 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2:
   resolved "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9"
   integrity sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck=
 
-postcss-values-parser@^1.5.0:
-  version "1.5.0"
-  resolved "https://registry.npm.taobao.org/postcss-values-parser/download/postcss-values-parser-1.5.0.tgz#5d9fa63e2bcb0179ce48f3235303765eb89f3047"
-  integrity sha1-XZ+mPivLAXnOSPMjUwN2XrifMEc=
-  dependencies:
-    flatten "^1.0.2"
-    indexes-of "^1.0.1"
-    uniq "^1.0.1"
-
 postcss@7.x.x, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.13, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7:
   version "7.0.21"
   resolved "https://registry.npm.taobao.org/postcss/download/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17"
@@ -8676,25 +8472,6 @@ postcss@^7.0.23:
     source-map "^0.6.1"
     supports-color "^6.1.0"
 
-precinct@^6.2.0:
-  version "6.2.0"
-  resolved "https://registry.npm.taobao.org/precinct/download/precinct-6.2.0.tgz#1755c369316d58ffeed2332a31442d5498f3cc33"
-  integrity sha1-F1XDaTFtWP/u0jMqMUQtVJjzzDM=
-  dependencies:
-    commander "^2.19.0"
-    debug "^4.1.1"
-    detective-amd "^3.0.0"
-    detective-cjs "^3.1.1"
-    detective-es6 "^2.0.0"
-    detective-less "^1.0.2"
-    detective-postcss "^3.0.0"
-    detective-sass "^3.0.0"
-    detective-scss "^2.0.0"
-    detective-stylus "^1.0.0"
-    detective-typescript "^5.1.1"
-    module-definition "^3.3.0"
-    node-source-walk "^4.2.0"
-
 prelude-ls@~1.1.2:
   version "1.1.2"
   resolved "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
@@ -9327,20 +9104,6 @@ require-main-filename@^2.0.0:
   resolved "https://registry.npm.taobao.org/require-main-filename/download/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
   integrity sha1-0LMp7MfMD2Fkn2IhW+aa9UqomJs=
 
-requirejs-config-file@^3.1.1:
-  version "3.1.2"
-  resolved "https://registry.npm.taobao.org/requirejs-config-file/download/requirejs-config-file-3.1.2.tgz#de8c0b3eebdf243511c994a8a24b006f8b825997"
-  integrity sha1-3owLPuvfJDURyZSooksAb4uCWZc=
-  dependencies:
-    esprima "^4.0.0"
-    make-dir "^2.1.0"
-    stringify-object "^3.2.1"
-
-requirejs@^2.3.5:
-  version "2.3.6"
-  resolved "https://registry.npm.taobao.org/requirejs/download/requirejs-2.3.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frequirejs%2Fdownload%2Frequirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9"
-  integrity sha1-5Qk9lgHCgpJRJYwLlEXU0Z+p58k=
-
 requires-port@^1.0.0:
   version "1.0.0"
   resolved "https://registry.npm.taobao.org/requires-port/download/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
@@ -9353,11 +9116,6 @@ resolve-cwd@^2.0.0:
   dependencies:
     resolve-from "^3.0.0"
 
-resolve-dependency-path@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.npm.taobao.org/resolve-dependency-path/download/resolve-dependency-path-2.0.0.tgz#11700e340717b865d216c66cabeb4a2a3c696736"
-  integrity sha1-EXAONAcXuGXSFsZsq+tKKjxpZzY=
-
 resolve-from@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npm.taobao.org/resolve-from/download/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
@@ -9383,7 +9141,7 @@ resolve@1.1.7:
   resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
   integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1:
+resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1:
   version "1.12.0"
   resolved "https://registry.npm.taobao.org/resolve/download/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
   integrity sha1-P8ZEo1yEpIVUYJ/ybsUrZvpXffY=
@@ -9541,13 +9299,6 @@ sass-loader@^8.0.0:
     schema-utils "^2.1.0"
     semver "^6.3.0"
 
-sass-lookup@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.npm.taobao.org/sass-lookup/download/sass-lookup-3.0.0.tgz#3b395fa40569738ce857bc258e04df2617c48cac"
-  integrity sha1-OzlfpAVpc4zoV7wljgTfJhfEjKw=
-  dependencies:
-    commander "^2.16.0"
-
 sass@^1.23.7:
   version "1.23.7"
   resolved "https://registry.npm.taobao.org/sass/download/sass-1.23.7.tgz#090254e006af1219d442f1bff31e139d5e085dff"
@@ -10136,7 +9887,7 @@ stringify-entities@^1.0.1:
     is-alphanumerical "^1.0.0"
     is-hexadecimal "^1.0.0"
 
-stringify-object@^3.2.1, stringify-object@^3.3.0:
+stringify-object@^3.3.0:
   version "3.3.0"
   resolved "https://registry.npm.taobao.org/stringify-object/download/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629"
   integrity sha1-cDBlrvyhkwDTzoivT1s5VtdVZik=
@@ -10373,14 +10124,6 @@ stylelint@^9.10.1:
     svg-tags "^1.0.0"
     table "^5.0.0"
 
-stylus-lookup@^3.0.1:
-  version "3.0.2"
-  resolved "https://registry.npm.taobao.org/stylus-lookup/download/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd"
-  integrity sha1-yeyj/3mWkQIPMLOCJgpnNV/v3d0=
-  dependencies:
-    commander "^2.8.1"
-    debug "^4.1.0"
-
 sugarss@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npm.taobao.org/sugarss/download/sugarss-2.0.0.tgz#ddd76e0124b297d40bf3cca31c8b22ecb43bc61d"
@@ -10641,11 +10384,6 @@ transliteration@^2.1.7:
   dependencies:
     yargs "^14.0.0"
 
-traverse-chain@~0.1.0:
-  version "0.1.0"
-  resolved "https://registry.npm.taobao.org/traverse-chain/download/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
-  integrity sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE=
-
 trim-newlines@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npm.taobao.org/trim-newlines/download/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20"
@@ -10759,7 +10497,7 @@ typedarray@^0.0.6:
   resolved "https://registry.npm.taobao.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@^3.0.3, typescript@^3.6.4, typescript@^3.7.2:
+typescript@^3.7.2:
   version "3.7.2"
   resolved "https://registry.npm.taobao.org/typescript/download/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
   integrity sha1-J+SJuV+lkJRF6f717kjYFpetGPs=
diff --git a/vant.config.js b/vant.config.js
index aa662935a..0a708579f 100644
--- a/vant.config.js
+++ b/vant.config.js
@@ -1,18 +1,3 @@
-const sharedSiteConfig = {
-  title: 'Vant',
-  logo: 'https://img.yzcdn.cn/vant/logo.png',
-  links: [
-    {
-      image: 'https://b.yzcdn.cn/vant/logo/weapp.svg',
-      url: 'vant-weapp'
-    },
-    {
-      image: 'https://b.yzcdn.cn/vant/logo/github.svg',
-      url: 'https://github.com/youzan/vant'
-    }
-  ]
-};
-
 module.exports = {
   title: 'vant',
   build: {
@@ -24,8 +9,19 @@ module.exports = {
     defaultLang: 'en-US',
     locales: {
       'zh-CN': {
-        ...sharedSiteConfig,
+        title: 'Vant',
         description: '轻量、可靠的移动端 Vue 组件库',
+        logo: 'https://img.yzcdn.cn/vant/logo.png',
+        links: [
+          {
+            image: 'https://b.yzcdn.cn/vant/logo/weapp.svg',
+            url: 'vant-weapp'
+          },
+          {
+            image: 'https://b.yzcdn.cn/vant/logo/github.svg',
+            url: 'https://github.com/youzan/vant'
+          }
+        ],
         nav: [
           {
             title: '开发指南',
@@ -351,8 +347,19 @@ module.exports = {
         ]
       },
       'en-US': {
-        ...sharedSiteConfig,
+        title: 'Vant',
         description: 'Mobile UI Components built on Vue',
+        logo: 'https://img.yzcdn.cn/vant/logo.png',
+        links: [
+          {
+            image: 'https://b.yzcdn.cn/vant/logo/weapp.svg',
+            url: 'vant-weapp'
+          },
+          {
+            image: 'https://b.yzcdn.cn/vant/logo/github.svg',
+            url: 'https://github.com/youzan/vant'
+          }
+        ],
         nav: [
           {
             title: 'Essentials',