時隔一年俭缓,我又回來了克伊。近期給團(tuán)隊(duì)的小伙伴分享webpack知識,也在此留印一下尔崔。
我們用webpage做什么答毫?
打包項(xiàng)目褥民,編譯代碼季春、本地開發(fā)
webpack在項(xiàng)目里怎么被啟動的?
在我們的package.json里面的script的指令消返,我們會對應(yīng)一條命令
"scripts": {
"start": "./node_modules/.bin/webpack-dev-server --config ./webpack.config.js --port=9090 --DEV=1 --LIVELOAD=1",
"build": "./node_modules/.bin/webpack --config ./webpack.config.js"
}
npm start去執(zhí)行了一個webpack-dev-server的命令并帶了一些參數(shù)進(jìn)去
-
為什么是執(zhí)行./node_modules/.bin/...载弄?
可能你會有這個疑問,我下載了全局的webpack撵颊,為什么要執(zhí)行node_modules里面的webpack
是因?yàn)槊總€項(xiàng)目可能所對應(yīng)的webpack版本不一樣宇攻,以免發(fā)生跨版本的錯誤,所以會執(zhí)行自己目錄里依賴的包
-
什么是webpack-dev-server倡勇?
字面意思就是在開發(fā)環(huán)境起服務(wù)逞刷,這里不細(xì)說。webpack-dev-server文檔
-
什么是--config妻熊?
我說一些常用的命令
--config 指定配置文件 --watch 文件更新時自動構(gòu)建 --display-modules 構(gòu)建時顯示信息(耗時等) --port 指定啟動端口 --mode 告知 webpack 使用相應(yīng)模式的內(nèi)置優(yōu)化夸浅。 --自定義參數(shù) 可以在自己的配置文件取到
前戲
我們通過--config參數(shù)指定了我們自定義的配置文件 webpack.config.js,我們現(xiàn)在開始編寫它
首先扔役,webpack就接收一個對象帆喇,里面配置對應(yīng)字段和規(guī)則就可以了!
module.exports = {
// 入口
entry: {},
// 出口
output: {},
}
如何執(zhí)行它亿胸,就要看package里的命令怎么寫坯钦。
還有预皇!先下載依賴 webpack webpack-cli
開始
第一步:執(zhí)行命令
"build": "./node_modules/.bin/webpack --config ./webpack.config.js --mode=production"
第二步:編寫webpack.config.js
module.exports = {
entry: {
"index": path.resolve(__dirname, './index.js')
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
},
}
第三步:npm run build
你會發(fā)現(xiàn),webpack已經(jīng)開始工作了婉刀。它把我們寫好的index.js打包到了./dist/index.js這里
臥槽吟温,這就完成了,可以跑起來了突颊。
你會問溯街,為什么我只是簡單寫了入口出口,它就可以自己給我壓縮混淆代碼了洋丐?呈昔??
注意看你package上的build命令友绝,帶了什么參數(shù)堤尾!--mode=production 這個參數(shù)是告訴webpack用哪種模式的內(nèi)置優(yōu)化,我們選擇的是生產(chǎn)環(huán)境迁客,那么它就會幫我們壓縮混淆代碼郭宝,反之,我們選擇development 開發(fā)模式的話掷漱,它只會幫我編譯打包代碼
相信到這里大家會對webpack的了解會清晰一些了粘室。那么下面我們繼續(xù)再進(jìn)階到我們真實(shí)項(xiàng)目場景里面
進(jìn)階 (入門級進(jìn)階)
先看需求:
- 我要npm start自動開啟瀏覽器,進(jìn)入開發(fā)態(tài)
- 我要編譯React
- 我要編譯less
- 我要npm run build 打包整個項(xiàng)目
接著上面的Demo我們來增加一些配置就可以了
1. 我要npm start自動開啟瀏覽器卜范,進(jìn)入開發(fā)態(tài)
這個需求的工作邏輯是衔统,先啟動一個服務(wù),然后打開瀏覽器海雪,去到對應(yīng)的地址锦爵!
通過網(wǎng)上查閱資料,我們得知
- 啟動服務(wù)用:webpack-dev-server
- 打開瀏覽器用:open-browser-webpack-plugin
先下載依賴奥裸,我們把package中的start命令改成去執(zhí)行webpack-dev-server
"start": "./node_modules/.bin/webpack-dev-server --config ./webpack.config.js --port=8801"
然后進(jìn)去webpack.config.js增加配置項(xiàng), 文檔地址
devServer: {
contentBase: path.resolve(__dirname, "dist"),
}
接著我們要去/dist目錄新建一個index.html
最后险掀,我們增加自動打開瀏覽器的配置, 從命令上獲取端口
// 引入插件
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
// 獲取端口
let argv = require('yargs').argv;
argv.port = argv.port || 9000;
// 在webpack的配置對象中新增plugins項(xiàng)
plugins: [
new OpenBrowserPlugin({ url: 'http://localhost:' + argv.port })
]
OK!我們 npm start 湾宙,一切都在我們的掌控之中樟氢,很簡單,我們完成了第一個需求O丽埠啃!
2. 我要編譯React
先下載依賴 react react-dom
然后我們進(jìn)到./index.js, 引入react
'use strict';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return (
<div>
Hello stupid guys
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
那么我們對應(yīng)的html就要改動一下畦攘,增加對應(yīng)id
<!doctype html>
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Hello World</title>
<meta name="viewport" content="width=device-width">
</head>
<body>
<div class="main-container" id="container">
正在加載...
</div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
好霸妹,我們要開始增加webpack對應(yīng)的配置項(xiàng)了
module:{
rules: [
]
}
不同類型模塊比如 js、css知押、jsx叹螟、less
那么怎么處理呢鹃骂?假設(shè)我要處理js和jsx, 這里也是接收一個對象
我們先看下有哪些常用的配置項(xiàng)
{ test: Condition }
:匹配特定條件罢绽。一般是提供一個正則表達(dá)式或正則表達(dá)式的數(shù)組畏线,但這不是強(qiáng)制的。{ use: { loader: "", options: {} } }
:指定使用一個 loader, options可以理解為是loader的選項(xiàng)
這里要重點(diǎn)說一下loader良价,到底是個什么東西寝殴,怎么用!
我們熟知的babel-loader明垢, 就是用來幫我們編譯的蚣常,將高版本的語言翻譯到同語言的低版本
不要以下載babel-loader這個依賴就可以了,它是由無數(shù)個包組成的痊银,它的幾個核心包也要一起下
<p style="color:#0099ff;fontSize:40px">我用我查閱資料后蹩腳的總結(jié)給大家大概說一下它的工作流是怎樣的</p>
當(dāng)我們輸入ES6語法后抵蚊,babel-core里面會調(diào)用babel.transform去解析,返回{ code, map, ast }溯革,
然后再根據(jù)loader中的option配置去將前面返回的AST樹翻譯成配置對應(yīng)的代碼
babel.transform(code, options) // => { code, map, ast }
for example...
var es6Code = 'let x = n => n + 1';
var es5Code = require('babel-core')
.transform(es6Code, {
presets: ['es2015']
})
.code;
// '"use strict";\n\nvar x = function x(n) {\n return n + 1;\n};'
再比如我要編譯react代碼贞绳,那么我需要配置一個預(yù)設(shè)插件去翻譯, babel-preset-react-app
理解上面這兩個配置項(xiàng)致稀,你就已經(jīng)離熟悉webpack不遠(yuǎn)了冈闭,那我們就快點(diǎn)來進(jìn)行配置吧!
module: {
rules: [
{
// 特定條件
test: /\.(js|jsx|mjs)$/,
// 指定使用 loader
use: {
loader: "babel-loader",
options: {
// 這里就是我上面說的預(yù)設(shè)插件抖单,翻譯react
// N堋!下載babel-preset-react-app依賴3舨隆躺酒!
presets: ["react", "env"],
}
},
}
]
}
這時候押蚤,就搞定了編譯React了, 我們再 npm start 蔑歌,挖槽,世界是這么的和諧揽碘!有沒有很簡單4瓮馈?
3. 我要編譯Less
我們首先會想到less-loader雳刺,我們看下它的文檔 less-loader文檔
根據(jù)我們上面的理解劫灶,我們再來看less-loader就很好懂了。下載依賴掖桦,根據(jù)它這么配置本昏,就可以跑起來了,注意還有style-loader枪汪、css-loader需要下載涌穆!
但是U颉!我們會發(fā)現(xiàn)宿稀,構(gòu)建出來并沒有css文件呀趁舀!一看dist/index.js才發(fā)現(xiàn),它把樣式打進(jìn)去js里面祝沸,那這樣不是很友好矮烹,我們希望它有個單獨(dú)的css。那么less-loader下面也有說到罩锐,通常會搭配extract-text-webpack-plugin這個插件一起使用奉狈,顧名思義,它就是抽取樣式的
那么我們繼續(xù)根據(jù)文檔使用
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const extractLess = new ExtractTextPlugin({
filename: "[name].[contenthash].css"
});
module.exports = {
...
module: {
rules: [{
test: /\.less$/,
use: extractLess.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
},
plugins: [
extractLess
]
};
下載依賴涩惑!npm i extract-text-webpack-plugin@next -D
需要下載最新版本嘹吨,對應(yīng)webpack4,不要構(gòu)建會報錯
現(xiàn)在我們新建一個less文件境氢,寫點(diǎn)樣式蟀拷,應(yīng)用到項(xiàng)目中,記得在index.html中引入哦萍聊!
然后再 npm start 问芬,我去!又搞定一個J俳啊此衅!
4. 構(gòu)建項(xiàng)目
先看package中的build命令
"build": "./node_modules/.bin/webpack --config ./webpack.config.js --mode=production"
迫不及待要build一下了!我們先試試 npm run build
檢查發(fā)現(xiàn)亭螟,css文件沒有被壓縮挡鞍!
我們把下面這個配置加到css-loader、less-loader下面就可以了预烙!
options: {
minimize: true
}
總結(jié)
靜下心整個看下來墨微,沒有想象中那么復(fù)雜吧。扁掸。翘县。可以使用它完成一個簡單項(xiàng)目的腳手架了
但是里面還有很多很多很多需要完善的谴分。
需要大家自己去里面探索~
謝謝