此博客僅供自身學習使用
webpack介紹
根據入口文件的依賴關系,將資源引進來,形成chunk代碼塊,根據不同資源進行編譯,這個處理過程我們叫做打包,打包輸出的文件叫做bundle


webpack五個核心概念
entry 入口
output 出口
loader(類似於翻譯官,因為webpack本身只能識別js文件,所以需要loader將css,img等文件翻譯成webpack能看懂的)
plugins:插件(可以執行范圍更廣的任務,比如打包優化和壓縮等)
mode:相應環境下的配置


webpack初體驗:結論

打包樣式資源
在目錄下新建webpack.config.js

loader的配置:


打包html資源:(在plugins配置html-webpack-glugin)
loader和plugins的區別:

html-webpack-glugin的作用(自動生成html文件或復制某個文件下的html文件,自動導入js/css文件,作用就是無需自己導入文件,html-webpack-glugin幫我們做了這個事情)
步驟一:引入html-webpack-plugin

步驟二:在 plugins中引入 實例化的HtmlWebpackPlugin

打包圖片資源 (url-loader file-loader html-loader)
url-loader是基於file-loader的,所以要一起引入
url-loader是處理后綴為png|jpg|gif。並且可以限制低於8kb的轉換成base64
重新用hash值命名
html-loader 是處理html中的img圖片(負責在html引入img,從而能被url-loader處理)

08 打包其他資源(例如一些字體資源 等)

09 devServer(熱更新,自動編譯,自動打開瀏覽器,自動刷新瀏覽器)

10 開發環境基本配置(總結之前的基本配置) (注:是webpack開發環境的基本配置)
//運行項目的兩個指令:
//webpack 會將打包結果輸出出去(build文件夾)
//npx webpack-dev-server 只會在內存中編譯打包,沒有輸出
//loader 和 plugin 的不同:(plugin 一定要先引入才能使用)
//loader:1. 下載 2. 使用(配置 loader)
//plugins:1.下載 2. 引入 3. 使用
// resolve用來拼接絕對路徑的方法
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') // 引用plugin
module.exports = {
// webpack配置
entry: './src/js/index.js', // 入口起點
output: {
// 輸出
// 輸出文件名
filename: 'js/build.js',
// __dirname是nodejs的變量,代表當前文件的目錄絕對路徑
path: resolve(__dirname, 'build'), // 輸出路徑,所有資源打包都會輸出到這個文件夾下
},
// loader配置
module: {
rules: [
// 詳細的loader配置
// 不同文件必須配置不同loader處理
{
// 匹配哪些文件
test: /\.less$/,
// 使用哪些loader進行處理
use: [
// use數組中loader執行順序:從右到左,從下到上,依次執行(先執行css-loader)
// style-loader:創建style標簽,將js中的樣式資源插入進去,添加到head中生效
'style-loader',
// css-loader:將css文件變成commonjs模塊加載到js中,里面內容是樣式字符串
'css-loader',
// less-loader:將less文件編譯成css文件,需要下載less-loader和less
'less-loader'
],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
// url-loader:處理圖片資源,問題:默認處理不了html中的img圖片
test: /\.(jpg|png|gif)$/,
// 需要下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小於8kb,就會被base64處理,優點:減少請求數量(減輕服務器壓力),缺點:圖片體積會更大(文件請求速度更慢)
// base64在客戶端本地解碼所以會減少服務器壓力,如果圖片過大還采用base64編碼會導致cpu調用率上升,網頁加載時變卡
limit: 8 * 1024,
// 給圖片重命名,[hash:10]:取圖片的hash的前10位,[ext]:取文件原來擴展名
name: '[hash:10].[ext]',
// 問題:因為url-loader默認使用es6模塊化解析,而html-loader引入圖片是conmonjs,解析時會出問題:[object Module]
// 解決:關閉url-loader的es6模塊化,使用commonjs解析
esModule: false,
outputPath: 'imgs',
},
},
{
test: /\.html$/,
// 處理html文件的img圖片(負責引入img,從而能被url-loader進行處理)
loader: 'html-loader',
},
// 打包其他資源(除了html/js/css資源以外的資源)
{
// 排除html|js|css|less|jpg|png|gif文件
exclude: /\.(html|js|css|less|jpg|png|gif)/,
// file-loader:處理其他文件
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media',
},
},
],
},
// plugin的配置
plugins: [
// html-webpack-plugin:默認會創建一個空的html文件,自動引入打包輸出的所有資源(JS/CSS)
// 需要有結構的HTML文件可以加一個template
new HtmlWebpackPlugin({
// 復制這個./src/index.html文件,並自動引入打包輸出的所有資源(JS/CSS)
template: './src/index.html',
}),
],
// 模式
mode: 'development', // 開發模式
// 開發服務器 devServer:用來自動化,不用每次修改后都重新輸入webpack打包一遍(自動編譯,自動打開瀏覽器,自動刷新瀏覽器)
// 特點:只會在內存中編譯打包,不會有任何輸出(不會像之前那樣在外面看到打包輸出的build包,而是在內存中,關閉后會自動刪除)
// 啟動devServer指令為:npx webpack-dev-server
devServer: {
// 項目構建后路徑
contentBase: resolve(__dirname, 'build'),
// 啟動gzip壓縮
compress: true,
// 端口號
port: 3000,
// 自動打開瀏覽器
open: true,
},
}
而生產環境的配置需要考慮以下幾個方面:
- 提取 css 成單獨文件
- css 兼容性處理
- 壓縮 css
- js 語法檢查
- js 兼容性處理
- js 壓縮
- html 壓縮
下面是生產環境下的配置
12、提取css單獨文件(之前的css文件都是通過css-loader編譯在js里面的)

引入 plugin mini-css-extract-plugin

13、css兼容性處理
首先要下載兩個包 npm i postcss-loader postcss-preset-env


14、壓縮css(plugin: optimize-css-assets-webpack-plugin )

15、js語法檢查eslint (npm i airbnb eslint-config-airbnb-base eslint-plugin-import eslint)


16 js兼容性處理eslint (npm i babel - loader @babel/core @babel/preset-env)
1、基本兼容性處理:@babel/preset-env
問題:只能轉換基本語法,如果是promise等就轉化不了
2、全部js兼容性處理 : @babel/polyfill(已經廢棄)
問題:直解決部分兼容性問題,但是將所有兼容性代碼都全部引入了,體積太大
3、需要做兼容性處理的就做:按需加載 --> core-js

最后是結合第一個和第三個一起實現的

17 壓縮html和js
生產環境下會自動壓縮js代碼


18、生產環境基本配置
const { resolve } = require('path')
const MiniCssExtractorPlugin = require('mini-css-extract-plugin')
const OptimiziCssAssetsWebpackPlugin = require('optimizi-css-assets-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 定義node.js的環境變量,決定使用browserslist的哪個環境
process.env.NODE_ENV = 'production'
// 復用loader的寫法
const commonCssLoader = [
// 這個loader取代style-loader。作用:提取js中的css成單獨文件然后通過link加載
MiniCssExtractPlugin.loader,
// css-loader:將css文件整合到js文件中
// 經過css-loader處理后,樣式文件是在js文件中的
// 問題:1.js文件體積會很大2.需要先加載js再動態創建style標簽,樣式渲染速度就慢,會出現閃屏現象
// 解決:用MiniCssExtractPlugin.loader替代style-loader
'css-loader',
/*
postcss-loader:css兼容性處理:postcss --> 需要安裝:postcss-loader postcss-preset-env
postcss需要通過package.json中browserslist里面的配置加載指定的css兼容性樣式
在package.json中定義browserslist:
"browserslist": {
// 開發環境 --> 設置node環境變量:process.env.NODE_ENV = development
"development": [ // 只需要可以運行即可
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生產環境。默認是生產環境
"production": [ // 需要滿足絕大多數瀏覽器的兼容
">0.2%",
"not dead",
"not op_mini all"
]
},
*/
{
loader: 'postcss-loader',
options: {
ident: 'postcss', // 基本寫法
plugins: () => [
// postcss的插件
require('postcss-preset-env')(),
],
},
},
]
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
{
test: /\.css$/,
use: [...commonCssLoader],
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
/*
正常來講,一個文件只能被一個loader處理
當一個文件要被多個loader處理,那么一定要指定loader執行的先后順序
先執行eslint再執行babel(用enforce)
*/
{
/*
js的語法檢查: 需要下載 eslint-loader eslint
注意:只檢查自己寫的源代碼,第三方的庫是不用檢查的
airbnb(一個流行的js風格) --> 需要下載 eslint-config-airbnb-base eslint-plugin-import
設置檢查規則:
package.json中eslintConfig中設置
"eslintConfig": {
"extends": "airbnb-base", // 繼承airbnb的風格規范
"env": {
"browser": true // 可以使用瀏覽器中的全局變量(使用window不會報錯)
}
}
*/
test: /\.js$/,
exclude: /node_modules/, // 忽略node_modules
enforce: 'pre', // 優先執行
loader: 'eslint-loader',
options: {
// 自動修復
fix: true,
},
},
/*
js兼容性處理:需要下載 babel-loader @babel/core
1. 基本js兼容性處理 --> @babel/preset-env
問題:只能轉換基本語法,如promise高級語法不能轉換
2. 全部js兼容性處理 --> @babel/polyfill
問題:只要解決部分兼容性問題,但是將所有兼容性代碼全部引入,體積太大了
3. 需要做兼容性處理的就做:按需加載 --> core-js
*/
{
// 第三種方式:按需加載
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 預設:指示babel做怎樣的兼容性處理
presets: [
'@babel/preset-env', // 基本預設
{
useBuiltIns: 'usage', //按需加載
corejs: { version: 3 }, // 指定core-js版本
targets: { // 指定兼容到什么版本的瀏覽器
chrome: '60',
firefox: '50',
ie: '9',
safari: '10',
edge: '17'
},
},
],
},
},
{
// 圖片處理
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false, // 關閉url-loader默認使用的es6模塊化解析
},
},
// html中的圖片處理
{
test: /\.html$/,
loader: 'html-loader',
},
// 處理其他文件
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media',
},
},
],
},
plugins: [
new MiniCssExtractPlugin({
// 對輸出的css文件進行重命名
filename: 'css/built.css',
}),
// 壓縮css
new OptimiziCssAssetsWebpackPlugin(),
// HtmlWebpackPlugin:html文件的打包和壓縮處理
// 通過這個插件會自動將單獨打包的樣式文件通過link標簽引入
new HtmlWebpackPlugin({
template: './src/index.html',
// 壓縮html代碼
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注釋
removeComments: true,
},
}),
],
// 生產環境下會自動壓縮js代碼
mode: 'production',
}
