ホームページ ウェブフロントエンド jsチュートリアル Vue-cli コマンドライン ツールについての簡単な説明

Vue-cli コマンドライン ツールについての簡単な説明

May 14, 2018 pm 04:44 PM
vue-cli コマンドライン 道具

Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。vue-webpack-boilerplate,官方定义为:full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction.本文主要介绍了浅谈Vue-cli 命令行工具分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

目录结构:

├── README.md
├── build
│  ├── build.js
│  ├── utils.js
│  ├── vue-loader.conf.js
│  ├── webpack.base.conf.js 
│  ├── webpack.dev.conf.js
│  └── webpack.prod.conf.js
├── config
│  ├── dev.env.js
│  ├── index.js
│  └── prod.env.js
├── index.html
├── package.json
├── src
│  ├── App.vue
│  ├── assets
│  │  └── logo.png
│  ├── components
│  │  └── Hello.vue
│  └── main.js
└── static
ログイン後にコピー

config 环境配置

config 配置文件用来配置 devServer 的相关设定,通过配置 NODE_ENV 来确定使用何种模式(开发、生产、测试或其他)

config
|- index.js #配置文件
|- dev.env.js #开发模式
|- prod.env.js #生产模式
ログイン後にコピー

index.js

'use strict'
const path = require('path');

module.exports = {
 dev: {

  // 路径
  assetsSubDirectory: 'static', // path:用来存放打包后文件的输出目录
  assetsPublicPath: '/', // publicPath:指定资源文件引用的目录
  proxyTable: {}, // 代理示例: proxy: [{context: ["/auth", "/api"],target: "http://localhost:3000",}]

  // 开发服务器变量设置
  host: 'localhost',
  port: 8080,
  autoOpenBrowser: true, // 自动打开浏览器devServer.open
  errorOverlay: true, // 浏览器错误提示 devServer.overlay
  notifyOnErrors: true, // 配合 friendly-errors-webpack-plugin
  poll: true, // 使用文件系统(file system)获取文件改动的通知devServer.watchOptions

  // source map
  cssSourceMap: false, // develop 下不生成 sourceMap
  devtool: 'eval-source-map' // 增强调试 可能的推荐值:eval, eval-source-map(推荐), cheap-eval-source-map, cheap-module-eval-source-map 详细:https://doc.webpack-china.org/configuration/devtool
 },
 build: {
  // index模板文件
  index: path.resolve(__dirname, '../dist/index.html'),

  // 路径
  assetsRoot: path.resolve(__dirname, '../dist'),
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',

  // bundleAnalyzerReport
  bundleAnalyzerReport: process.env.npm_config_report,

  // Gzip
  productionGzip: false, // 默认 false
  productionGzipExtensions: ['js', 'css'],

  // source map
  productionSourceMap: true, // production 下是生成 sourceMap
  devtool: '#source-map' // devtool: 'source-map' ?
 }
}
ログイン後にコピー

dev.env.js

'use strict'
const merge = require('webpack-merge');
const prodEnv = require('./prod.env');

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
});
prod.env.js
'use strict'
module.exports = {
  NODE_ENV: '"production"'
};
ログイン後にコピー

build Webpack配置

build
|- utils.js #代码段
|- webpack.base.conf.js #基础配置文件
|- webpack.dev.conf.js #开发模式配置文件
|- webpack.prod.conf.js #生产模式配置文件
|- build.js #编译入口
ログイン後にコピー

实用代码段 utils.js

const config = require('../config')
const path = require('path')

exports.assetsPath = function (_path) {
  const assetsSubDirectory = process.env.NODE_ENV === 'production'
    ? config.build.assetsSubDirectory // 'static'
    : config.dev.assetsSubDirectory
  return path.posix.join(assetsSubDirectory, _path) // posix方法修正路径
}

exports.cssLoaders = function (options) { // 示例: ({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
 options = options || {};

 // cssLoader
 const cssLoader = {
  loader: 'css-loader',
  options: { sourceMap: options.sourceMap }
 }
 // postcssLoader
 var postcssLoader = {
  loader: 'postcss-loader',
  options: { sourceMap: options.sourceMap }
 }

 // 生成 loader
 function generateLoaders (loader, loaderOptions) {
  const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] // 设置默认loader
  if (loader) {
   loaders.push({
    loader: loader + '-loader',
    options: Object.assign({}, loaderOptions, { // 生成 options 对象
     sourceMap: options.sourceMap
    })
   })
  }

  // 生产模式中提取css
  if (options.extract) { // 如果 options 中的 extract 为 true 配合生产模式
   return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader' // 默认使用 vue-style-loader
   })
  } else {
   return ['vue-style-loader'].concat(loaders)
  }
 }

 return { // 返回各种 loaders 对象
  css: generateLoaders(),
  postcss: generateLoaders(),
  less: generateLoaders('less'), 
  // 示例:[
  // { loader: 'css-loader', options: { sourceMap: true/false } },
  // { loader: 'postcss-loader', options: { sourceMap: true/false } },
  // { loader: 'less-loader', options: { sourceMap: true/false } },
  // ]
  sass: generateLoaders('sass', { indentedSyntax: true }),
  scss: generateLoaders('sass'),
  stylus: generateLoaders('stylus'),
  styl: generateLoaders('stylus')
 }
}

exports.styleLoaders = function (options) {
 const output = [];
 const loaders = exports.cssLoaders(options);
 for (const extension in loaders) {
  const loader = loaders[extension]
  output.push({
    test: new RegExp('\\.' + extension + '$'),
   use: loader
  })
  // 示例:
  // {
  //  test: new RegExp(\\.less$),
  //  use: {
  //   loader: 'less-loader', options: { sourceMap: true/false }
  //  }
  // }
 }
 return output
}

exports.createNotifierCallback = function () { // 配合 friendly-errors-webpack-plugin
 // 基本用法:notifier.notify('message');
 const notifier = require('node-notifier'); // 发送跨平台通知系统

 return (severity, errors) => {
  // 当前设定是只有出现 error 错误时触发 notifier 发送通知
  if (severity !== 'error') { return } // 严重程度可以是 'error' 或 'warning'
  const error = errors[0]

  const filename = error.file && error.file.split('!').pop();
  notifier.notify({
   title: pkg.name,
   message: severity + ': ' + error.name,
   subtitle: filename || ''
   // icon: path.join(__dirname, 'logo.png') // 通知图标
  })
 }
}
ログイン後にコピー

基础配置文件 webpack.base.conf.js

基础的 webpack 配置文件主要根据模式定义了入口出口,以及处理 vue, babel 等的各种模块,是最为基础的部分。其他模式的配置文件以此为基础通过 webpack-merge 合并。

'use strict'
const path = require('path');
const utils = require('./utils');
const config = require('../config');

function resolve(dir) {
 return path.join(__dirname, '..', dir);
}

module.exports = {
 context: path.resolve(__dirname, '../'), // 基础目录
 entry: {
  app: './src/main.js'
 },
 output: {
  path: config.build.assetsRoot, // 默认'../dist'
  filename: '[name].js',
  publicPath: process.env.NODE_ENV === 'production'
  ? config.build.assetsPublicPath // 生产模式publicpath
  : config.dev.assetsPublicPath // 开发模式publicpath
 },
 resolve: { // 解析确定的拓展名,方便模块导入
  extensions: ['.js', '.vue', '.json'], 
  alias: {  // 创建别名
   'vue$': 'vue/dist/vue.esm.js', 
   '@': resolve('src') // 如 '@/components/HelloWorld'
  }
 },
 module: {
  rules: [{
    test: /\.vue$/, // vue 要在babel之前
    loader: 'vue-loader',
    options: vueLoaderConfig //可选项: vue-loader 选项配置
   },{
    test: /\.js$/, // babel
    loader: 'babel-loader',
    include: [resolve('src')]
   },{ // url-loader 文件大小低于指定的限制时,可返回 DataURL,即base64
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, // url-loader 图片
    loader: 'url-loader',
    options: { // 兼容性问题需要将query换成options
     limit: 10000, // 默认无限制
     name: utils.assetsPath('img/[name].[hash:7].[ext]') // hash:7 代表 7 位数的 hash
    }
   },{
    test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, // url-loader 音视频
    loader: 'url-loader',
    options: {
     limit: 10000,
     name: utils.assetsPath('media/[name].[hash:7].[ext]')
    }
   },{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, // url-loader 字体
    loader: 'url-loader',
    options: {
     limit: 10000,
     name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
    }
   }
  ]
 },
 node: { // 是否 polyfill 或 mock
  setImmediate: false,
  dgram: 'empty',
  fs: 'empty',
  net: 'empty',
  tls: 'empty',
  child_process: 'empty'
 }
}
ログイン後にコピー

开发模式配置文件 webpack.dev.conf.js

开发模式的配置文件主要引用了 config 对于 devServer 的设定,对 css 文件的处理,使用 DefinePlugin 判断是否生产环境,以及其他一些插件。

'use strict'
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const portfinder = require('portfinder'); // 自动检索下一个可用端口
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); // 友好提示错误信息

const devWebpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
    // 自动生成了 css, postcss, less 等规则,与自己一个个手写一样,默认包括了 css 和 postcss 规则
  },

  devtool: config.dev.devtool,// 添加元信息(meta info)增强调试

  // devServer 在 /config/index.js 处修改
  devServer: {
    clientLogLevel: 'warning', // console 控制台显示的消息,可能的值有 none, error, warning 或者 info
    historyApiFallback: true, // History API 当遇到 404 响应时会被替代为 index.html
    hot: true, // 模块热替换
    compress: true, // gzip
    host: process.env.HOST || config.dev.host, // process.env 优先
    port: process.env.PORT || config.dev.port, // process.env 优先
    open: config.dev.autoOpenBrowser, // 是否自动打开浏览器
    overlay: config.dev.errorOverlay ? { // warning 和 error 都要显示
      warnings: true,
      errors: true,
    } : false,
    publicPath: config.dev.assetsPublicPath, // 配置publicPath
    proxy: config.dev.proxyTable, // 代理
    quiet: true, // 控制台是否禁止打印警告和错误 若使用 FriendlyErrorsPlugin 此处为 true
    watchOptions: {
      poll: config.dev.poll, // 文件系统检测改动
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': require('../config/dev.env') // 判断生产环境或开发环境
    }),
    new webpack.HotModuleReplacementPlugin(), // 热加载
    new webpack.NamedModulesPlugin(), // 热加载时直接返回更新的文件名,而不是id
    new webpack.NoEmitOnErrorsPlugin(), // 跳过编译时出错的代码并记录下来,主要作用是使编译后运行时的包不出错
    new HtmlWebpackPlugin({ // 该插件可自动生成一个 html5 文件或使用模板文件将编译好的代码注入进去
      filename: 'index.html',
      template: 'index.html',
      inject: true // 可能的选项有 true, 'head', 'body', false
    }),
  ]
})

module.exports = new Promise((resolve, reject) => {
 portfinder.basePort = process.env.PORT || config.dev.port; // 获取当前设定的端口
 portfinder.getPort((err, port) => {
  if (err) { reject(err) } else {
   process.env.PORT = port; // process 公布端口
   devWebpackConfig.devServer.port = port; // 设置 devServer 端口

   devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ // 错误提示插件
    compilationSuccessInfo: {
     messages: [`Your application is running here: http://${config.dev.host}:${port}`],
    },
    onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined
   }))

   resolve(devWebpackConfig);
  }
 })
})
ログイン後にコピー

生产模式配置文件 webpack.prod.conf.js

'use strict'
const path = require('path');
const utils = require('./utils');
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');

const env = process.env.NODE_ENV === 'production'
 ? require('../config/prod.env')
 : require('../config/dev.env')

const webpackConfig = merge(baseWebpackConfig, {
 module: {
  rules: utils.styleLoaders({
   sourceMap: config.build.productionSourceMap, // production 下生成 sourceMap
   extract: true, // util 中 styleLoaders 方法内的 generateLoaders 函数
   usePostCSS: true
  })
 },
 devtool: config.build.productionSourceMap ? config.build.devtool : false,
 output: {
  path: config.build.assetsRoot,
  filename: utils.assetsPath('js/[name].[chunkhash].js'),
  chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
 },
 plugins: [
  new webpack.DefinePlugin({ 'process.env': env }),
  new webpack.optimize.UglifyJsPlugin({ // js 代码压缩还可配置 include, cache 等,也可用 babel-minify
   compress: { warnings: false },
   sourceMap: config.build.productionSourceMap,
   parallel: true // 充分利用多核cpu
  }),
  // 提取 js 文件中的 css
  new ExtractTextPlugin({
   filename: utils.assetsPath('css/[name].[contenthash].css'),
   allChunks: false,
  }),
  // 压缩提取出的css
  new OptimizeCSSPlugin({
   cssProcessorOptions: config.build.productionSourceMap
   ? { safe: true, map: { inline: false } }
   : { safe: true }
  }),
  // 生成 html
  new HtmlWebpackPlugin({
   filename: process.env.NODE_ENV === 'production'
    ? config.build.index
    : 'index.html',
   template: 'index.html',
   inject: true,
   minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
   },
   chunksSortMode: 'dependency' // 按 dependency 的顺序引入
  }),
  new webpack.HashedModuleIdsPlugin(), // 根据模块的相对路径生成一个四位数的 hash 作为模块 id
  new webpack.optimize.ModuleConcatenationPlugin(), // 预编译所有模块到一个闭包中
  // 拆分公共模块
  new webpack.optimize.CommonsChunkPlugin({
   name: 'vendor',
   minChunks: function (module) {
    return (
     module.resource &&
     /\.js$/.test(module.resource) &&
     module.resource.indexOf(
      path.join(__dirname, '../node_modules')
     ) === 0
    )
   }
  }),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'manifest',
   minChunks: Infinity
  }),
  new webpack.optimize.CommonsChunkPlugin({
   name: 'app',
   async: 'vendor-async',
   children: true,
   minChunks: 3
  }),

  // 拷贝静态文档
  new CopyWebpackPlugin([{
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
  }])]
})

if (config.build.productionGzip) { // gzip 压缩
 const CompressionWebpackPlugin = require('compression-webpack-plugin');

 webpackConfig.plugins.push(
  new CompressionWebpackPlugin({
   asset: '[path].gz[query]',
   algorithm: 'gzip',
   test: new RegExp('\\.(' + config.build.productionGzipExtensions.join('|') + ')$'),
   threshold: 10240, // 10kb 以上大小的文件才压缩
   minRatio: 0.8 // 最小比例达到 .8 时才压缩
  })
 )
}

if (config.build.bundleAnalyzerReport) { // 可视化分析包的尺寸
 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}

module.exports = webpackConfig;
ログイン後にコピー

build.js 编译入口

'use strict'

process.env.NODE_ENV = 'production'; // 设置当前环境为生产环境
const ora = require('ora'); //loading...进度条
const rm = require('rimraf'); //删除文件 'rm -rf'
const chalk = require('chalk'); //stdout颜色设置
const webpack = require('webpack');
const path = require('path');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');

const spinner = ora('正在编译...');
spinner.start();

// 清空文件夹
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err;
  // 删除完成回调函数内执行编译
  webpack(webpackConfig, function (err, stats) {
    spinner.stop();
    if (err) throw err;
  
  // 编译完成,输出编译文件
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n');

  //error
  if (stats.hasErrors()) {
    console.log(chalk.red(' 编译失败出现错误.\n'));
    process.exit(1);
  }

  //完成
  console.log(chalk.cyan(' 编译成功.\n'))
  console.log(chalk.yellow(
   ' file:// 无用,需http(s)://.\n'
  ))
 })

})
ログイン後にコピー

相关推荐:

PHP命令行

linux命令行汇总

关于webpack命令行的详细介绍

以上がVue-cli コマンドライン ツールについての簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

フリーマーケットビューイングソフトウェアWebサイトは何ですか?通貨サークルのトップ10の自由市場視聴ソフトウェアのランキング フリーマーケットビューイングソフトウェアWebサイトは何ですか?通貨サークルのトップ10の自由市場視聴ソフトウェアのランキング Apr 22, 2025 am 10:57 AM

通貨サークルの上位3つのトップ10のフリーマーケットビューイングソフトウェアは、OKX、Binance、およびgate.ioです。 1。OKXは、シンプルなインターフェイスとリアルタイムデータを提供し、さまざまなチャートと市場分析をサポートしています。 2。Binanceには強力な機能、正確なデータがあり、あらゆる種類のトレーダーに適しています。 3。Gate.ioは、その安定性と包括性で知られており、長期的および短期投資家に適しています。

信頼性が高く使いやすい仮想通貨交換アプリの推奨 信頼性が高く使いやすい仮想通貨交換アプリの推奨 Apr 22, 2025 pm 01:21 PM

信頼性が高く使いやすい仮想通貨交換アプリは次のとおりです。1。Binance、2。Okx、3。Gate.io、4。Coinbase、5。Kraken、6。HuobiGlobal、7。Bitfinex、8。Kucoin、9。Bittrex、10。Poloniex。これらのプラットフォームは、トランザクションのボリューム、ユーザーエクスペリエンス、セキュリティに最適なものとして選択され、すべてが登録、検証、預金、撤退、および取引操作を提供しています。

通貨サークル市場に関するリアルタイムデータの上位10の無料プラットフォーム推奨事項がリリースされます 通貨サークル市場に関するリアルタイムデータの上位10の無料プラットフォーム推奨事項がリリースされます Apr 22, 2025 am 08:12 AM

初心者に適した暗号通貨データプラットフォームには、Coinmarketcapと非小さいトランペットが含まれます。 1。CoinMarketCapは、初心者と基本的な分析のニーズに合わせて、グローバルなリアルタイム価格、市場価値、取引量のランキングを提供します。 2。小さい引用は、中国のユーザーが低リスクの潜在的なプロジェクトをすばやくスクリーニングするのに適した中国フレンドリーなインターフェイスを提供します。

初心者に適したデジタル通貨取引アプリは何ですか? 1つの記事でコインサークルについて学びます 初心者に適したデジタル通貨取引アプリは何ですか? 1つの記事でコインサークルについて学びます Apr 22, 2025 am 08:45 AM

初心者に適したデジタル通貨取引プラットフォームを選択する場合、セキュリティ、使いやすさ、教育リソース、コストの透明性を考慮する必要があります。 2。シンプルなインターフェイスとクリア操作を備えたアプリは、初心者により適しています。 3.プラットフォームは、チュートリアルや市場分析などの学習ツールを提供する必要があります。 4.取引手数料や現金引き出し料などの隠れた費用に注意してください。

ミームコイン交換ランキングミームコインメインエクスチェンジトップ10スポット ミームコイン交換ランキングミームコインメインエクスチェンジトップ10スポット Apr 22, 2025 am 09:57 AM

ミームコインを取引するのに最も適したプラットフォームには、次のものがあります。1。Binance、世界最大、高流動性と低いハンドリング料金があります。 2。OKX、効率的な取引エンジンであり、さまざまなミームコインをサポートしています。 3。Xbit、分散型、クロスチェーン取引をサポートする。 4。Redim(Solana Dex)、低コスト、血清注文帳。 5。PancakesWap(BSC DEX)、低い取引手数料、高速。 6。ORCA(Solana Dex)、ユーザーエクスペリエンスの最適化。 7。コインベース、高セキュリティ、初心者に適しています。 8。アジアで有名なHuobi、豊かな取引ペア。 9。デクスラビット、インテリジェント

通貨サークル2025の上位10の市場Webサイトのヒントと推奨事項 通貨サークル2025の上位10の市場Webサイトのヒントと推奨事項 Apr 22, 2025 am 08:03 AM

国内のユーザー適応ソリューションには、コンプライアンスチャネルとローカリゼーションツールが含まれます。 1。コンプライアンスチャネル:サークルトレードなどのOTCプラットフォームを介したフランチャイズ通貨交換、国内では、香港や海外のプラットフォームを通過する必要があります。 2。ローカリゼーションツール:Currency Circleネットワークを使用して中国の情報を取得し、Huobi Global Stationはメタユニバース取引端末を提供します。

2025年のデジタル通貨取引プラットフォームは何ですか?トップ10のデジタル通貨アプリの最新のランキング 2025年のデジタル通貨取引プラットフォームは何ですか?トップ10のデジタル通貨アプリの最新のランキング Apr 22, 2025 pm 03:09 PM

上位10の仮想通貨視聴プラットフォームの推奨アプリ:1。OKX、2。BINANCE、3。GATE.IO、4。HUOBI、5。COINBASE、6。KRAKEN、7。BITFINEX、8。KUCOIN、9。BYBIT、10。

トップ10のデジタル仮想通貨アプリのランキング:通貨サークル取引におけるトップ10のデジタル通貨交換 トップ10のデジタル仮想通貨アプリのランキング:通貨サークル取引におけるトップ10のデジタル通貨交換 Apr 22, 2025 pm 03:00 PM

上位10のデジタル仮想通貨アプリは次のとおりです。1。Okx、2。Binance、3。Gate.io、4。Coinbase、5。Kraken、6。Huobi、7。Kucoin、8。Bitfinex、9。Bitstamp、10。Poloniex。これらの交換は、トランザクションのボリューム、ユーザーエクスペリエンス、セキュリティなどの要因に基づいて選択され、すべてがさまざまなデジタル通貨取引サービスと効率的な取引エクスペリエンスを提供します。

See all articles