本文將從多個方面回顧下自己了解的Webpack知識,包括常見的配置項,前端搭建的一些方法和項目實際優化方法,有錯誤的地方還請指出並多多包涵。
一、關於Webpack
1.概念
本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關系圖(dependency graph),其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。常見構造結構如下:
module.exports = {
entry:'./main.js',
output:{
path:__dirname,
filename:'bundle.js'
},
module:{
rules:[
{
test:/\.(png|jpg)$/,
use:[
{
loader:'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}
2.入口(entry)
入口起點(entrypoint)指示webpack應該使用哪個模塊,來作為構建其內部依賴圖的開始。進入入口起點后,webpack會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。可以通過在 webpack配置中配置entry屬性,來指定一個入口起點(或多個入口起點)。默認值為 ./src。
{
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
3.出口(output)
output 屬性告訴 webpack在哪里輸出它所創建的bundles,以及如何命名這些文件,默認值為 ./dist。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個output字段,來配置這些處理過程。在上面的示例中,我們通過output.filename 和 output.path 屬性,來告訴 webpack bundle 的名稱,以及我們想要 bundle 生成(emit)到哪里。當有多個入口起點的時候,可以使用如下對象的形式來寫入口和出口:
4.模式(mode)
提供 mode 配置選項,告知 webpack 使用相應模式的內置優化。
mode : 'development' | 'production'
5.loader
loader 用於對模塊的源代碼進行轉換。loader 可以使你在 import 或"加載"模塊時預處理文件。因此,loader 類似於其他構建工具中“任務(task)”,並提供了處理前端構建步驟的強大方法。loader 可以將文件從不同的語言(如 TypeScript)轉換為 JavaScript,或將內聯圖像轉換為 data URL。loader 甚至允許你直接在 JavaScript 模塊中 import CSS文件!
5.1.使用loader
Loaders需要單獨安裝並且需要在webpack.config.js中的modules關鍵字下進行配置,Loaders的配置包括以下幾方面:
- test:一個用以匹配loaders所處理文件的拓展名的正則表達式 (必須)
- loader:loader的名稱 (必須)
- include/exclude: 手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)(可選);
- query:為loaders提供額外的設置選項 (可選)
module.exports = {
entry:'./main.jsx',
output:{
path:__dirname,
filename:'bundle.js'
},
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test:/\.jsx?$/,
exclude:/node_modules/,
use:{
loader:'babel-loader',
options:{
presets:['es2015','react']
}
}
}
]
}
}
5.2.loader特性
- loader 支持鏈式傳遞。能夠對資源使用流水線(pipeline)。一組鏈式的 loader 將按照相反的順序執行。loader 鏈中的第一個 loader 返回值給下一個 loader。在最后一個 loader,返回 webpack 所預期的 JavaScript。
- loader 可以是同步的,也可以是異步的。
- loader 運行在 Node.js 中,並且能夠執行任何可能的操作。
- loader 接收查詢參數。用於對 loader 傳遞配置。
- loader 也能夠使用 options 對象進行配置。
- 除了使用 package.json 常見的 main 屬性,還可以將普通的 npm 模塊導出為 loader,做法是在 package.json 里定義一個 loader 字段。
- 插件(plugin)可以為 loader 帶來更多特性。
- loader 能夠產生額外的任意文件。
- include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)(可選)。
6.插件(plugins)
- 插件是 webpack 的支柱功能。webpack 自身也是構建於,你在 webpack 配置中用到的相同的插件系統之上!插件目的在於解決 loader 無法實現的其他事。
- webpack 插件是一個具有 apply 屬性的 JavaScript 對象。apply 屬性會被 webpack compiler 調用,並且 compiler 對象可在整個編譯生命周期訪問。
- 由於插件可以攜帶參數/選項,你必須在 webpack 配置中,向 plugins 屬性傳入 new 實例。
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝
const webpack = require('webpack'); //訪問內置的插件
--
--
--
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
二、前端搭建
當前開發構建項目過程,不管是Vue還是React,他們的腳手架
Vue-cli
和Create React App
工具都會自動把Webpack添加到項目中,下面介紹的是自己手動搭建的一些基本配置和過程。
1.安裝
npm install webpack webpack-cli -g
或者
yarn global add webpack webpack-cli
2.配置
新建一個webpack的文件夾,在其下新建一個try-webpack(防止init時項目名和安裝包同名)並初始化和配置webpack。
npm init -y //-y 默認所有的配置
yarn add webpack webpack-cli -D //-D webpack安裝在devDependencies環境中
三、部署webpack
在package.json里配置scripts
"scripts": {
"build": "webpack --mode production" //我們在這里配置,就可以使用npm run build 啟動我們的webpack
},
"devDependencies": {
"webpack": "^4.16.0",
"webpack-cli": "^3.0.8"
}
四、配置
1.html
打包html使用 html-webpack-plugin
plugins: [ //插進的引用, 壓縮,分離美化
new HtmlWebpackPlugin({ //將模板的頭部和尾部添加css和js模板,dist 目錄發布到服務器上,項目包。可以直接上線
file: 'index.html', //打造單頁面運用 最后運行的不是這個
template: 'src/index.html' //vue-cli放在跟目錄下
}),
],
2.live-server
安裝完成后進入根目錄 可直接啟動node服務
3.js
babel。在.babelrc配置文件中,主要是對預設(presets)和插件(plugins)進行配置,因此不同的轉譯器作用不同的配置項,大致可分為以下三項
- 語法轉義器
- 補丁轉義器
- jsx和flow插件
創建預設(presets)
"presets": [
[
"@babel/preset-env",
{ //options配置介紹:targets可以制定兼容瀏覽器版本
"targets": {
"chrome": 52,
"browsers": [
"last 2 versions",
"safari 7"
]
}
}
],
"@babel/preset-react",
"@babel/preset-flow"
]
插件(plugins)
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"@babel/plugin-proposal-class-properties",
{
"loose": true
}
],"react-hot-loader/babel",[
"@babel/plugin-transform-runtime",
{
// "regenerator": true
}
]]
五、項目優化
在實際的開發項目中,我遇到了打包后文件過大導致的頁面首次打開速度特別慢的情況,在查過好多資料和博客后,總結了一些簡單的優化方法。
1.打包可視化插件
name: webpack-bundle-analyzer -> BundleAnalyzerPlugin
簡介: 該插件可以將打包的項目以可視化的形式展現到瀏覽器上,並展示打包項目的名稱大小等,更加方便針對優化
// install
sudo npm i -D webpack-bundle-analyzer
// code
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
baseConfig.plugins.push(
new BundleAnalyzerPlugin({ analyzerPort: 8082 })
)
2.JS代碼壓縮
name: webpack-parallel-uglify-plugin
簡介: 使用 ParallelUglifyPlugin 並行壓縮輸出的 JS 代碼,並對具體壓縮內容做具體配置
// install
sudo npm i -D webpack-parallel-uglify-plugin
// code
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
new ParallelUglifyPlugin({
// 傳遞給 UglifyJS 的參數
uglifyJS: {
output: {
// 最緊湊的輸出
beautify: false,
// 刪除所有的注釋
comments: false,
},
compress: {
// 刪除所有的 `console` 語句,可以兼容ie瀏覽器
drop_console: true,
// 內嵌定義了但是只用到一次的變量
collapse_vars: true,
// 提取出出現多次但是沒有定義成變量去引用的靜態值
reduce_vars: true,
}
},
})
3.動態導入文件插件
name: dynamic-import-webpack
簡介: 用來支持React懶加載,否則會報錯
// install
npm i -D dynamic-import-webpack
//code 配置在 .babelrc文件 plugins中
{
"plugins": "dynamic-import-webpack",
}