目錄
- 一、版本
- 二、webpack 的主體概念
- 2-1、入口
- 2-1-1、單頁面入口
- 2-1-1-1、實作的寫法:
- 2-1-1-2、同樣也可以通過對象文法來解決不同場景的問題:
- 2-1-2、多頁面應用的入口
- 2-2、輸出
- 2-2-1、單頁面 輸出
- 2-2-2、多頁面 輸出
- 2-3、loader
- 2-3-1、如何編寫一個 loader
- 2-4、plugins
- 2-4-1、如何編寫一個plugins
- 三、如何使用
- 3-1 關于 resolve 解析的相關的疑問
- 3-1-1 resolve.alias
- 3-1-2 resolve.extensions
- 4-1 優化(optimization)
- 4-1-1 optimization.minimize
- 4-1-2 optimization.splitChunks
- 5-1 插件(plugins)
- 6-1 開發中 server (devServer)
- 3-1 關于 resolve 解析的相關的疑問
- 四、總結
目前 webpack 版本 : v4.18.0
webpack -v
// 4.18.0
同之前的版本不一樣的地方是需要 全局安裝 webpack-cli
webpack-cli -v
// 3.1.0
思考這個 webpack-cli 是真的有用麼? 其實對于我來講感覺很雞肋,雖然它是出現是為了讓我webpack 零配置化,但就目前 webpack-cli 的體驗來講,還是比較雞肋,在實際的開發過程中,我還是比較喜歡 diy ,這樣自由的折騰方式, 零配置,就意味着你要為 高度定制化作出犧牲。
這讓我想起了之前面試很多前端開發的時候,其實就是一個很簡單的問題,如何搭建一個最簡單的 webpack 的開發架構,JS 壓縮一下, LESS 預編譯一下, CSS 壓縮一下。這類,很多習慣了用 vue-cli 的同學就懵逼了,因為他們認為 架構就是用别人的東西,但實際的開發中,出于業務需求的需要,我們的架構需要更加多的靈活性和高度可定制化性。 是以這才是寫這篇文章的 出發點。
開局一張圖:
本質上,
webpack
是一個現代 JavaScript 應用程式的靜态子產品
打包器
(static module bundler)。在 webpack 處理應用程式時,它會在内部建立一個依賴圖(dependency graph),用于映射到項目需要的每個子產品,然後将所有這些依賴生成到一個或多個bundle。
在開始前我們需要先了解它的 核心概念
:
- 入口(entry)
- 輸出(output)
- loader
- 插件(plugins)
入口起點(entry point)
這裡是一切開始的起點。面對實際的業務來講的話,可以分為單頁面( SPA ) 和多頁面。那麼今天就針對這2種情況來分别 介紹下 利用 webpack 進行項目架構的需要注意的地方。
webpack.config.js
module.exports = {
entry: './app.js'
}
module.exports = {
entry: {
app: './app.js',
vendors: './src/JQ.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 對象。
module.exports = {
output: {
filename: 'bundle.js',
path: '/home/proj/public/assets'
}
};
module.exports = {
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
};
這裡的 loader 就像一個又一個的加工廠一樣,把你輸送給 加工産的原材料加工生成你想要的成品或者半成品。最後出廠~
有用過 gulp 類似的建構工具等同學 就很 容易了解,這裡的一個個的 loader 就想當一一個個的 task, 這個任務完成就會交給下一個人,直到整個流水線工作跑完~
在更高層面,在 webpack 的配置中 loader 有兩個特征(demo):
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
}
其中有三個需要注意的地方:
1、loader 的特征之一:
test
屬性,用于辨別出應該被對應的 loader 進行轉換的某個或某些檔案。
2、loader 的特征之二:
use
屬性,表示進行轉換時,應該使用哪個 loader。
3、在 webpack 配置中定義 loader 時,要定義在
module.rules
中,而不是
rules
前期這裡也隻是大概的了解一下,在後面的文章中,我們會手把手的教你 手寫一個 loader
這篇文章還隻是教你如何使用 webpack。 敬請期待後面的文章吧 😁
插件是 webpack 的
支柱
功能。webpack 自身也是建構于,你在 webpack 配置中用到的相同的插件系統之上!
插件目的在于解決 loader
無法實作
的其他事。
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'})
]
}
一樣的,前期這裡也隻是大概的了解一下,在後面的文章中,我們會手把手的教你 手寫一個 plugins
在上面的文章中,我們已經大緻介紹了 webpack 的概念,下面就是需要我們來配置一個 可以實際使用的項目。
webpack基礎配置項目位址
建立 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'
這樣就可以 忽略因為項目檔案過深而引起的 引用元件路徑出錯的問題,進而加快效率。
自動解析确定的擴充。預設值為:
module.exports = {
//...
resolve: {
extensions: ['.wasm', '.mjs', '.js', '.json']
}
};
這樣的話,就會幫你把未加上 字尾名的檔案自動加上配置字尾,進而加快開發效率。
當然也是按照你所給出的檔案路徑去比對的字尾,而不是随意加上字尾名。
關于 resolve 解析 的内容還有很多,大家可以參考 webpack 官方文檔去尋找自己需要的内容,讓自己開發項目的速度變得更加快捷友善。
在 4.0 以後的 webpack 版本,他們專門把 optimization 提取出來作為一個大的子產品來進行了優化,因為這個功能實在是太能有效的提升項目的加載速度了。為什麼會這麼說呢?下面我們就來了解了解~
我們先來看一個簡單的配置:
module.exports = {
//...
optimization: {
minimize: false
}
};
這個屬性是一個 布爾類型,是告訴 webpack 我們是否在目前環境下去壓縮混淆我們的 JS 代碼。
當然 需要配合這個屬性來使用的還有一個
插件
主要注意:
UglifyjsWebpackPlugin
這個屬性是在 webpack 4.0 + 才提供的。用來 分離切割 體積較大的 JS 檔案。
然後 webpack 會自動将 通用的 chunk 進行分割,進而最大限度的做到
複用
,進而減少 main chunk 的體積。
選項用于以各種方式自定義 webpack 建構過程。webpack 附帶了各種内置插件,可以通過
plugins
通路這些插件。
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 進而避免重複打包而帶來的性能損耗。
這裡的重要部分就是 webpack-dev-server 這個插件了。
webpack-dev-server 建立目前本地開發的node環境,進而才能有上面種種 webpack 對于檔案的操作權限,才能為所欲為,這個是基本。我們還是來一個最簡單的 demo。
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
};
這裡面也有非常多的 屬性配置,基本滿足了我們開發中遇到的大多數的問題。
基本上完成了上面文章中介紹到的内容,我們就已經可以完成基本的 webpack 配置的功能了, 注意: 這裡說到的是 基本的 webpack 的配置工作,那麼在我們的實際的項目開發中,我們會遇到的問題和需要我們通過webpack 來解決的問題非常之多。
因為我們需要結合一系列的架構來完成我們的前端開發的工作,React、Vue、Angular、JQ,Backbone 等等等。 這系列的架構 風格各異,但是又萬變不離其宗,核心需要注意的地方就那麼多,下一篇文章就會 講到一個 現代 前端開發 需要注意的一個重要 插件。 Babel
。
關于 webpack 入門的文章就介紹到這裡了,歡迎一起來論道~
GitHub 位址:(歡迎 star 、歡迎推薦 : )
前端 webpack 4.0 的應用建構
歡迎推薦,歡迎 star