一周伦、理解Webpack的打包過程
1.創(chuàng)建一個test目錄并進(jìn)入
mkdir test && cd test
- npm 初始化傻唾,生成package.json文件
npm init -y //如果不加-y就一路回車
- 安裝webpack
npm install webpack --save-dev //會安裝到test目錄下node_modules目錄下面
4.在根目錄下新建一個hello.js文件并用webpack進(jìn)行打包
touch hello.js
./node_modules/.bin/webpack hello.js hello.bundle.js
這樣就完成了一次最簡單的打包谷饿,./node_modules/.bin/webpack就是安裝在test目錄下的webpack命令惶我。雖然完成了一次極簡的打包,但是這樣是遠(yuǎn)遠(yuǎn)不夠的博投。
5.試著多添加一個world.js文件
world.js
export { world } //寫一個函數(shù)并將它暴露出來
function world() {
alert('我是world')
}
hello.js內(nèi)容
require('./world.js') //引入world.js
world() 在hollo.js中執(zhí)行world.js中的函數(shù)
運(yùn)行打包命令
./node_modules/.bin/webpack hello.js hello.bundle.js
成功打包绸贡。這樣,hello.js就是入口文件,其它文件諸如world.js都通過ES6/Commom.js/AMD語法引入到這個入口文件里恃轩,然后打包成一個文件hello.bundle.js文件结洼。這樣,就可以實現(xiàn)模塊化編程叉跛,不僅僅是JS文件松忍,CSS、SASS筷厘、LESS鸣峭、VUE等都可以引入到入口文件里,再進(jìn)行打包酥艳,這就是模塊化摊溶,而需要做的,就是安裝針對不同類型的loader充石。
二莫换、配置文件
上面寫的內(nèi)容主要是理解,接下來為了更好地發(fā)揮webpack的功能骤铃,我們重新整理和配置webpack的文件
1. 刪除之前根目錄下除了node_modules和json文件之外的所有其它文件拉岁。
2. 在test目錄下新建src目錄,所有的源碼都放在這里惰爬,在src目錄下喊暖,分別新建script目錄和style目錄用來存放
js文件和樣式文件。
3. 在test目錄下新建dist目錄撕瞧,作為打包以后的輸出文件的存放目錄陵叽。
4. 在test目錄下新建index.html文件,用script標(biāo)簽引入dist/bundle.js文件丛版。
5. 在test目錄下新建webpack.config.js作為配置文件巩掺。
三、配置webpack.config.js
webpack.config.js是webpack的配置文件页畦,在我們運(yùn)行webpack打包命令的時候锌半,它會自動去尋找這個文件,然后根據(jù)這個文件里的具體配置來進(jìn)行打包寇漫。
- webpack.config.js內(nèi)容
var path = require('path') //引入path
module.exports = { //注意這里是exports不是export
entry: './src/script/main.js', //入口文件
output: { //輸出文件
path: path.resolve(__dirname,'dist'), //輸出文件的目錄
filename: 'bundle.js' //輸出文件的名稱
}
}
運(yùn)行打包命令
./node_modules/.bin/webpack //有了配置文件以后直接輸入命令即可刊殉,它會自動找配置文件
如果我們有多個配置文件,比如還有一個webpack.dev.config.js文件州胳,webpack默認(rèn)運(yùn)行的文件是webpack.config.js记焊,但是想要讓它運(yùn)行另一個配置文件應(yīng)該怎么辦呢?辦法如下:
./node_modules/.bin --config webpack.dev.config.js //使用--config參數(shù)就行了
這里還有一個問題栓撞,就是每次運(yùn)行webpack命令遍膜,都要寫./node_modules/.bin/webpack這樣一長串碗硬,可不可心簡化呢?當(dāng)然是可以的。只需要package.json文件里寫一個script就行了。
這樣囱稽,只要我們運(yùn)行npm build
就相當(dāng)于執(zhí)行了webpack命令,而npm會非常智能地從node_modules里找這個命令翰意。
當(dāng)然,這個命令還可以繼續(xù)優(yōu)化信柿。我們發(fā)現(xiàn)冀偶,每次打包以后,bundle.js的文件都會非常大渔嚷,如果讓它變小呢进鸠?那就使用./node_modules/.bin/webpack -p
這個命令 -p就是出版的意思,這樣它就會自動壓縮形病,所以我再改一下package.json文件客年。
這樣,再次運(yùn)行npm run build
就相當(dāng)于運(yùn)行了./node_modules/.bin/webpack -p
了漠吻。我們可以明顯地發(fā)現(xiàn)量瓜,bundle.js的體積被壓縮了。
- 運(yùn)行打包命令時可以使用的其它參數(shù)
./node_modules/.bin/webpack --progress --display-modules --display-reason --colors //看到過程侥猩、顯示模塊、顯示打包原因抵赢、看到顏色變化
四欺劳、多頁面進(jìn)行打包時webpack.config.js的配置方法
var path = require('path')
module.exports = { //注意這里是exports不是export
entry: { //這里entry寫成了對象,這樣的話就可以寫多個入口文件分別打包
main: './src/script/main.js',
a: './src/script/a.js'
},
output: {
path: path.resolve(__dirname,'dist'),
filename: '[name]-[hash]-bundle.js' //這里[name]-[hash]-bundle.js通過name和hash來區(qū)分不同的
}
}
這樣的話铅鲤,就可以把多個入口文件打包成不同文件名和不同哈希值的JS文件划提,并且都放在dist目錄下。
但是這里卻有一個很大的問題邢享,那就是每次打包都會新生成一次打包文件鹏往,這些文件如何放到HMTL里呢?總不能每打一次包就手動更改一次吧骇塘?為了解決這個問題伊履,就需要使用一個插件:html-webpack-plugin。用這個插件動態(tài)生成HTML文件并且把相應(yīng)的打包文件放到里面款违。
npm安裝插件
npm install html-webpack-plugin --save-dev
改寫webpack.config.js文件:
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin') //Common.js語法引入插件
module.exports = { //注意這里是exports不是export
entry: {
main: './src/script/main.js',
a: './src/script/a.js'
},
output: {
path: path.resolve(__dirname,'dist'),
filename: '[name]-[hash]-bundle.js'
},
plugins: [ //使用插件
new HtmlWebpackPlugin({ //因為要生成兩個不同的html文件唐瀑,所以要new兩次
filename: 'index.html', //filename指定生成html文件名
template: 'index.html', //template指定打包參照的模板
chunks: ['main'] //chunks參數(shù)指定要把哪個入口文件打包后嵌入到HTML里,可以是一個也可以是多個
}),
new HtmlWebpackPlugin({
filename: 'a.html',
template: 'a.html',
chunks: ['a']
})
]
}
運(yùn)行打包命令后插爹,我們可以看到在dist目錄下哄辣,生成兩個打包的JS文件和HTML文件请梢,而打開a.html里面就內(nèi)嵌了a開頭的打包的js文件。而參照的template就是根目錄下index.html和a.html文件力穗。
五毅弧、使用loaders來加載資源(這一部分很重要)
webpack可以將各種各樣的資源,包括CSS/SASS/LESS/PNG/JPG/JPEG等都進(jìn)行打包当窗,只是它需要應(yīng)用不同的loader够坐。
安裝loaders
npm install --save-dev babel-loader babel-core babel-preset-es2015 //這是將es6轉(zhuǎn)換為es5所必須的
npm install --save-dev postcss-loader css-loader style-loader autoprefixer cssnano //安裝相應(yīng)loader和插件
npm install --save-dev less less-loader //安裝less和less-loader
npm install --save-dev sass sass-loader //安裝sass和sass-loader
npm install --save-dev file-loader url-loader
在使用postcss-loader的時候有點復(fù)雜,先在要目錄下新建一個postcss.config.js文件超全,如下:
module.exports = {
plugins: { //這里可以使用各種各樣的插件咆霜,postcss非常強(qiáng)大
'autoprefixer': {}, //這個插件用來給CSS文件添加前綴
'cssnano': {} //這個插件用來壓縮CSS
}
}
在webpack.config.js的配置文件配置loader:
var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = { //注意這里是exports不是export
entry: {
main: './src/script/main.js',
a: './src/script/a.js'
},
output: {
path: path.resolve(__dirname,'dist'),
filename: '[name]-[hash]-bundle.js'
},
module: {
loaders: [ //loaders在這里
{ test: /\.js$/, //針對js文件里可能出現(xiàn)的es6語法轉(zhuǎn)換
exclude: path.resolve(__dirname, 'node_modules'), //不檢測的路徑,這里用path改為了絕對路徑
include: path.resolve(__dirname, 'src'), //檢測的路徑嘶朱,注意這里是絕對路徑蛾坯,寫相對路徑會報錯。
loader: 'babel-loader',
query: {
presets: ['es2015'] //這個參數(shù)可以寫在這里疏遏,也可以在根目錄下建一個.babelrc或者寫在package.json里
}
},
{
test:/\.css$/,
use: [ //這里寫法和上面不太一樣脉课,但是效果相同
{loader: 'style-loader' }, //效果依然是從右往左,先是postcss-loader
{loader: 'css-loader', options: {importLoaders: 1}}, //這個css-loader寫了一個參數(shù)财异,是為了讓@import 進(jìn)來的CSS也同樣可以通過postcss-loader
{
loader: 'postcss-loader',
options: {
plugins: (loader) => [
require('autoprefixer')({ broswers: ['last 5 versions'] }), //這里給插件添加參數(shù)
require('cssnano')()
]
}
}
]
},
{
test: /\.less$/,
loader: 'style-loader!css-loader!postcss-loader!less-loader' //這里postcss-loader必須放在less和css之間
},
{
test: /\.scss$/,
loader: 'style-loader!css-loader!postcss-loader!sass-loader'
},
{
test: /\.(jpg|png|gif|svg$)/, //對于一些圖片文件的加載倘零,可以使用file-loader和url-loader
use: [ //對于CSS中的url可以正常加載沒問題,對于組件里的就需要用到require語法
{ //如果是在根目錄index.html那個img的話戳寸,那就沒辦法了呈驶,要么轉(zhuǎn)換成背景圖片,要么就使用import導(dǎo)入到入口的JS文件里疫鹊,再用JS方法加上去
// loader: 'file-loader',
loader: 'url-loader', //url-loader和file-loader的區(qū)別在于袖瞻,可以指定一個limit參數(shù),小于它就用base-64位編碼
options: {
limit: 200000,
// name: 'images/[name].[ext]',
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
filename: 'a.html',
template: 'a.html',
chunks: ['a']
})
]
}
對于index.html里圖片url路徑的問題拆吆,要么轉(zhuǎn)化成背景圖片聋迎,要么import到入口JS文件里再用JS的辦法添加,其它沒有辦法枣耀。