webapck 基礎(chǔ) (小白篇)

為什么選擇 webpack

  • 社區(qū)生態(tài)豐富
  • 配置靈活和插件化擴(kuò)展
  • 官方更新迭代速度快

配置文件名稱(chēng)

  • webpack 默認(rèn)配置文件 webpack.config.js
  • 也可以通過(guò) webpack --config 執(zhí)行配置文件

webpack 配置組成

module.exports = {
  entry:   ----> 打包文件的入口
    output:  -----> 打包的輸出
    mode: 'production'  ----> 環(huán)境
    module: {
        rules: [
            { test: /\.txt$/ }   -----> Loader 配置
        ]
    },
    plugins: [      -------> 插件配置
        new HtmlwebpackPlugin({
            template: ''
        })
    ]
}

使用 webpack 打包文件

  • 使用 webpack 小案例

準(zhǔn)備文件及安裝webapck

  1. 打開(kāi)終端 常見(jiàn)文件 及 初始化項(xiàng)目 (注意要先安裝 node)
mkdir  my-webpack
cd my-webpack
npm init -y
  1. 安裝 webpack 及 webpack-cli
npm install webpack webpack-cli --save-dev
  1. 新建webpack.config.js
const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'main.js'
  },
  mode: 'production'
}
  1. 創(chuàng)建src 下的 index.js 文件箍土,簡(jiǎn)單寫(xiě)一寫(xiě)邏輯代碼
  2. 然后在項(xiàng)目目錄下的終端執(zhí)行
./node_modules/.bin/webpack
  • 然后會(huì)在 dist 文件夾中找到打包后的 main.js 文件
  1. 使用 npm 命令 替代 ./node_modules/.bin/webpack 打包
  • 在 package.json 中的 scripts 添加 build 命令
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
},
  • 執(zhí)行 npm run build 一樣可以打包

entry 和 output

單入口

entry: './src/index.js',
output: {
    path: path.join(__dirname, 'dist'),
  filename: 'build.js'
}

多入口

entry: {
    app: './src/index.js'
    app2: './src/main.js'
},
output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
},

Loaders

  • 本身就是一個(gè)函數(shù),接收源文件作為參數(shù)附帽,返回轉(zhuǎn)換的結(jié)果

常用的 Loaders

  • babel-loader
  • css-loader
  • less-loader
  • ts-loader
  • file-loader

Plugins

  • 插件用于 bundle 文件的優(yōu)化乾吻,資源管理和環(huán)境變量注入
  • 作用于整個(gè)構(gòu)建構(gòu)成

常見(jiàn)的 Plugins

  • CleanWbpackPlugin 清理構(gòu)建目錄
  • CommonsChunkPlugin 講chunks相同的模塊代碼提取成公共 js
  • HtmlWebpackPlugin 創(chuàng)建 HTML 文件去承載輸出的 bundle
  • UglifyjsWebpackPlugin 壓縮JS

Mode

  • 用來(lái)指定當(dāng)前的構(gòu)建環(huán)境是 production development 還是 none
  • 設(shè)置 mode 可以使用 webpack 內(nèi)置函數(shù)枪萄,默認(rèn)值是 production
module.exports = {
  mode: 'development'
};
  • 或者從 cli 參數(shù)中傳遞
webpack --mode=development

內(nèi)置函數(shù)功能

  • 選項(xiàng) development

會(huì)將 DefinePlugin 中 process.env.NODE_ENV 的值設(shè)置為 development. 為模塊和 chunk 啟用有效的名农尖。

  • production

會(huì)將 DefinePlugin 中 process.env.NODE_ENV 的值設(shè)置為 production。為模塊和 chunk 啟用確定性的混淆名稱(chēng)扔役,F(xiàn)lagDependencyUsagePlugin肄鸽,F(xiàn)lagIncludedChunksPlugin卫病,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin 和 TerserPlugin 典徘。

  • node

不使用任何默認(rèn)優(yōu)化選項(xiàng)

使用 babel 解析 ES6

  • 安裝 babel 解析文件
npm i @babel/core @babel/preset-env babel-loader -D
  • 創(chuàng)建 .babelrc 文件 并添加:
{
  "presets": [
    "@babel/press-env"
  ]
}
  • webpack.config.js 中添加 rules
module: {
    rules: [
        {
            test: /.js$/,
            use: 'babel-loader'
        }
    ]
}

解析 CSS 文件

  • 安裝 style-loader 和 css-loader
  • 修改 webpack.config.js 文件
module: {
    rules: [
        {
            test: /.js$/,
            use: 'babel-loader'
        },
        {
            test: /.css$/,
            use: [
                'style-loader',
                'css-loader'
            ]
        }
    ]
}

loader 的執(zhí)行順序是 從又右到左的

url-loader 解析圖片

  • 安裝 url-loader 和 file-loader
module: {
    rules: [
        {
            test: /.js$/,
            use: 'babel-loader'
        },
        {
            test: /.css$/,
            use: [
                'style-loader',
                'css-loader'
            ]
        },
        {
            test: /.(png|jpg|gif|jpeg)$/,
            use: [
                {
                    loader: 'url-loader',
                    options: { // 圖片大小的限制 如果小于 10k 轉(zhuǎn)成 base64 格式
                        limit: 10240
                    }
                }
            ]
        }
    ]
}

webpack 文件監(jiān)聽(tīng)

  1. 啟動(dòng) webpack 命令時(shí)蟀苛,帶上 --watch 參數(shù)
    • 缺點(diǎn)是: 每次需要手動(dòng)刷新瀏覽器
  2. 在配置 webpack.config.js 中設(shè)置 watch: true
  • 文件監(jiān)聽(tīng)的原理分析
    • 輪詢(xún)判斷文件的最后編譯事件是否變化
    • 某個(gè)文件發(fā)生了變化,并不會(huì)立即監(jiān)聽(tīng)者逮诲,而是先緩存起來(lái)帜平,等 aggregateTimeout
watch: true,
watchOptions: {
    // 默認(rèn)為空,不監(jiān)聽(tīng)文件或文件件梅鹦,支持正則
    ignored: /node_modules/,
    // 監(jiān)聽(tīng)發(fā)生變化后等待 xxx 毫秒去執(zhí)行裆甩,默認(rèn) 300
    aggregateTimeout: 300,
    // 判斷文件是否發(fā)生變化,通過(guò)不停的詢(xún)問(wèn)系統(tǒng)指定文件有沒(méi)有變化實(shí)現(xiàn)齐唆,默認(rèn)每秒問(wèn) 1000 次
    poll: 1
}

熱更新 webpack-dev-server

  • 特點(diǎn): 不刷新瀏覽器嗤栓,不輸出文件,而是放在內(nèi)存中
  • webpack-dev-server --open

熱更新 使用 webpack-dev-middleware

  • 通過(guò) node express/koa 創(chuàng)建一個(gè) server 編寫(xiě)相關(guān)邏輯
  • 將 webpack 輸出文件傳輸給服務(wù)器
  • 適用于靈活的定制場(chǎng)景

熱更新的原理分析

  1. Webpack Compile
  • 將 JS 編譯成 Bundle (打包好輸出的文件)
  1. HMR (Hot Module Replacement) Server:
  • 將熱更新文件傳輸給 HMR Rumtime
  1. Bundle Server:
  • 提供文件在瀏覽器的訪問(wèn) (通過(guò)服務(wù)器的方式訪問(wèn),例如 127.0.0.1:8080)
  1. HMR Rumtime:
  • 打包時(shí)會(huì)被注入到瀏覽器中茉帅,使瀏覽器和服務(wù)器建立連接叨叙,通常的連接方式是用 websocket, 用來(lái)更新文件的變化
  1. bundle.js
  • 構(gòu)建輸出的文件

熱更新的過(guò)程

  1. 熱更新的啟動(dòng)階段
  • 代碼通過(guò) Webpack Compile 進(jìn)行編譯打包,然后將編譯好的文件傳輸給 Bundle Server (服務(wù)器)堪澎,讓文件以 server 的方式被 瀏覽器 訪問(wèn)到擂错。
  1. 更新階段
  • 代碼通過(guò) Webpack Compile 進(jìn)行編譯打包,將代碼發(fā)送給 HMR Server 知道哪些 js 文件發(fā)生變動(dòng)樱蛤,然后通知 HMR Rumtime (HMR Server 在 服務(wù)端钮呀,HMR Rumtime 在客戶(hù)端)哪些文件發(fā)生變化,通常是已JSON 的方式傳輸昨凡,然后 HMR Rumtime 更新代碼.

文件指紋

  • 打包后輸出的文件名的后綴

Hash

  • 和整個(gè)項(xiàng)目的構(gòu)建相關(guān), 只要項(xiàng)目文件有修改爽醋,整個(gè)項(xiàng)目構(gòu)建的 hash 值就會(huì)更改

Chunkhash

  • 和 webpack 打包的 chunk 有關(guān),不同的 entry 會(huì)生成不同的 chunkhash 值

Contenthash

  • 根據(jù)文件內(nèi)容來(lái)定義 hash土匀,文件內(nèi)容不變子房,則 Contenthash 不變
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name][chunkhash:8].js'
  },
    module: {
        rules: [
            {
                test: /\.(png|svg|jpg)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: 'img/[name][hash:8].[ext]'
                        }
                    }
                ] 
            },
            {
                test: /.css$/,
                use: [
                    // 'style-loader', 這個(gè)是把 css 放到 style 里面和用  MiniCssExtractPlugin 有沖突,它是把 css 放到一個(gè)獨(dú)立的文件中
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            },
        ]
    }
  mode: 'production',
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name][contenthash:8].css'
        })
    ]
}

:8 意思是只取前 8 位

  • 圖片文件指紋設(shè)置可選參數(shù)
    • [ext] : 資源后綴名
    • [name] : 文件名稱(chēng)
    • [path] : 文件相對(duì)路徑
    • [folder] : 文件所在的文件夾
    • [contenthash]: 文件內(nèi)容的 hash 默認(rèn) MD5 生成
    • [hash] : 文件內(nèi)容的 hash 默認(rèn) MD5 生成
    • [emoji] : 一個(gè)隨機(jī)的指定文件內(nèi)容的 emoji

代碼壓縮

JS 文件的壓縮

  • uglifyjs-webpack-plugin webpack4.0 后內(nèi)置了

css 壓縮

  • 安裝
    • npm i optimize-css-assets-webpack-plugin -D
    • npm i cssnano -D
  • 代碼
new OpeimizeCssAssetsPlugin({
    assetNameEegExp: /\.css$/g,
    cssProcessor: require('cssnano')
}),

html 壓縮

  • 安裝
npm i html-webpack-plugin -D
  • 代碼
new HtmlWebpackPlugin({
    // 模板 所在的位置
    template: path.join(__dirname, 'src/index.html'),
    // 指定打包后的文件名稱(chēng)
    filename: 'index.html',
    // 聲明 HTML 使用什么 chunks
    chunks: ['index'],
    // 把引入的 js 或 css 自動(dòng)注入
    inject: true,
    minify: {
        html5: true,
        collapseWhitespace: true,
        preserveLineBreaks: false,
        minifyCSS: true,
        minifyJS: true,
        removeComments: false
    }
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末就轧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子田度,更是在濱河造成了極大的恐慌妒御,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镇饺,死亡現(xiàn)場(chǎng)離奇詭異乎莉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)奸笤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)惋啃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人监右,你說(shuō)我怎么就攤上這事边灭。” “怎么了健盒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵绒瘦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我扣癣,道長(zhǎng)惰帽,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任父虑,我火速辦了婚禮该酗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘士嚎。我一直安慰自己呜魄,他們只是感情好烁焙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著耕赘,像睡著了一般骄蝇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上操骡,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天九火,我揣著相機(jī)與錄音,去河邊找鬼册招。 笑死岔激,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的是掰。 我是一名探鬼主播虑鼎,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼键痛!你這毒婦竟也來(lái)了炫彩?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤絮短,失蹤者是張志新(化名)和其女友劉穎江兢,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丁频,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杉允,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了席里。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叔磷。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖奖磁,靈堂內(nèi)的尸體忽然破棺而出改基,到底是詐尸還是另有隱情,我是刑警寧澤署穗,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布寥裂,位于F島的核電站,受9級(jí)特大地震影響案疲,放射性物質(zhì)發(fā)生泄漏封恰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一褐啡、第九天 我趴在偏房一處隱蔽的房頂上張望诺舔。 院中可真熱鬧,春花似錦、人聲如沸低飒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褥赊。三九已至糕档,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拌喉,已是汗流浹背速那。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿背,地道東北人端仰。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像田藐,于是被迫代替她去往敵國(guó)和親荔烧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容