《前端之路》之 webpack 4.0+ 的應用構建

[TOC]javascript

1、版本

當前 webpack 版本 : v4.18.0html

webpack -v
// 4.18.0
複製代碼

同以前的版本不同的地方是須要 全局安裝 webpack-cli前端

webpack-cli -v
// 3.1.0
複製代碼

思考這個 webpack-cli 是真的有用麼? 其實對於我來說感受很雞肋,雖然它是出現是爲了讓我webpack 零配置化,但就目前 webpack-cli 的體驗來說,仍是比較雞肋,在實際的開發過程當中,我仍是比較喜歡 diy ,這樣自由的折騰方式, 零配置,就意味着你要爲 高度定製化做出犧牲。vue


這讓我想起了以前面試不少前端開發的時候,其實就是一個很簡單的問題,如何搭建一個最簡單的 webpack 的開發架構,JS 壓縮一下, LESS 預編譯一下, CSS 壓縮一下。這類,不少習慣了用 vue-cli 的同窗就懵逼了,由於他們認爲 架構就是用別人的東西,但實際的開發中,出於業務需求的須要,咱們的架構須要更加多的靈活性和高度可定製化性。 因此這纔是寫這篇文章的 出發點。java

2、webpack 的主體概念

開局一張圖:node

本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(static module bundler)。在 webpack 處理應用程序時,它會在內部建立一個依賴圖(dependency graph),用於映射到項目須要的每一個模塊,而後將全部這些依賴生成到一個或多個bundle。webpack

在開始前咱們須要先理解它的核心概念git

  • 入口(entry)
  • 輸出(output)
  • loader
  • 插件(plugins)

2-一、入口

入口起點(entry point)github

這裏是一切開始的起點。面對實際的業務來說的話,能夠分爲單頁面( SPA ) 和多頁面。那麼今天就針對這2種狀況來分別 介紹下 利用 webpack 進行項目架構的須要注意的地方。web

2-1-一、單頁面入口

2-1-1-一、實現的寫法:

webpack.config.js

module.exports = {
	entry: './app.js'
}
複製代碼

2-1-1-二、一樣也能夠經過對象語法來解決不一樣場景的問題:

webpack.config.js

module.exports = {
	entry: {
		app: './app.js',
		vendors: './src/JQ.js'
	}
}
複製代碼

2-1-二、多頁面應用的入口

webpack.config.js

module.exports = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};
複製代碼

可是這裏只是人工的去配置了多頁面,其實很明顯這種作法很不聰明。 因此你須要一個聰明的作法,這裏就大體講一下思路。 經過 ( ' ./src/**/*.js' ) 匹配到 多頁面到文件入口路徑,而後 經過 glob.sync(globPath) 獲取到所有路徑,拿到每一個頁面的 入口文件路徑。 最後傳值給 webpack 的 entry 對象。

2-二、輸出

2-2-一、單頁面 輸出

webpack.config.js

module.exports = {
  output: {
    filename: 'bundle.js',
    path: '/home/proj/public/assets'
  }
};
複製代碼

2-2-二、多頁面 輸出

webpack.config.js

module.exports = {
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
};
複製代碼

2-三、loader

這裏的 loader 就像一個又一個的加工廠同樣,把你輸送給 加工產的原材料加工生成你想要的成品或者半成品。最後出廠~

有用過 gulp 相似的構建工具等同窗 就很 容易理解,這裏的一個個的 loader 就想當一一個個的 task, 這個任務完成就會交給下一我的,直到整個流水線工做跑完~

在更高層面,在 webpack 的配置中 loader 有兩個特徵(demo):

webpack.config.js

const path = require('path');

module.exports = {
  output: {
    filename: 'my-first-webpack.bundle.js'
  },
  module: {
    rules: [
      { test: /\.txt$/, use: 'raw-loader' }
    ]
  }
}
複製代碼

其中有三個須要注意的地方:

一、loader 的特徵之一: test 屬性,用於標識出應該被對應的 loader 進行轉換的某個或某些文件。

二、loader 的特徵之二: use 屬性,表示進行轉換時,應該使用哪一個 loader。

三、在 webpack 配置中定義 loader 時,要定義在 module.rules 中,而不是 rules

2-3-一、如何編寫一個 loader

前期這裏也只是大概的瞭解一下,在後面的文章中,咱們會手把手的教你 手寫一個 loader

這篇文章還只是教你如何使用 webpack。 敬請期待後面的文章吧 😁

2-四、plugins

插件是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的插件系統之上!

插件目的在於解決 loader 沒法實現的其餘事。

webpack.config.js

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
}

複製代碼

2-4-一、如何編寫一個plugins

同樣的,前期這裏也只是大概的瞭解一下,在後面的文章中,咱們會手把手的教你 手寫一個 plugins

這篇文章還只是教你如何使用 webpack。 敬請期待後面的文章吧 😁

3、如何使用

在上面的文章中,咱們已經大體介紹了 webpack 的概念,下面就是須要咱們來配置一個 能夠實際使用的項目。

webpack基礎配置項目地址

3-1 關於 resolve 解析的相關的疑問

3-1-1 resolve.alias

建立 import 或 require 的別名,來確保模塊引入變得更簡單。例如,一些位於 src/ 文件夾下的經常使用模塊:

module.exports = {
  //...
  resolve: {
    alias: {
	  'vue$': 'vue/dist/vue.common.js',
      'src': path.resolve(__dirname, './src/src/'),
      'assets': path.resolve(__dirname, './src/assets/'),
      'components': path.resolve(__dirname, '../src/components')
    }
  }
};
複製代碼

有了上面的配置後,在項目文件中若是須要引用 components 文件夾下面的某個組件的時候 就能夠 直接 以下的引用方式:

import Alert from 'component/alert'
複製代碼

這樣就能夠 忽略由於項目文件過深而引發的 引用組件路徑出錯的問題,從而加快效率。

3-1-2 resolve.extensions

自動解析肯定的擴展。默認值爲:

module.exports = {
  //...
  resolve: {
    extensions: ['.wasm', '.mjs', '.js', '.json']
  }
};
複製代碼

這樣的話,就會幫你把未加上 後綴名的文件自動加上配置後綴,從而加快開發效率。

固然也是按照你所給出的文件路徑去匹配的後綴,而不是隨意加上後綴名。

關於 resolve 解析 的內容還有不少,你們能夠參考 webpack 官方文檔去尋找本身須要的內容,讓本身開發項目的速度變得更加快捷方便。

4-1 優化(optimization)

在 4.0 之後的 webpack 版本,他們專門把 optimization 提取出來做爲一個大的模塊來進行了優化,由於這個功能實在是太能有效的提高項目的加載速度了。爲何會這麼說呢?下面咱們就來了解了解~

咱們先來看一個簡單的配置:

module.exports = {
  //...
  optimization: {
    minimize: false
  }
};
複製代碼

4-1-1 optimization.minimize

這個屬性是一個 布爾類型,是告訴 webpack 咱們是否在當前環境下去壓縮混淆咱們的 JS 代碼。

固然 須要配合這個屬性來使用的還有一個 插件 主要注意: UglifyjsWebpackPlugin

4-1-2 optimization.splitChunks

這個屬性是在 webpack 4.0 + 才提供的。用來 分離切割 體積較大的 JS 文件。

而後 webpack 會自動將 通用的 chunk 進行分割,從而最大限度的作到 複用 ,從而減小 main chunk 的體積。

5-1 插件(plugins)

plugins 選項用於以各類方式自定義 webpack 構建過程。webpack 附帶了各類內置插件,能夠經過 webpack.[plugin-name] 訪問這些插件。

webpack 插件列表。例如,當多個 bundle 共享一些相同的依賴,CommonsChunkPlugin 有助於提取這些依賴到共享的 bundle 中,來避免重複打包。這裏仍是舉例說明:

module.exports = {
  //...
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: 'vendor-[hash].min.js',
    })
  ]
};
複製代碼

這裏 CommonsChunkPlugin 就會告訴 webpack 讓它把 多個 bundle 共享一些相同的依賴,抽離出來,造成一個單獨的 bundle 從而避免重複打包而帶來的性能損耗。

6-1 開發中 server (devServer)

這裏的重要部分就是 webpack-dev-server 這個插件了。

webpack-dev-server 建立當前本地開發的node環境,從而纔能有上面種種 webpack 對於文件的操做權限,才能隨心所欲,這個是基本。咱們仍是來一個最簡單的 demo。

module.exports = {
  //...
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,   
    port: 9000
  }
};
複製代碼

這裏面也有很是多的 屬性配置,基本知足了咱們開發中遇到的大多數的問題。

4、總結

基本上完成了上面文章中介紹到的內容,咱們就已經能夠完成基本的 webpack 配置的功能了, 注意: 這裏說到的是 基本的 webpack 的配置工做,那麼在咱們的實際的項目開發中,咱們會遇到的問題和須要咱們經過webpack 來解決的問題很是之多。


由於咱們須要結合一系列的框架來完成咱們的前端開發的工做,React、Vue、Angular、JQ,Backbone 等等等。 這系列的框架 風格各異,可是又萬變不離其宗,核心須要注意的地方就那麼多,下一篇文章就會 講到一個 現代 前端開發 須要注意的一個重要 插件。 Babel


關於 webpack 入門的文章就介紹到這裏了,歡迎一塊兒來論道~

GitHub 地址:(歡迎 star 、歡迎推薦 : )

前端 webpack 4.0 的應用構建

相關文章
相關標籤/搜索