- 什么是webpack
WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項(xiàng)目結(jié)構(gòu)猪杭,找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語言(Scss启摄,TypeScript等),并將其打包為合適的格式以供瀏覽器使用辩尊。 - webpack核心概念
Entry:入口烟馅,Webpack 執(zhí)行構(gòu)建的第一步將從 Entry 開始说庭,可抽象成輸入。
Module:模塊郑趁,在 Webpack 里一切皆模塊刊驴,一個(gè)模塊對(duì)應(yīng)著一個(gè)文件。Webpack 會(huì)從配置的 Entry 開始遞歸找出所有依賴的模塊寡润。
Chunk:代碼塊捆憎,一個(gè) Chunk 由多個(gè)模塊組合而成,用于代碼合并與分割梭纹。 Loader:模塊轉(zhuǎn)換器躲惰,用于把模塊原內(nèi)容按照需求轉(zhuǎn)換成新內(nèi)容。
Plugin:擴(kuò)展插件变抽,在 Webpack 構(gòu)建流程中的特定時(shí)機(jī)注入擴(kuò)展邏輯來改變構(gòu)建結(jié)果或做你想要的事情础拨。
Output:輸出結(jié)果,在 Webpack 經(jīng)過一系列處理并得出最終想要的代碼后輸出結(jié)果绍载。
webpack執(zhí)行流程
webpack啟動(dòng)后會(huì)在entry里配置的module開始遞歸解析entry所依賴的所有module诡宗,沒找到一個(gè)module, 就會(huì)根據(jù)配置的loader去找相應(yīng)的轉(zhuǎn)換規(guī)則,對(duì)module進(jìn)行轉(zhuǎn)換后在解析當(dāng)前module所依賴的module击儡,這些模塊會(huì)以entry為分組僚焦,一個(gè)entry和所有相依賴的module也就是一個(gè)chunk,最后webpack會(huì)把所有chunk轉(zhuǎn)換成文件輸出曙痘,在整個(gè)流程中webpack會(huì)在恰當(dāng)?shù)臅r(shí)機(jī)執(zhí)行plugin的邏輯開始從零配置webpack
-
初始化配置
mkdir webpack-start cd webpack-start npm init
-
配置webpack
yarn add webpack webpack-cli -D //webpack4把webpack拆分了 mkdir src cd src并且創(chuàng)建index.html, index.js mkdir dist touch webpack.config.js
webpack.config.js
module.exports = {
entry: './src/index.js', //入口文件芳悲,src下的index.js
output: {
path: path.join(__dirname, 'dist'), // 出口目錄,dist文件
filename: '[name].[hash].js' //這里name就是打包出來的文件名边坤,因?yàn)槭菃稳肟诿福褪莔ain,多入口下回分解
},
module: {},
plugin: {},
devServer: {}
}
-
配置開發(fā)服務(wù)器
yarn add webpack-dev-server -D
修改webpack.config.js
devServer: {
contentBase: path.join(__dirname, "dist"), //靜態(tài)文件根目錄
port: 9090, // 端口
host: 'localhost',
overlay: true,
compress: true // 服務(wù)器返回瀏覽器的時(shí)候是否啟動(dòng)gzip壓縮
}
修改package.json
"script": {
"build": "webpack --mode development", //這里為了不壓縮代碼茧痒,用開發(fā)環(huán)境
"dev": "webpack-dev-server --open --mode development"
}
- 支持css文件
yarn add style-loader css-loader -D
// css-loader用來處理css中url的路徑
// style-loader可以把css文件變成style標(biāo)簽插入head中
// 多個(gè)loader是有順序要求的肮韧,從右往左寫,因?yàn)檗D(zhuǎn)換的時(shí)候是從右往左轉(zhuǎn)換的
module: {
rules: {
test: /\.css$/,
use: ['style-laoder', 'css-loader'],
include: path.join(__dirname, 'src'), //限制范圍旺订,提高打包速度
exclude: /node_modules/
}
}
- 支持es6弄企,react.js等
yarn add babel-loader babel-core babel-preset-env babel-preset-stage-0 babel-preset -react -D
{
test: /\.js$/,
use: {
loader: 'babel-loader',
query: {
presets: ['env', 'stage-0', 'react'] // env轉(zhuǎn)換es6 stage-0轉(zhuǎn)es7 react轉(zhuǎn)react
}
}
}
同時(shí)可以把babel配置寫到.babelrc中
- 從js中分離css
yarn add extract-text-webpack-plugin -D
{
test: /\.css$/, // 轉(zhuǎn)換文件的匹配正則
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
//如果需要,可以在 sass-loader 之前將 resolve-url-loader 鏈接進(jìn)來
use: ['css-loader']
})
},
//加上plugin
plugins: [
new ExtractTextWebpackPlugin({
filename: 'css/[name].[hash].css' //放到dist/css/下
})
]
- 支持圖片
yarn add file-loader url-loader -D
file-loader 解決css等文件中引入圖片路徑的問題
url-loader 當(dāng)圖片較小的時(shí)候會(huì)把圖片BASE64編碼区拳,大于limit參數(shù)的時(shí)候還是使用file-loader 進(jìn)行拷貝
{
// file-loader是解析圖片地址拘领,把圖片從源文件拷貝到目標(biāo)文件并且修改源文件名字
// 可以處理任意二進(jìn)制,bootstrap里的字體
// url-loader可以在文件比較小的時(shí)候樱调,直接變成base64字符串內(nèi)嵌到頁面中
{
test: /\.(png|jpg|jpeg|gif|svg)/,
use: {
loader: 'url-loader',
options: {
outputPath: 'images/', // 圖片輸出的路徑
limit: 5 * 1024
}
}
},
// 同時(shí)要處理打包圖片路徑問題约素,
output: {
publicPath: '/'
}
-
處理css3屬性前綴
yarn add postcss-loader -D { test: /\.css$/, // 轉(zhuǎn)換文件的匹配正則 // css-loader用來處理css中url的路徑 // style-loader可以把css文件變成style標(biāo)簽插入head中 // 多個(gè)loader是有順序要求的届良,從右往左寫,因?yàn)檗D(zhuǎn)換的時(shí)候是從右往左轉(zhuǎn)換的 // 此插件先用css-loader處理一下css文件 use: ExtractTextWebpackPlugin.extract({ fallback: 'style-loader', //如果需要圣猎,可以在 sass-loader 之前將 resolve-url-loader 鏈接進(jìn)來 use: ['css-loader', 'postcss-loader'] }) },
建立.postcssrc.js文件
module.exports = {
"plugins": {
// to edit target browsers: use "browserslist" field in package.json
"autoprefixer": {
"browsers": [
"ie >= 9",
"ff >= 30",
"chrome >= 34",
"safari >= 7",
"opera >= 23"
]
}
}
}
- 調(diào)試打包的代碼 webapck通過配置可以自動(dòng)給我們source maps文件士葫,map文件是一種對(duì)應(yīng)編譯文件和源文件的方法
devtool: 'eval-source-map'
1. source-map 把映射文件生成到單獨(dú)的文件,最完整最慢
2. cheap-module-source-map 在一個(gè)單獨(dú)的文件中產(chǎn)生一個(gè)不帶列映射的Map
3. eval-source-map 使用eval打包源文件模塊,在同一個(gè)文件中生成完整sourcemap
4. cheap-module-eval-source-map sourcemap和打包后的JS同行顯示送悔,沒有映射列
- 壓縮js
webpack --mode production 會(huì)壓縮慢显,可以忽略下面
yarn add uglifyjs-webpack-plugin -D
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
new UglifyjsWebpackPlugin(),
- 壓縮css
webpack --mode production 會(huì)壓縮,可以忽略下面
{
test: /\.css$/, // 轉(zhuǎn)換文件的匹配正則
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-laoder',
options: {minimize: true}
},
'postcss-loader'
]
})
},
- 清空打包輸出目錄
yarn add clean-webpack-plugin -D
const CleanWebpackPlugin = require('clean-webpack-plugin')
new CleanWebpackPlugin([path.join(__dirname, 'dist')]),
- 區(qū)分環(huán)境變量 許多 library 將通過與 process.env.NODE_ENV 環(huán)境變量關(guān)聯(lián)欠啤,以決定 library 中應(yīng)該引用哪些內(nèi)容荚藻。我們可以使用 webpack 內(nèi)置的 DefinePlugin 為所有的依賴定義這個(gè)變量:
"scripts": {
"build": "cross-env NODE_ENV=production webpack --mode development", // 設(shè)置NODE_ENV為production
"dev": "webpack-dev-server --open --mode development "
},
new webpack.DefinePlugin({
NODE_ENV:JSON.stringify(process.env.NODE_ENV)
})
在全局都有NODE_ENV這個(gè)變量,當(dāng)yarn run build,時(shí),NODE_ENV = 'production'
- 暴露全局變量
new Webpack.ProvidePlugin({
'$': 'jquery'
}),
- resolve解析
extension: 指定extension之后可以不用在require或是import的時(shí)候加文件擴(kuò)展名,會(huì)依次嘗試添加擴(kuò)展名進(jìn)行匹配
resolve: {
//自動(dòng)補(bǔ)全后綴跪妥,注意第一個(gè)必須是空字符串,后綴一定以點(diǎn)開頭
extension: ['', '.js', '.json', '.css']
}
alias: 配置別名可以加快webpack查找模塊的速度
resolve: {
alias: {
'bootstrap': 'bootstrap/dist/css/bootstrap.css'
}
}
- 復(fù)制靜態(tài)資源
yarn add copy-webpack-plugin
const CopyWebpackPlugin = require('copy-webpack-plugin')
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, 'static'),
to: path.resolve(__dirname, 'pages/static'),
ignore: ['.*']
}
])
基礎(chǔ)就是這些吧鞋喇,代碼優(yōu)化,提高打包速度眉撵,多頁配置侦香,咱們下回分解,詳見webpack高級(jí)配置