diff --git a/build/build-components.js b/build/build-components.js
deleted file mode 100644
index 8ae152d18..000000000
--- a/build/build-components.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Compile components
- */
-const fs = require('fs-extra');
-const path = require('path');
-const babel = require('@babel/core');
-const markdownVetur = require('@vant/markdown-vetur');
-
-const esDir = path.join(__dirname, '../es');
-const libDir = path.join(__dirname, '../lib');
-const srcDir = path.join(__dirname, '../src');
-const veturDir = path.join(__dirname, '../vetur');
-const babelConfig = {
-  configFile: path.join(__dirname, '../babel.config.js')
-};
-
-const scriptRegExp = /\.(js|ts|tsx)$/;
-const isDir = dir => fs.lstatSync(dir).isDirectory();
-const isCode = path => !/(demo|test|\.md)$/.test(path);
-const isScript = path => scriptRegExp.test(path);
-
-function compile(dir) {
-  const files = fs.readdirSync(dir);
-
-  files.forEach(file => {
-    const filePath = path.join(dir, file);
-
-    // remove unnecessary files
-    if (!isCode(file)) {
-      return fs.removeSync(filePath);
-    }
-
-    // scan dir
-    if (isDir(filePath)) {
-      return compile(filePath);
-    }
-
-    // compile js or ts
-    if (isScript(file)) {
-      const { code } = babel.transformFileSync(filePath, babelConfig);
-      fs.removeSync(filePath);
-      fs.outputFileSync(filePath.replace(scriptRegExp, '.js'), code);
-    }
-  });
-}
-
-// clear dir
-fs.emptyDirSync(esDir);
-fs.emptyDirSync(libDir);
-
-// compile es dir
-fs.copySync(srcDir, esDir);
-compile(esDir);
-
-// compile lib dir
-process.env.BABEL_MODULE = 'commonjs';
-fs.copySync(srcDir, libDir);
-compile(libDir);
-
-// generate vetur tags & attributes
-markdownVetur.parseAndWrite({
-  path: srcDir,
-  test: /zh-CN\.md/,
-  tagPrefix: 'van-',
-  outputDir: veturDir
-});
diff --git a/build/build-entry.js b/build/build-entry.js
deleted file mode 100644
index 3462288dd..000000000
--- a/build/build-entry.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const fs = require('fs-extra');
-const path = require('path');
-const Components = require('./get-components')();
-const packageJson = require('../package.json');
-
-const camelizeRE = /-(\w)/g;
-const pascalizeRE = /(\w)(\w*)/g;
-
-function camelize(str) {
-  return str.replace(camelizeRE, (_, c) => c.toUpperCase());
-}
-
-function pascalize(str) {
-  return camelize(str).replace(
-    pascalizeRE,
-    (_, c1, c2) => c1.toUpperCase() + c2
-  );
-}
-
-const version = process.env.VERSION || packageJson.version;
-const tips = '// This file is auto generated by build/build-entry.js';
-
-function buildEntry() {
-  const uninstallComponents = [
-    'Locale',
-    'Lazyload',
-    'Waterfall'
-  ];
-
-  const importList = Components.map(name => `import ${pascalize(name)} from './${name}';`);
-  const exportList = Components.map(name => `${pascalize(name)}`);
-  const installList = exportList.filter(name => !~uninstallComponents.indexOf(pascalize(name)));
-  const content = `${tips}
-import { VueConstructor } from 'vue/types';
-${importList.join('\n')}
-
-declare global {
-  interface Window {
-    Vue?: VueConstructor;
-  }
-}
-
-const version = '${version}';
-const components = [
-  ${installList.join(',\n  ')}
-];
-
-const install = (Vue: VueConstructor) => {
-  components.forEach(Component => {
-    Vue.use(Component);
-  });
-};
-
-/* istanbul ignore if */
-if (typeof window !== 'undefined' && window.Vue) {
-  install(window.Vue);
-}
-
-export {
-  install,
-  version,
-  ${exportList.join(',\n  ')}
-};
-
-export default {
-  install,
-  version
-};
-`;
-
-  fs.writeFileSync(path.join(__dirname, '../src/index.ts'), content);
-}
-
-buildEntry();
diff --git a/build/get-components.js b/build/get-components.js
deleted file mode 100644
index 69ff9d3db..000000000
--- a/build/get-components.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-const EXCLUDES = ['index.ts', 'index.less', 'style', 'mixins', 'utils', '.DS_Store'];
-
-module.exports = function() {
-  const src = path.resolve(__dirname, '../src');
-  const dirs = fs.readdirSync(src);
-  return dirs.filter(dir => !EXCLUDES.includes(dir));
-};
diff --git a/build/release-site.sh b/build/release-site.sh
index 585ac6fa7..95d903b82 100644
--- a/build/release-site.sh
+++ b/build/release-site.sh
@@ -1,7 +1,7 @@
 #!/usr/bin/env sh
 rm -rf docs/dist
 
-npx cross-env NODE_ENV=production webpack --config build/webpack.site.prd.js
+vant-cli build-site
 
 superman-cdn /vant ./docs/dist/*.js
 
diff --git a/build/webpack.base.js b/build/webpack.base.js
deleted file mode 100644
index a8f7a6a27..000000000
--- a/build/webpack.base.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const path = require('path');
-const { VueLoaderPlugin } = require('vue-loader');
-
-module.exports = {
-  mode: 'development',
-  resolve: {
-    extensions: ['.js', '.ts', '.tsx', '.vue', '.less']
-  },
-  module: {
-    rules: [
-      {
-        test: /\.vue$/,
-        use: [
-          {
-            loader: 'vue-loader',
-            options: {
-              compilerOptions: {
-                preserveWhitespace: false
-              }
-            }
-          }
-        ]
-      },
-      {
-        test: /\.(js|ts|tsx)$/,
-        exclude: /node_modules/,
-        use: {
-          loader: 'babel-loader',
-          // enable sub-packages to find babel config
-          options: {
-            rootMode: 'upward'
-          }
-        }
-      },
-      {
-        test: /\.less$/,
-        sideEffects: true,
-        use: [
-          'style-loader',
-          'css-loader',
-          'postcss-loader',
-          {
-            loader: 'less-loader',
-            options: {
-              paths: [path.resolve(__dirname, 'node_modules')]
-            }
-          }
-        ]
-      },
-      {
-        test: /\.md$/,
-        use: ['vue-loader', '@vant/markdown-loader']
-      }
-    ]
-  },
-  plugins: [new VueLoaderPlugin()]
-};
diff --git a/build/webpack.site.dev.js b/build/webpack.site.dev.js
deleted file mode 100644
index c097b13f1..000000000
--- a/build/webpack.site.dev.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const path = require('path');
-const merge = require('webpack-merge');
-const config = require('./webpack.base');
-const HtmlWebpackPlugin = require('html-webpack-plugin');
-
-module.exports = merge(config, {
-  entry: {
-    'vant-docs': './docs/site/desktop/main.js',
-    'vant-mobile': './docs/site/mobile/main.js'
-  },
-  devServer: {
-    open: true,
-    progress: true,
-    host: '0.0.0.0',
-    stats: 'errors-only',
-    disableHostCheck: true,
-  },
-  output: {
-    path: path.join(__dirname, '../docs/dist'),
-    publicPath: '/',
-    chunkFilename: 'async_[name].js'
-  },
-  optimization: {
-    splitChunks: {
-      cacheGroups: {
-        chunks: {
-          chunks: 'all',
-          minChunks: 2,
-          minSize: 0,
-          name: 'chunks'
-        }
-      }
-    }
-  },
-  plugins: [
-    new HtmlWebpackPlugin({
-      chunks: ['chunks', 'vant-docs'],
-      template: path.join(__dirname, '../docs/site/desktop/index.html'),
-      filename: 'index.html'
-    }),
-    new HtmlWebpackPlugin({
-      chunks: ['chunks', 'vant-mobile'],
-      template: path.join(__dirname, '../docs/site/mobile/index.html'),
-      filename: 'mobile.html'
-    })
-  ]
-});
diff --git a/build/webpack.site.prd.js b/build/webpack.site.prd.js
deleted file mode 100644
index 141ab6521..000000000
--- a/build/webpack.site.prd.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const path = require('path');
-const merge = require('webpack-merge');
-const config = require('./webpack.site.dev');
-
-module.exports = merge(config, {
-  mode: 'production',
-  output: {
-    path: path.join(__dirname, '../docs/dist'),
-    publicPath: 'https://b.yzcdn.cn/vant/',
-    filename: '[name].[hash:8].js',
-    chunkFilename: 'async_[name].[chunkhash:8].js'
-  }
-});
diff --git a/package.json b/package.json
index 82e143aef..57f187f9d 100644
--- a/package.json
+++ b/package.json
@@ -14,13 +14,12 @@
   ],
   "scripts": {
     "bootstrap": "yarn || npm i",
-    "dev": "npm run build:entry && webpack-dev-server --config build/webpack.site.dev.js",
+    "dev": "vant-cli dev",
     "lint": "vant-cli lint",
-    "build:entry": "node build/build-entry.js",
-    "build:changelog": "vant-cli changelog ./docs/markdown/changelog.generated.md --tag v2.2.0",
     "test": "vant-cli test",
     "test:watch": "vant-cli test --watch",
     "test:coverage": "open test/coverage/index.html",
+    "changelog": "vant-cli changelog ./docs/changelog.generated.md",
     "release": "vant-cli release",
     "release:site": "sh build/release-site.sh"
   },
@@ -32,11 +31,11 @@
   },
   "lint-staged": {
     "*.{ts,tsx,js,vue}": [
-      "eslint",
+      "eslint --fix",
       "git add"
     ],
     "*.{vue,css,less}": [
-      "stylelint",
+      "stylelint --fix",
       "git add"
     ]
   },