1. 程式人生 > >webpack4介紹與總結

webpack4介紹與總結

webpack是目前最火的打包工具,本文以最新的webpack4為背景,從概念方面介紹webpack是什麼、能給我們帶來什麼好處以及如何配置。

由於web應用擴充套件地得極其迅猛,前端技術也是日新月異,前端的苦不是有多難學,而是我剛學完,這東西就被淘汰了(手動哭臉)。框架方面我們有vue、react、angular,我們需要寫vue單檔案,也需要寫jsx語法;js方面我們有Typescript、es6(7、8、9),現在是每年一個小版本的迭代,語法也是在不斷更新和淘汰;模組方面我們有es6的modlue、CommonJS、AMD;css方面我們有sass、less、postcss。新技術層出不窮,瀏覽器實現跟不上,還要考慮到瀏覽器相容性問題,是一個令人頭大的問題。但是webpack可以輕鬆幫我們解決這些問題,我們可以在webpack的世界中放心地使用上述提到的技術,以更方便、舒服的方式完成我們開發。

webpack是什麼

At its core, webpack is a static module bundler for modern JavaScript applications.這是官網的定義,webpack就是一個靜態模組的打包工具。webpack可以將工程中的靜態資源根據我們宣告的依賴關係,打包出最後的正常執行的輸出檔案。官網顯示的這幅圖很形象地描述了這個過程:

打包過程

在webpack中,所有的靜態資源都可以被處理為一個模組,包括js、圖片、css、字型。模組化是前端開發的主要模式,模組化的好處有很多,我想到的有以下3種:

  • 更輕鬆地拆分程式碼邏輯,對於大型工程尤其重要
  • 更容易地去管理變數,模組會自動生成一個區域性變數環境,減少全域性變數的汙染
  • 顯示地宣告依賴關係,想想之前在head中引入很多script標籤,由於script順序錯誤而引起的bug

在es6之前,原生js是不支援模組化開發。因為js設計之初,只是為了實現表單驗證等簡單的互動,並沒有考慮到要用js來寫大型的web應用。隨著js承擔地職責越來越大,模組化開發的需求越來越急迫。於是,js社群誕生出了CommonJS、AMD這樣的js模組化標準,隨後在es6中,也終於加入了module的原生支援。現在最新版本的各大瀏覽器均已實現了對es6的module語法支援,但也僅限於最新的幾個版本,詳情可以檢視一下

can i ues。我們可以把webpack當成是模組化標準的實現方案,但webpack的功能不僅限於此。

webpack支援多種模組使用方式,包括es6的module、CommonJS、AMD。推薦使用es6的module語法,一方面是因為它是標準,是以後模組化語法的主要使用方式;另一方面,是因為它是靜態的,webpack可以依靠靜態分析,做一些優化,比如Treeshaking。webpack自帶js模組處理功能,其他型別的靜態資源我們需要通過配置相應的loader去處理。

概念和配置

webpack中最重要的概念有以下幾個:

  • Entry, 工程的入口檔案配置
  • Output, 打包的輸出的檔案配置
  • Chunk, webpack處理和輸出的包
  • Loaders, 載入器,用於處理各種不同型別的模組,可擴充套件
  • Plugins, 外掛,在webpack打包過程中不同時機執行一些任務,比如清除打包目錄、複製靜態檔案、抽取css檔案
  • Mode, 區分開發環境和生成環境

webpack一般根據配置檔案去執行打包任務,我們建立一個webpack.config.js檔案來編寫我們的打包配置。

Entry

Entry,顧名思義就是工程的入口檔案,Entry的配置寫法有三種:

  • 物件,可配置多入口,可配置chunk名,靈活可擴充套件,最常用,一個屬性就是一個entry chunk
module.exports = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};
複製程式碼
  • 字串, 最簡單直接方式,單入口,chunk名預設為main
module.exports = {
  entry: './path/to/my/entry/file.js'
};
複製程式碼
  • 陣列, 多入口,將多個入口檔案打包為一個chunk,chunk名預設為main
module.exports = {
  entry: ['./path/to/my/entry/file.js', './path/to/my/entry/file1.js']
};
複製程式碼

入口一般用物件寫法即可,其他兩種寫法的可忽略。

Output

Output用於配置打包輸出的檔案,包括輸出檔案的檔名、輸出路徑、靜態資源地址,這裡列出最常用的4種:

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: 'js/[name].js',
    chunkFilename: 'js/[name].js',
    path: __dirname + '/dist',
    publicPath: 'http://cdn.example.com/assets/[hash]/'
  }
};
複製程式碼

配置項如下:

  • filename: 配置輸出檔名,可新增路徑配置(例子中js/),可使用佔位符,佔位符有以下5種:

    • name: chunk名,在該例子中就是app和search
    • hash: 模組識別符號的hash值,跟工程內容相關
    • chunkhash: chunk內容的hash值,只和當前chunk內容相關,可用於快取設定
    • id: 模組識別符號
    • query:模組查詢引數,取檔名中?後面的內容
  • path: 檔案的輸出路徑,必須是絕對地址

  • publicPath: 用於設定打包過程中產生的靜態檔案的最終引用地址,靜態檔案的最終引用地址為output.publicPath + output.filename,很多時候,你的靜態檔案放置在CDN上,通過publicPath就可以很方便地設定。如果你的靜態引用地址在執行時才能確定,可以在入口檔案中設定__webpack_public_path__來決定publicPath的值:

    __webpack_public_path__ = myRuntimePublicPath;
    
    // rest of your application entry
    複製程式碼
  • chunkFilename: 用於設定非entry入口的chunk的輸出檔名,非entry入口的chunk一般在動態引入和CommonsChunkPlugin中產生,這是一個Plugin,用於抽取公共程式碼或者進行程式碼分割等操作,該plugin已經在webpack4中廢除,由webpac4內建的optimization.splitChunks替代,後面會講到

output還有其他很多配置,這4個是常用配置。

Loaders

Loaders可以理解為不同型別模組的處理器,將這些型別的模組處理為瀏覽器可執行和識別的程式碼。比如babel-loader將es6以上程式碼轉換為es5程式碼;sass-loader將sass程式碼解析為css程式碼;url-loader和file-loader可以將圖片、字型等靜態檔案解析為base64碼或者靜態檔案地址。Loaders給我們提供了處理模組的入口,在裡面可以使用全部的js功能,從而使webpack具有了強大而靈活的能力。webpack及webpack社群提供了功能強大的loader供開發者使用,你也可以自己編寫loader。下面介紹一下在工程中常用的loader。

js Loaders

babel-loader

使用babel將ES2015+的程式碼轉碼為ES5的程式碼,babel的具體配置可參考babel官網

modlue: {
    rules: [
        {
             test: /\.js$/,
             exclude: /(node_modules|bower_components)/,
             use: 'babel-loader
        }
    ]
}
複製程式碼

exclude表示不處理的目錄,一般node_modules中的第三方js檔案不在我們的處理範圍內。

script-loader

該loader使對應的js檔案在全域性環境中執行一次。比如我們在工程中使用了jquery的外掛,需要全域性暴露,我們就需要讓jquery檔案在全域性環境中執行,以便讓它把掛載到全域性變數中,效果和在瀏覽器中加script標籤一樣。

import 'jquery';

module: {
    rules: [
        {
        test: /jquery$/,
        use: [ 'script-loader' ]
        }
    ]
}
複製程式碼

css Loaders

  • style-loader:將css模組以style標籤的形式加入到html中

  • css-loader:主要用來解析css中的靜態資源,將@import和url()解析為import/require(),解析出的除css以外的靜態資源,一般交給url-loader和file-loader去處理

  • postcss-loader:可以對css進行各種處理,功能強大,比如自動新增css字首,也可自定義外掛

  • sass-loader/less-loader:將sass/less程式碼轉換為css

解析一個sass檔案,並不只需要一個loader,它需要多個loader序列處理,webpack可以配置多個loader序列處理:

module: {
    rules: [
        {
        test: /\.sass$/,
        use: [ 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' ]
        }
    ]
}
複製程式碼

我們可以將use配置為一個數組,loader從右往左依次執行,且前一個loader的結果是下一個loader的輸入。最後一個loader的輸出就是我們最終要的結果。一個sass檔案首先經過sass-loader處理,變成css檔案,又經過postcss-loader處理,新增瀏覽器字首等功能,接著交給css-loader去解析css檔案引用的靜態變數,最後由style-loaderscript標籤的形式加入到html中。

Files Loaders

url-loaderfile-loader是一對用來處理圖片、svg、視訊、字型等靜態資原始檔的loader。一般體積比較小的資源交給url-loader處理,編碼為base64字串,直接嵌入js檔案中。體積較大的檔案由file-loader處理,直接釋放為了一個輸出檔案。

{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 10000,
        name: 'img/[name].[hash:7].[ext]'
    }
},
複製程式碼

一般只配置url-loader即可,在資源超過limit的時候,url-loader會將資源自動交給file-loader處理,並將options內容也傳遞給file-loader。

Plugins

loaders用來轉換某種特定型別的module,plugins則用來在一些合適的時機執行一些特定的任務,比如程式碼分割、靜態資源處理、環境變數的注入、將所有css的module抽取為單個檔案等。webpack自身也是用外掛系統構建起來的。外掛的目的是做任何loaders做不了的事情。

HtmlWebpackPlugin

HtmlWebpackPlugin外掛可以用來生成包含你所有打包檔案(js和css)的html檔案,特別是你在打包檔名配置了hash,就不得不用這個外掛了。

module.exports = {
  plugins: [
      new HtmlWebpackPlugin({
          template: path.resolve(__dirname, 'src/index.html'),  
          filename: 'static/index.[hash].html',  
          inject: true, 
          minify: false, 
          chunks: ['app', 'vendor'] 
      })
  ]
};
複製程式碼
  • template: HtmlWebpackPlugin生成html檔案的模板,如果簡單的話可以直接通過其他配置項生成,不必單獨提供一個html檔案模板,詳情可參考HtmlWebpackPlugin
  • filename: 輸出的html檔名,規則和output的filename相同
  • inject: 是否注入打包的檔案,包括js和通過MiniCssExtractPlugin打包輸出的css檔案,預設為true
  • minify: 是否壓縮
  • chunks: 只注入某些特定chunk的輸出檔案,在多檔案場景下比較有用

MiniCssExtractPlugin

MiniCssExtractPlugin將一個chunk中的css抽取為一個單獨的css檔案,如果chunk中不包含css,則不生成檔案。且支援按需載入和sourceMap。webpack4新增外掛,在webpack4之前是使用ExtractTextWebpackPlugin來做這件事。官方文件總結了MiniCssExtractPlugin相對ExtractTextWebpackPlugin的四個優勢:

  • 按需非同步載入
  • 沒有重複編譯(效能)
  • 使用更簡單
  • 專門為css設計
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          devMode ? 'style-loader' : {  // MiniCssExtractPlugin目前還沒有HMR功能,所以最好只在生成環境使用
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../' // 可單獨配置publicPath,預設採用output中的publicPath
            }
          },
          "css-loader"
        ]
      }
    ]
  }
}
複製程式碼

CopyWebpackPlugin

CopyWebpackPlugin用來處理靜態檔案,可以將檔案或者資料夾原封不動地移動到打包目錄。

const CopyWebpackPlugin = require('copy-webpack-plugin')

const config = {
  plugins: [
    new CopyWebpackPlugin([
        { from: 'source', to: 'dest' },
        { from: 'source', to: 'dest', toType: 'dir|file|template' }, // 手動設定to的型別,比如設定成dir,即使to設定為a.js,最後也會生成a.js資料夾
        { from: 'source', to: 'dest', context: '/app' }, // 基準目錄,from相對於context解析
        { from: 'source', to: 'dest', ignore: ['*.js'] }, // ignore, 忽略匹配的檔案
        'source' // 只有from,to預設為output的path
     ], {
         context: '/app', // 同上
         ignore: ['*.js'], // 同上
     })
  ]
}
複製程式碼

CleanWebpackPlugin

CleanWebpackPlugin用來清除打包目錄,主要用於每次重新生成的時候,清除殘留檔案。在檔案有hash值的情況下,是必要的。

const CleanWebpackPlugin = require('clean-webpack-plugin');
const config = {
  plugins: [
    new CleanWebpackPlugin(['dist', 'bulid/*.js'], {
        watch: false, // 是否在--watch模式下也清除files然後重新編譯,預設為false
        exclude: [ 'files', 'svg', 'css' ] // 不刪除的子目錄和檔案
    }),
  ]
}
複製程式碼

DefinePlugin

DefinePlugin用來定義webpack編譯期間的全域性變數。我們可以根據這些變數,來做不同的動作。最典型的就是可以區分開發環境和生產環境,比如在開發環境列印各種警告、錯誤,在生產環境去掉這些跟業務無關的程式碼。

DefinePlugin的引數是一個物件,鍵名是一個識別符號,或者用.隔開的多級識別符號,引數遵循以下規則

  • 如果引數值是一個字串,則被當做程式碼塊
  • 如果引數值不是字串,則會自動轉換為字串
  • 如果引數值是一個物件,則物件的每個值都按照上述規則被定義為全域性變數
  • 如果鍵名前面有typeof,則只是定義typeof的呼叫
new webpack.DefinePlugin({
 'process.env.NODE_ENV': JSON.stringify('production'),
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify('5fa3b9'),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: '1+1',
  'typeof window': JSON.stringify('object')
});
複製程式碼

index.js

console.log('PRODUCTION', PRODUCTION);
console.log('VERSION', VERSION);
console.log('BROWSER_SUPPORTS_HTML5', BROWSER_SUPPORTS_HTML5);
console.log('TWO', TWO);
console.log('Object', typeof window);
複製程式碼

被編譯為

console.log('PRODUCTION', true);
console.log('VERSION', "5fa3b9");
console.log('BROWSER_SUPPORTS_HTML5', true);
console.log('TWO', 1+1);
console.log('Object',  false ? undefined : _typeof(window));    // 不太明白
複製程式碼

DefinePlugin的原理很簡單,只是在編譯過程中遇到這些定義好的鍵名,就用鍵值做簡單的文字替換。所以,你如果想給全域性變數賦一個字串,需要這樣寫'"production"',一般使用JSON.stringify來轉一下。

Mode

webpack4新增了mode配置。webpack會根據mode值自動幫你做一個不同的優化:

  • production(預設值)

    • DefinePlugin中將process.env.NODE_ENV設定為production
    • 預設啟用瞭如下外掛:FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin and UglifyJsPlugin
  • development:

    • DefinePlugin中將process.env.NODE_ENV設定為development
    • 預設啟用瞭如下外掛:NamedChunksPlugin, NamedModulesPlugin
  • none: 什麼都不做

mode的兩種使用方式

  • 配置:
module.exports = {
  mode: 'production'
};
複製程式碼
  • 命令列:
webpack --mode=production
複製程式碼

程式碼分割

程式碼分割可以把程式碼按照一定的邏輯分割,用來做按需載入或者並行載入,以減少載入時間。在webpack中,主要有以下3中方式,實現程式碼分割:

  • Entry Points: 手動在entry入口配置處配置多個入口
  • SplitChunks: webpack4預設帶這個優化外掛,用於抽取不同chunk的公共部分,或者直接程式碼分割
  • Dynamic Imports: 動態載入,在函式中使用import()語法,webpack使用SplitChunksimport()載入的module分割為一個單獨的chunk,並在函式執行時載入該chunk對應的js檔案。

第一種沒什麼好說的,主要說一下後兩種。

SplitChunks

在webpack4之前的版本,都是使用CommonsChunkPlugin來抽取公共chunk,在webpack4中廢棄了CommonsChunkPlugin,轉而支援內建的optimization.splitChunks

splitChunks預設只對按需載入的chunk起作用,會自動將import()引入的module分割為單獨chunk,但是需要滿足以下條件:

  • 新chunk中的模組被共享或者來自node_modules
  • 新chunk必須大於30kb(before min+gz)
  • 按需載入的chunks並行載入的數量要小於等於5
  • 入口檔案的並行載入的請求應該小於等於3

在執行後兩個原則的時候,體積大的chunk被優先生成。

splitChunks的預設配置如下,我們可以看出正好是和上面4個條件對應的:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000, // chunk只有超過這個大小才會被分割
      maxSize: 0, // 大於這個體積的chunk會被自動分割為更小的chunk
      minChunks: 1, // 一個模組被共享的chunk數量大於minChunks時,才會被分割出來
      maxAsyncRequests: 5, // 按需載入最大的並行數
      maxInitialRequests: 3, // 初始載入最大的並行數
      automaticNameDelimiter: '~', // name為true時,新chunk的檔名由cacheGroups的key加上chunks屬性的一些資訊生成,automaticNameDelimiter是分隔符
      name: true,
      cacheGroups: {  // 配置拆分規則,會繼承splitChunks所有的配置項,所有splitChunks配置項都可以在這裡重寫覆蓋,test、prioprity、reuseExistingChunk是cacheGroups獨有的屬性
        vendors: {
          test: /[\\/]node_modules[\\/]/, // 模組匹配規則,可以是正則表示式或者函式,不寫預設選擇所有模組
          priority: -10 // 優先順序,當同一個模組同時包含在不同cacheGroup中,該模組將被劃分到優先順序高的組中
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true  // 如果該chunk包含的modules都已經另一個被分割的chunk中存在,那麼直接引用已存在的chunk,不會再重新產生一個
        }
      }
    }
  }
};
複製程式碼

chunks

splitChunks的chunks屬性表示作用的chunk範圍。chunks可以是一個函式,完全由開發者控制;也可以是一個字串,字串一共有3個值:

  • initial,表示只作用於入口chunk
  • async,表示只作用於動態引入的非同步chunk
  • all,所有chunk

name

name屬性表示最後生成chunk的檔名,有以下3中型別取值:

  • boolean,設定為true,則會根據cacheGroup的key和chunks屬性的資訊自動生成
  • string,如果設定在splitChunks下,那所有chunk設定為相同的名稱,這會造成不同的chunk合成為一個chunk,當然你可以設定在cacheGroup
  • function,完全由開發者控制

Tree Shaking

Tree Shaking這次詞很形象,搖樹,把爛掉的樹葉搖下來。我們工程中的爛樹葉就是那些我們匯出了,但是沒有用到的程式碼,Tree Shaking可以幫助我們去除無效程式碼,減小打包體積,有其在大工程中,效果明顯。

Tree Shaking的使用三部曲:

靜態的模組語法

使用Tree Shaking的第一個前提條件就是必須使用ES2015的模組語法,import,export。因為ES2015的模組語法是靜態載入的,而CommonJS和AMD都是動態載入靜態載入是指在編譯階段你就能確定匯出和載入的內容。ES2015在語法上規定:你只能在頂層模組作用域進行匯入匯出操作,不允許在條件語句中匯入匯出,也不允許匯入和匯出的內容有變數。這意味著你只分析原始碼就可以確定匯入和匯出的內容,而不是等到執行時才能確定。比如說下面CommonJS的語法,在ES6中就是不能使用的:

var my_lib;
if (Math.random()) {
    my_lib = require('foo');
} else {
    my_lib = require('bar');
}
複製程式碼

你只有在執行的時候,才知道到底載入是的foo還是bar。ES6強制模組語法靜態化,失去了一定的靈活性,但是帶來了更多的好處,其中之一就是我們可以通過靜態分析去實現Tree Shaking。

sideEffects

在完全的Es6模組世界中,程式碼是沒有副作用的,但是現在我們可能用到的各種地方庫會有副作用。副作用是指程式碼除了匯入和匯出,還做了一些其他影響了其他程式碼的行為,比如定義了全域性變數。最典型的例子就是polyfills,比如Promise的polyfills就定義了Promise全域性變數。這時候如果我們分析到Promise有未使用的匯出程式碼,則不能刪除,否則可能會影響Promise的使用。哪些是有副作用的程式碼,需要你識別,並且告訴webpack,方式就是通過設定sideEffects,可以設定在package.json檔案中,也可以設定的module.rules中。

{
  "name": "your-project",
  "sideEffects": [
    "./src/some-side-effectful-file.js",
    "*.css"
  ]
}
複製程式碼

UglifyJSPlugin

webpack會通過靜態分析找到冗餘程式碼,並打上標記,我們看一下官網例子:

math.js

export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}
複製程式碼

index.js

 import { cube } from './math.js';

  function component() {
   var element = document.createElement('pre');

   element.innerHTML = [
     'Hello webpack!',
     '5 cubed is equal to ' + cube(5)
   ].join('\n\n');

    return element;
  }

  document.body.appendChild(component());
複製程式碼

development模式下打包,內容如下:

/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
  'use strict';
  /* unused harmony export square */
  /* harmony export (immutable) */ __webpack_exports__['a'] = cube;
  function square(x) {
    return x * x;
  }

  function cube(x) {
    return x * x * x;
  }
});
複製程式碼

我們可以看到程式碼中並未用到math.js中的square方法,webpack輸出檔案中表示它未被使用。如果想去掉未被使用的程式碼,則需要用到UglifyJSPlugin外掛,它是用來壓縮js檔案的,自動啟用了去除冗餘程式碼的功能。我們可以在production模式下打包,會發現square的程式碼已經被去除。

部落格地址


作者:輝衛無敵
連結:https://juejin.im/post/5b66f1256fb9a04f8e144db1
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

相關推薦

webpack4介紹總結

webpack是目前最火的打包工具,本文以最新的webpack4為背景,從概念方面介紹webpack是什麼、能給我們帶來什麼好處以及如何配置。 由於web應用擴充套件地得極其迅猛,前端技術也是日新月異,前端的苦不是有多難學,而是我剛學完,這東西就被淘汰了(手動哭臉)。框架方

介紹總結

自由 上進 工作 職業方向 pytho 崗位 sql 過去的 碼農 自我介紹 211606349;我是倔強的蔡晨旸;我的愛好是聽音樂;我最喜歡的是麻辣香鍋(四堂);堅持,不放棄才會贏。 (1)回想一下你初入大學時對本專業的暢想。 1.當初你是如何做出選擇軟件工程專業的決定的

AVL樹演算法介紹總結

在電腦科學中,AVL樹是最先發明的自平衡二叉查詢樹。在AVL樹中任何節點的兩個子樹的高度最大差別為一,所以它也被稱為高度平衡樹。查詢、插入和刪除在平均和最壞情況下都是O(log n)。增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。AVL樹得名於它的發明者 G.M. Adelson-Velsky 和

差分拘束介紹總結例題

end push 規模 mem 矛盾 需要 vector -c swap 差分約束的具體概念: 如果一個系統由n個變量和m個約束條件組成,形成m個形如ai-aj≤k的不等式(i,j∈[1,n],k為常數),則稱其為差分約束系統。 例子: 假設有3個數a,b,c 我們知道:

Android通知欄介紹適配總結(上篇)

此文已由作者黎星授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 由於歷史原因,Android在釋出之初對通知欄Notification的設計相當簡單,而如今面對各式各樣的通知欄玩法,谷歌也不得不對其進行更新迭代調整,增加新功能的同時,也在不斷地改變樣式,試圖迎合更多

android開發框架總結 (二)MVPMVVM詳細介紹對比,如何選擇適合的框架(乾貨!)

前言 本篇文章將非常“細緻”地總結分析MVP與MVVM這兩種框架對於架構的選擇做了比較多的分析,應該是乾貨滿滿,如果你對這兩者的使用與選擇上還有迷惑之處。真的希望你能認真看完。 如果你是非常有經驗的程式猿,那就當相互學習總結,如果有不同看法還望指教。當然,我也是非常想進步的。  

ElasticSearch學習總結(二):ES介紹架構說明

本文主要從概念以及架構層面對Elasticsearch做一個簡單的介紹,在介紹ES之前,會先對ES的“發動機”Lucene做一個簡單的介紹 1. Lucene介紹 為了更深入地理解ElasticSearch的工作原理,特別是索引和查詢這兩個過程,理解Lucene的工作原理至關重要。本

算法和數據結構~各位排序算法的介紹實現(C#)

index per 歸並 一次 集中 div lag 合並 如何 排序是指將元素集合按照規定的順序排列。通常有兩種排序方法,升序排列和降序排列。例如,對整數集{5,2,7,1}進行升序排列,結果為{1,2,5,7},對其進行降序排列結果為{7,5,2,1}。總的來說,排

thinkphp錯誤積累總結

erro let pan index 似的 thinkphp php pos ges 1,非法請求:index/user/addlist 使用兩種類似的url分別請求兩個方法 這兩個方法: public function add6(){ $user[‘nickn

文件上傳到tomcat服務器 commons-fileupload的詳細介紹使用

部分 中文字符 form 引用 編碼 path -type dex item 三個類:DiskFileUpload、FileItem和FileUploadException。這三個類全部位於org.apache.commons.fileupload包中。 首先需要說明一下f

Linux bash介紹使用

ash 倒數 想要 之間 箭頭 單詞 一般來說 周期 use Linux————bash的簡單使用 對於一個操作系統來說,shell相當於內核kernel外的一層外殼,作為用戶接口。一般來說,操作系統的接口分為兩類:GLI:command line interface命令行

機器學習入門 - 1. 介紹決策樹(decision tree)

recursion machine learning programmming 機器學習(Machine Learning) 介紹與決策樹(Decision Tree)機器學習入門系列 是 個人學習過程中的一些記錄與心得。其主要以要點形式呈現,簡潔明了。1.什麽是機器學習?一個比較概括的理解是:

Nginx學習筆記01Nginx簡要介紹目錄說明

server 簡單 adt 服務器 網站目錄 interface simple 內核 優化 1.1. Nginx簡要介紹 (1)Nginx是Web服務器。 Apache、IIS:經典的通用Web服務器。 Lighttpd、Nginx:輕量級Web服務器。 Tomcat、

atitit.js c# java交互html5化的原理總結.doc

pad 托管 works onclick rgb sar com 2.0 swing atitit.js 與c# java交互html5化的原理與總結.doc 1. 實現html5化界面的要解決的策略 1 1.1. Js交互 1 1.2. 動態參數個

關於RestFul API 介紹實踐

clas 分享 ice div 之前 api 設計 article alt 之前演示的PPT,直接看圖。。。 ?參考鏈接: ?RESTful API 設計最佳實踐 ?RESTful API 設計指南 ?SOAP webserivce和 RESTfulwebse

mybatis介紹環境搭建

mybatis一、不用純jdbc的原因,即缺點。1、數據庫理解,使用時創建,不用時釋放,會對數據庫進行頻繁的鏈接開啟和關閉,造成數據庫的資源浪費,影響數據庫的性能。設想:使用數據庫的連接池。2、將sql語句硬編碼到java代碼中,不利於系統維護。設想:將sql放到配置文件中。3、向preparedstatem

C#操作Word Aspose.Words組件介紹及使用—基本介紹DOM概述

控制 包含 枚舉類 讀取 標記 服務器端 方法 python level 1.基本介紹 Aspose.Words是一個商業.NET類庫,可以使得應用程序處理大量的文件任務。Aspose.Words支持Doc,Docx,RTF,HTML,OpenDocument,PDF,XP

內核調試神器SystemTap — 簡單介紹使用(一)

kprobe utils its preview response art sym about output a linux trace/probe tool. 官網:https://sourceware.org/systemtap/ 簡單介紹 S

1.Angular框架-angular介紹基本使用,MVC模式介紹

就會 web javascrip 點擊 技術分享 fig page 格式 存儲 1.1. AngularJS概述 1.1.1. 介紹 簡稱:ng Angular是一個MVC框架 AngularJS 誕生於2009年,由 Misko Hevery 等人創建,後為Goog

npm介紹cnpm介紹

json 通過 查看 命令 all npm安裝 可能 介紹 配置文件 npm介紹 說明:npm(node package manager)是nodejs的包管理器,用於node插件管理(包括安裝、卸載、管理依賴等) 使用npm安裝插件:命令提示符執行npm install