基於webpack4搭建一個react腳手架

来源:https://www.cnblogs.com/DDante/archive/2018/07/25/9368694.html
-Advertisement-
Play Games

為了實現一個可定製化高的react工程,我們往往會自己搭建一個react工程。所以本文會從零開始搭建一個react腳手架工程。解釋webpack中配置的含義。 基於webpack 4.0 。包含 開發環境配置,生產環境配置,代碼分離,css提取,gzip壓縮,base64載入資源,打包分析,ssh一... ...


目錄

react-sample-javascript

React 16.0 boilerplate with react-router-dom, redux & webpack 4. (for javascript)
github項目地址

項目初始化

統一規範代碼格式

  1. 配置 .editorconfig 使得IDE的方式統一 (見代碼)
  2. 配置 .eslintrc.js 使得代碼規範統一 (見代碼)

    預期功能

  3. 管理資源: 能載入css、sccc、less、以及靜態文件
  4. 管理輸出:將打包後的靜態文件輸出至static目錄下,以各自的文件類型管理
  5. dev:使用source map,方便調試時代碼定位
  6. dev:配置devServer,並配置熱替換,熱載入,自動刷新,自動打開瀏覽器,並預留proxyTable
  7. dev:設置預設打開8080,被占用則尋找下一個空介面
  8. production:代碼分離,打包css文件,css代碼壓縮,js代碼壓縮,輸出到模板html,配置gzip
  9. analysis::使用BundleAnalyzerPlugin 分析打包後的性能

    目錄結構

  • 首先使用npm init 初始化一個包含package.json的根目錄
:.
│  .babelrc             #babel的規則以及插件
│  .editorconfig        #IDE/編輯器相關的配置
│  .eslintignore        #Eslint忽視的目錄
│  .eslintrc.js         #Eslint的規則和插件
│  .gitignore           #Git忽視的目錄
│  .postcssrc.js        #postcss的插件
│  package-lock.json
│  package.json         #項目相關的包
│  README.md
│  yarn.lock
│
├─build                 #webpack相關的配置
│      utils.js         #webpack配置中的通用方法
│      webpack.base.conf.js #webpack的基礎配置
│      webpack.dev.conf.js  #webpack的開發環境配置
│      webpack.prod.conf.js #webpack的生產環境配置
│
└─src                   #主目錄,業務代碼
    │  app.css
    │  App.js
    │  favicon.ico
    │  index.ejs
    │  index.js
    │
    └─assets            #靜態目錄,存放靜態資源
        │  config.json
        │
        └─img
                logo.svg

安裝依賴

  • eslint-loader
  • eslint
  • eslint-config-airbnb
  • eslint-plugin-import
  • eslint-friendly-formatter
  • eslint-plugin-flowtype
  • eslint-plugin-jsx-a11y
  • eslint-plugin-react
  • babel-polyfill
  • webpack
  • jest
  • friendly-errors-webpack-plugin 編譯提示的webpack插件
  • html-webpack-plugin 新建html入口文件的webpack插件
  • copy-webpack-plugin webpack配置合併模塊
  • webpack-merge webpack配置合併模塊
  • webpack-dev-server
  • webpack-bundle-analyzer
  • webpack-cli
  • portfinder 尋找介面的插件
  • extract-text-webpack-plugin
  • node-notifier
  • optimize-css-assets-webpack-plugin
  • autoprefixer
  • mini-css-extract-plugin
  • autoprefixer
  • css-loader
  • less-loader
  • postcss-loader
  • postcss-import
  • postcss-loader
  • style-loader
  • babel-core
  • babel-eslint
  • babel-loader
  • babel-plugin-transform-runtime
  • babel-plugin-import
  • babel-preset-env
  • babel-preset-react
  • babel-polyfill
  • url-loader
  • cross-env
  • file-loader
yarn add eslint eslint-loader eslint-config-airbnb eslint-plugin-import eslint-friendly-formatter eslint-plugin-flowtype eslint-plugin-jsx-a11y eslint-plugin-react babel-polyfill webpack jest webpack-merge copy-webpack-plugin html-webpack-plugin friendly-errors-webpack-plugin webpack-dev-server webpack-bundle-analyzer webpack-cli portfinder extract-text-webpack-plugin node-notifier optimize-css-assets-webpack-plugin autoprefixer mini-css-extract-plugin autoprefixer css-loader less-loader postcss-loader postcss-import postcss-loader style-loader babel-core babel-eslint babel-loader babel-plugin-transform-runtime babel-plugin-import babel-preset-env babel-preset-react babel-polyfill url-loader cross-env file-loader -D

項目配置

webpack 基礎配置

  1. 為了控制開發環境和生產環境,我們可以新建build文件夾。分別書寫開發環境和生產環境的webpack配置文件,這樣也更可以方便我們分別控制生產環境和開發環境。
  2. 為了提高代碼的復用率,也為了區別 基礎配置個性配置 ,可以分別新建webpack.basewebpack.devwebpack.prod三個配置文件。首先配置最基礎的entry(入口)和output(出口)。
module.exports = {
  context: path.resolve(__dirname, '../'),  //絕對路徑。__dirname為當前目錄。
    //基礎目錄用於從配置中解析入口起點。因為webpack配置在build下,所以傳入 '../'
  entry: {
    app: ('./src/index.js') //項目的入口
  },
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
    libraryTarget: 'umd',
  },
}

entry

entry可以分別為字元串、數組和對象。

倘若應用只有一個單一的入口,entry的值可以使用任意類型,不會影響輸出結果。

// entry為字元串
{
    entry: './src/index.js',
    output: {
        path: '/dist',
        filename: 'bundle.js'
    }
}
// 結果會生成 '/dist/bundle.js'
// entry為數組,可以添加多個彼此不互相依賴的文件。結合output.library選項,如果傳入數組,則只導出最後一項。
{
    //如果你在html文件里引入了'bable-polyfill',可以通過數組將它加到bundle.js的最後。
    entry: ['./src/index.js', 'babel-polyfill'] ,
    output:{
        path: '/dist',
        filename: 'bundle.js'
    }
}
// entry為對象,可以將頁面配置為多頁面的而不是SPA,有多個html文件。通過對象告訴webpack為每個入口,成一個bundle文件。
// 多頁面的配置,可能還要藉助於HtmlWebpackPlugin,來指定每個html需要引入的js
{
    entry: {
        index: './src/index.js'
        main: './src/index.js'
        login: './src/login.js'
    }
    output:{
        path: '/dist/pages'
        filename: '[name]-[hash:5].js' //文件名取自'entry'對象的鍵名,為了防止推送代碼後瀏覽器讀緩存,故再生成的文件之後加上hash碼。
    }
}
// 會分別生成index.js,main.js,login.js三個文件

關於 webpack構建多頁面 可以參考這篇文章。不過現在webpack4.x也是一次斷崖式升級,感興趣的同學可以自行搜索。

// entry也可以傳入混合類型
{
    entry:{
        vendor: ['jquery','amap','babel-polyfill'] //也可以藉助CommonsChunkPlugin提取vendor的chunk。
        index: './src/index.js'
    }
    output: {
        path: '/dist'
        filename: '[name]-[hash:5].js'
    }
}

CommonsChunkPlugin在webpack4.0之後移除了,可以使用splitChunksPlugin代替。

可以參閱如下鏈接:optimization.splitChunks


output

output最基礎的兩個配置為 pathfilename

  • path 告訴 webpack的輸出目錄在那裡,一般我們會設置在根目錄的 dist 文件夾;
  • filename 用於指定輸出文件的文件名,如果配置了創建了多個單獨的 chunk 則可以使用[name].[hash] 這種占位符來確保每個文件有唯一的名稱;
  • 另一個常見配置 publicPath 則是用於更加複雜的場景。舉例:在本地時,你可能會使用 ../assets/test.png 這種url來載入圖片。而在生產環境下,你可能會使用CDN或者圖床的地址。那麼就需要配置 publicPath = "http://cdn.example.com/assets/" 來實現生產模式下編譯輸出文件時自動更新url。
 output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash:8].js',
    publicPath: '/',
  },

resolve

resolve常用的兩個配置為 aliasextensions

  • alias 創建import或者require的別名
  • extensins 自動解析文件拓展名,補全文件尾碼
resolve: {
    // 自動解析文件擴展名(補全文件尾碼)(從左->右)
    // import hello from './hello'  (!hello.js? -> !hello.jsx? -> !hello.json)
    extensions: ['.js', '.jsx', '.json'],
    alias: {
      '@': resolve('src')
    }
  },

module

module的選項決定瞭如何處理項目中的不同類型的模塊。其中常用的有 rulesnoParese 兩個配置項。

  • noParese 是為了防止weback解析與所有與rule相匹配的文件。目的是,忽略大型的library可以提高構建性能。
noParse: function(content) {
  return /jquery|lodash/.test(content);
}
  • rules 用於在創建模塊是,匹配規則數組,以確定哪些規則能夠對module應用loader,或者是修改parser。
module: {
    rules: [
    {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        enforce: 'pre',
        use: [{
          loader: 'babel-loader',
        }, {
          loader: 'eslint-loader', // 指定啟用eslint-loader
          options: {
            formatter: require('eslint-friendly-formatter'),
            emitWarning: false
          }
        }]
      },
    {
        test: /\.css$/,
        include: /node_modules/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              plugins: () => [autoprefixer({ browsers: 'last 5 versions' })],
              sourceMap: false,
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: ('assets/img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: ('assets/media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: ('assets/fonts/[name].[hash:7].[ext]')
        }
      }
    ]
    }

例如上述代碼,就使用eslint-lodaerbabel-loader 處理了除了node_modules 以外的 js||jsx。同時配置了,解析圖片、視頻、字體文件等的解析,當rules匹配到的文件時,小於10000 byte 時,採用url-loader解析文件。(因為base64會讓圖片的體積變大,所以當文件較大時,使用base64並不明智)

Webpack開發配置

因為在webpack 4.X 中使用了流行的 ”約定大於配置“ 的做法,所以在新加入配置項 mode ,可以告知webpack使用相應模式的內置優化。

選項 描述
development 會將process.env.NODE_ENV 的值設為 development 。啟用NamedChunksPluginNamedMoudulesPlugin
production 會將process.env.NODE_ENV 的值設為 production 。啟用FlagDependencyUsagePluginFlagIncludedChunksPluginModuleConcatenationPluginNoEmitOnErrorsPluginOccurrenceOrderPluginSideEffectsFlagPluginUglifyJsPlugin

如果我們只設置NODE_ENV,則不會自動設置 mode

在開發時,我們往往希望能看到當前開發的頁面,並且能熱載入。這時,我們可以藉助webpack-dev-server 這個插件,來在項目中起一個應用伺服器。

// package.json
"scripts": {
    "start": "webpack-dev-server --mode development --config build/webpack.dev.conf.js",
}
// 設置當前的mode為development,同樣這個配置也可以寫在webpack.dev.conf.js中。然後使用build目錄下的webpack.dev.conf.js 來配置相關的webpack。
devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: true, //在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
    contentBase: path.resolve(__dirname, '../src'),
    compress: true,
    hot: true, // 熱載入
    inline: true, //自動刷新
    open: true, //自動打開瀏覽器
    host: HOST||'localhost',
    port: PORT,
    overlay: { warnings: false, errors: true }, // 在瀏覽器上全屏顯示編譯的errors或warnings。
    publicPath: '/',
    proxy: {},
    quiet: true, // necessary for FriendlyErrorsPlugin // 終端輸出的只有初始啟動信息。 webpack 的警告和錯誤是不輸出到終端的
    watchOptions: {
      poll: false
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      ...process.env
    }),
    //開啟HMR(熱替換功能,替換更新部分,不重載頁面!)
    new webpack.HotModuleReplacementPlugin(),// HMR shows correct file names in console on update.
    //顯示模塊相對路徑
    new webpack.NamedModulesPlugin(),
    //不顯示錯誤信息
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    ]

其實在開發時,我們可以設置 contentBase: '/src'contentBase 指定了devServer能訪問的資源地址。因為我們開發時,資源大部分都放在src目錄下,所以可以直接指定資源路徑為src目錄。因為我們在webpack基礎配置時,配置了 output 輸出為 dist 目錄,所以我們也可以在devServer里,設置 contentBasedist 目錄。不過此時需要使用copyWebpackPlugin將一些靜態資源複製到 dist 目錄下,手動新建dist目錄,並複製也可以。

另外,當使用 history 路由時,要配置 historyApiFallback = true ,以此讓伺服器放棄路由許可權,交由前端路由。而是用 hash 路由則不需要此配置。

項目進階

生產環境配置

在使用webpack 4.x 的 mode 配置之後,需要我們手動配置的項已經減少了很多,像js代碼壓縮這種工具 UglifyJsPlugin 就已經不用手動去配置。但是像很多前面提到的 代碼分離css代碼提取和壓縮html的生成 以及 複製靜態資源 還需要我們手動配置。

代碼分離

// 設置代碼分離的輸出目錄
output: {
    path: path.resolve(__dirname, '../dist'),
    filename: ('js/[name].[hash:8].js'),
    chunkFilename: ('js/[name]-[id].[hash:8].js')
  },
 // 代碼分離
 optimization: {
    runtimeChunk: {
      name: "manifest"
    },
    splitChunks: {
      chunks: 'all'
    }
  },

可以參閱如下鏈接:optimization.splitChunks


css代碼壓縮

藉助 MiniCssExtractPlugin 來實現壓縮css和提取css。因為 MiniCssExtractPlugin 無法與style-loader 共存,所以我們需要判斷當前環境是生成環境還是開發環境。

我們可以新建一個util.js的文件,在webpack當中一些共用的方法。考慮使用個別配置欄位 extract 來配置使用何種方式來配置css-loader。參見 util.js 代碼。

new MiniCssExtractPlugin({
      filename: 'css/[name].[hash:8].css',
      chunkFilename: 'css/[name]-[id].[hash:8].css',
    }),

生成HTML

使用htmlWebpackPlugin,配合ejs。可以使控制html 的生成。通過配置的方式,生成html。因為 HtmlWebpackPlugin 本身可以解析ejs,所以不需要單獨引入ejs的loader。

new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './src/index.ejs', // 設置目錄
      title: 'React Demo',
      inject: true, // true->'head' || false->'body'
      minify: {
        //刪除Html註釋
        removeComments: true,
        //去除空格
        collapseWhitespace: true,
        //去除屬性引號
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="robots" content="noindex, nofollow">

  <title><%= htmlWebpackPlugin.options.title %></title>
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
  <link rel="icon" href="/favicon.ico" type="image/x-icon">

  <% for (var chunk in htmlWebpackPlugin.files.css) { %>
  <link rel="preload" href="<%= htmlWebpackPlugin.files.css[chunk] %>"  as="style">
  <% } %>
  <% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
  <link rel="preload" href="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>" as="script">
  <% } %>

  <base href="/">
</head>
<body>
<div id="root"></div>
</body>
<style type="text/css">
  body {
    font-family: 'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;
  }
</style>
</html>

複製靜態目錄

將所以可能被請求的靜態文件,分別放在assets目錄下。那麼在打包後,為了保證目錄能正常訪問(不使用CDN等載入靜態資源時),我們可以配置 publicPath = '/' 。然後藉助於 CopyWebpackPlugin 實現資源複製。

new CopyWebpackPlugin([{
      from: './src/assets/',
      to: 'assets'
    }]),

src/assets 複製到 dist/assets 目錄下。


開啟打包分析

藉助插件 BundleAnalyzerPlugin 直接在plugins中創建該插件:

// webpack.prod.conf.js
const BundleAnalyzerPlugin = process.env.NODE_ENV=== 'analysis' ? require('webpack-bundle-analyzer').BundleAnalyzerPlugin:null
process.env.NODE_ENV=== 'analysis' ? new BundleAnalyzerPlugin() : ()=>{}

在package.json 中可做如下配置:

"scripts": {
    "analysis": "cross-env NODE_ENV=analysis webpack -p --mode production --progress --config ./build/webpack.prod.conf.js ",
  },

通過註入環境變數,來控制是否運行打包分析。


ssh部署

打包後的dist文件夾,可以直接藉助 node 的 ssh-node ,直接部署到伺服器指定的目錄下。 ssh-node既支持ssh,也支持密碼登錄。建議可以為在每個項目下,新建一個.ssh文件,存放項目的私鑰。代碼如下:

// usage: https://www.npmjs.com/package/node-ssh
var path, node_ssh, ssh, fs, opn, host

fs = require('fs')
path = require('path')
node_ssh = require('node-ssh')
opn = new require('opn')
ssh = new node_ssh()
host = 'localhost'
var localDir = './dist'
var remoteDir = '/opt/frontend/new'
var removeCommand = 'rm -rf ./*'
var pwdCommand = 'pwd'

ssh.connect({
  host: host,
  username: 'root',
  port: 22,
  // password,
  privateKey: "./.ssh/id_rsa",
})
  .then(function() {
    ssh.execCommand(removeCommand, { cwd:remoteDir }).then(function(result) {
      console.log('STDOUT: ' + result.stdout)
      console.log('STDERR: ' + result.stderr)
      ssh.putDirectory(localDir, remoteDir).then(function() {
        console.log("The File thing is done")
        ssh.dispose()
        opn('http://'+host, {app:['chrome']})
      }, function(error) {
        console.log("Something's wrong")
        console.log(error)
        ssh.dispose()
      })
    })
  })

此時,在命令行直接 node deploy.js 就可以運行以上腳本,我們也可以添加一個build + deploy的script腳本,便於啟動。

"scripts": {
    "depoly": "npm run build && node ./deploy.js",
}

結語

本次從零到一,新建了一個react腳手架。過程中有很多問題,也參考了不少大牛的解釋。代碼里也有諸多問題。還望各位看官,不吝指教。
記得留下你的足跡哦。

參考

參考了vue-cli v2.96的webpack配置。
【翻譯】Webpack——令人困惑的地方
webpack中文文檔


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄 學習Service相關知識點: 1. 概述; 2. Service生命周期; 3. Service的基本用法; 4. 服務。 問:達叔,今日工作累嗎? 答:累啊,那麼問你,你知道Android中的 Service(服務)嗎?~ 問:哥,這麼乾的嗎? 答:呵呵,是的,~ 概述: 在Android ...
  • Objective-C語言是iOS開發的專用語言,雖然現在在逐步被swift語言取代,但是仍可以作為基礎學習,學會Objective-C之後入手swift也是相當快速。今天我來簡談一下關於OC中的類。 如果有過C++,Java基礎的同學就會對類有了初步的瞭解。類,是一個抽象的概念,將一個事物抽象後概 ...
  • 因為自帶的listView不能滿足項目需求,通過實現自己的Adapter去繼承ArrayAdapter 來實現自定義ListView的Item項目。 出現點擊ListView的每一項都不會執行setOnItemClickListener 裡面的onItemClick 方法。 原因是item裡面存在一 ...
  • 1、在android studio 安裝adb wifi插件 2、打開命令行 運行adb tcpip 5555 和 adb connect 192.168.10.163 IP地址查看手機wifi的ip 要求手機和電腦在同一個區域網 3、點擊 運行 >調式- 就可以看到 連接的設備 ...
  • 一.小程式開發的兩種選項 ①小游戲開發:內部對應的入口配置文件為game.json丶game.wxml之類的文件或者項目。 ②小程式開發:內部對應的入口配置文件為app.json丶app.wxml之類的文件或者項目。 小程式: 小游戲: 所以當我們使用小游戲的appid去發佈一個小程式的時候就會出現 ...
  • 淺談自記憶函數 最近閱讀《JavaScript忍者秘籍》看到了一種有趣的函數:自記憶函數。 簡介 何為自記憶函數?書中提到: 記憶化(memoization)是一種構建函數的處理過程,能夠記住上次計算結果 通過這句話可以得出,自記憶函數其實就是能夠記住上次計算結果的函數。在實現中,我們可以這樣進行處 ...
  • 沒學過 css,學過一點點 html,這些天看了一些模板樣式很 nice 的博客,跟大家分享下: 其實只是我的個人看法而已,但是 their 創意和各種特效還是很酷的,雖然這兩天我改的博客模板也就這個樣子,也不知道怎麼透明化,但是改個大體上的模板實際上是不難的。有一個簡書上發佈的圖解操作,我就是從這 ...
  • 1 常用指令 v-if指令 v-show指令 v-else指令 v-for指令 v-bind指令 v-model v-on指令 v-text指令 1.1 v-if是條件渲染指令,它根據表達式的真假來刪除和插入元素,它的基本語法如下: expression是一個返回bool值的表達式,表達式可以是一個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...