首先安裝
第一種方式: 全局安裝 (不推薦)
npm install webpack -g
第二種方式 本地安裝
npm install webpack webpack-cli -D
-D 縮寫 development ,開發(fā)階段
首先創(chuàng)建 package.json 文件. 命令為npm init -y
我是在之前的Angular的項(xiàng)目中直接 install的 效果為:
"devDependencies": {
"@angular-devkit/build-angular": "~0.7.0",
"@angular/cli": "~6.1.4",
...
"typescript": "~2.7.2",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2"
}
在Webpack中所有文件都是模塊
-js 模塊 模塊化(AMD CMD ES6 commonjs);
打包命令為: npx webpack
會(huì)進(jìn)行打包.
默認(rèn)實(shí)在dist文件下邊打包main.js
新的文件夾中 效果為:
默認(rèn)打包效果是在dist中打包成main.js 文件.
加了webpack.config.js 文件之后的效果為 build下邊的build.js 文件.
//基于node 的遵循commonjs規(guī)范
let path = require('path');
module.exports = {
entry:'./src/index.js',//入口
output:{
filename:'build.js', //起個(gè)名 默認(rèn)的是main.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{},//開發(fā)服務(wù)器
module:{},//模塊配置
plugins:[],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
我們想動(dòng)態(tài)一點(diǎn). 首先
然后安裝webpack-dev-server
命令為
npm install webpack-dev-server -D
修改package.json文件
{
"name": "Webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack",
"start":"webpack-dev-server"
},
"keywords": [],
"author": "",
"license": "ISC"
}
build 和start 是新加的.
那么在命令行里直接 運(yùn)行npm run start
有沒(méi)有感覺很熟悉? 這不就是Angular 里邊 的ng serve 之后出來(lái)的么...
其實(shí)Angular 本身的 打包命令. ng build 也是基于webpack 實(shí)現(xiàn).
然后打開瀏覽器運(yùn)行l(wèi)ocalhost:8080 就是這樣
接著對(duì)devServer配置
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true//自動(dòng)打開瀏覽器
//hot:true
}
這時(shí)候再運(yùn)行npm run start 命令會(huì)默認(rèn)打開瀏覽器并且是3000端口. 這時(shí)候需要在項(xiàng)目中有build 文件夾, 沒(méi)有的話 顯示不了Cannot GET / 并在console中顯示 404 請(qǐng)求不到資源
現(xiàn)在還沒(méi)有html看不見頁(yè)面 , 需要實(shí)現(xiàn)功能是這樣, 打包之后的js 文件可以直接被引入到在src 下邊創(chuàng)建 的index.html. index.html可以自動(dòng)的引入打包之后的那個(gè)js 文件.
,有需要還可以向index.html中傳值 .
src目錄中創(chuàng)建index.html
接著安裝 npm install html-webpack-plugin -D
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry:'./src/index.js',//入口
output:{
filename:'build.[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true//自動(dòng)打開瀏覽器
//hot:true
},//開發(fā)服務(wù)器
module:{},//模塊配置
plugins:[new HtmlWebpackPlugin({
//打包html 插件
template:'./src/index.html',
hash:true,
minify:{
removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
collapseWhitespace:true//不換行,
},
title:'this is title from webpack configuration'
})],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
index.html 代碼如下
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h1>Welcome to my home</h1>
</body>
</html>
實(shí)現(xiàn)效果如下
下一個(gè)需求:
目前實(shí)現(xiàn)的功能每次打包都生成一個(gè)新的js文件, 雖然能引到最新的那個(gè) 但是之前生成的那個(gè) 沒(méi)有刪除. 按道理說(shuō), 打包之后的文件,每次新打包的時(shí)候都需要重新生成一遍.
接著引入插件 npm install clean-webpack-plugin -D
引入clean-webpack
let CleanWebpackPlugin = require('clean-webpack-plugin');
在plugins數(shù)組里邊添加
new CleanWebpackPlugin([
'./build'
]),
接著下一個(gè)需求.
現(xiàn)在只有一個(gè)入口index.js,而且在index.js 中引入了a.js . 如果index.js 和a.js 相互獨(dú)立, 那么打包之后, 只能把index.js 里邊的內(nèi)容打進(jìn)去, 結(jié)果a.js 的內(nèi)容就丟了 .咋整 ?
entry:['./src/index.js','./src/a.js'],
換entry 的內(nèi)容. 這樣兩個(gè)都可以打包進(jìn)去.
接著下一個(gè)需求 ,實(shí)現(xiàn)生成兩個(gè)index.html 名字不一樣. 一個(gè)叫a.html 另外一個(gè)叫b.html, a.html引入a.js, b.html 引入b.js ,但是模板都用的是index.html
首先entry 寫多個(gè). output 中 filename改成[name] 其次多個(gè)HtmlWebpackPlugin , 并能通過(guò)chunks 知道是哪個(gè)入口
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
//entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
entry:{
index:"./src/index.js",
a:"./src/a.js"
},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true//自動(dòng)打開瀏覽器
//hot:true
},//開發(fā)服務(wù)器
module:{},//模塊配置
plugins:[
new CleanWebpackPlugin([
'./build'
]),
new HtmlWebpackPlugin({
//打包html 插件
filename:"a.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
chunks:["a"],
title:'this is title from webpack configuration'
}),
new HtmlWebpackPlugin({
//打包html 插件
filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
chunks:["index"],
title:'this is title from webpack configuration'
})],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
下一個(gè)需求, 熱更新. 不用每次更改一點(diǎn)東西就刷新頁(yè)面.
配置文件中 導(dǎo)入模塊
let webpack = require("webpack");
plugins里邊添加
new webpack.HotModuleReplacementPlugin(),
在index.js 代碼如下
let str = require("./a.js");
if(module.hot){
module.hot.accept();
}
document.getElementById("title").innerHTML = str;
下個(gè)需求. html里邊不可能沒(méi)有css 文件 ,創(chuàng)建index.css 文件, 然后就是想辦法把他引進(jìn)來(lái).
在index.js里邊引入index.css
import './index.css'
結(jié)果報(bào)錯(cuò)如下
webpack 默認(rèn)只支持js 模塊, 別的不認(rèn)識(shí)
解析模塊 需要loader
接著npm install style-loader css-loader
要是用less 就是less-loader
sass sass-loader
引入less 的時(shí)候 需要些npm install less less-loader
要不 引的不夠.
在index.js 中 引入兩個(gè)css 文件
import './index.css'
import './style.less'
后引入的會(huì)替換之前引入的效果.
在config 文件中對(duì)模塊進(jìn)行配置
module:{
rules:[//從右往左寫
{
test:/\.css$/,use:[
{loader:'style-loader',options:'' } ,
{loader:'css-loader'}
]},
{
test:/\.less$/,use:[
{loader:'style-loader',options:'' } ,
{loader:'css-loader'},
{loader:'less-loader'}
]}
]
},
這樣可以用css 和less 但是有一個(gè)問(wèn)題, 這時(shí)候所有的css 樣式都打包到了js 文件中,
這不是我們想要的效果 .
接著安裝插件:
npm install extract-text-webpack-plugin@next mini-css-extract-plugin -D
版本的問(wèn)題, 兩個(gè)都安一下.
主要的目的是為了從js 中抽離出css
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let webpack = require("webpack");
let ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
//entry:{
//index:"./src/index.js",
//a:"./src/a.js"
//},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true,//自動(dòng)打開瀏覽器
hot:true
},//開發(fā)服務(wù)器
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: ExtractTextWebpackPlugin.extract({
use:[
{loader:'css-loader'}
]
})},
{
test:/\.less$/, use: ExtractTextWebpackPlugin.extract({
use:[
{loader:'css-loader'},
{loader:'less-loader'}
]
})}
]
},//模塊配置
plugins:[
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin([
'./build'
]),
new ExtractTextWebpackPlugin({
filename:"css/index.css"
}),
new HtmlWebpackPlugin({
//打包html 插件
//filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
//chunks:["index"],
title:'this is title from webpack configuration'
})],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
成功:
新需求又來(lái)了
剛才可以滿足css 抽離,但是用戶想把css 和less 的樣式分開抽離 ,即生成不同的樣式文件. css 的css.css , less 的抽離為less.css
配置文件為
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let webpack = require("webpack");
let ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let cssExtract = new ExtractTextWebpackPlugin("css/css.css");
let lessExtract = new ExtractTextWebpackPlugin("css/less.css");
module.exports = {
entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
//entry:{
//index:"./src/index.js",
//a:"./src/a.js"
//},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true,//自動(dòng)打開瀏覽器
hot:true
},//開發(fā)服務(wù)器
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: cssExtract.extract({
use:[
{loader:'css-loader'}
]
})},
{
test:/\.less$/, use: lessExtract.extract({
use:[
{loader:'css-loader'},
{loader:'less-loader'}
]
})}
]
},//模塊配置
plugins:[
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin([
'./build'
]),
//new ExtractTextWebpackPlugin({
// filename:"css/index.css"
//}),
cssExtract,
lessExtract,
new HtmlWebpackPlugin({
//打包html 插件
//filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
//chunks:["index"],
title:'this is title from webpack configuration'
})],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
但是這樣還是有一個(gè)問(wèn)題.
因?yàn)榘裞ss 給抽到不同的文件里邊了,并在index.html中引入 不同的css 文件, 熱更新就沒(méi)了 , 只能手動(dòng)強(qiáng)制刷新.
而且還考慮一個(gè)問(wèn)題. 其實(shí)這個(gè)抽取出來(lái)的過(guò)程, 只在上線的時(shí)候 需要, 本地的時(shí)候最好還是能保持熱更新. 那就在dev開發(fā)階段用style.loader 雖然會(huì)把樣式放到style標(biāo)簽里邊.
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let webpack = require("webpack");
let ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let cssExtract = new ExtractTextWebpackPlugin({
filename:"css/css.css",
disable:true
});
let lessExtract = new ExtractTextWebpackPlugin({
filename:"css/less.css",
disable:true
});
module.exports = {
entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
//entry:{
//index:"./src/index.js",
//a:"./src/a.js"
//},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true,//自動(dòng)打開瀏覽器
hot:true
},//開發(fā)服務(wù)器
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: cssExtract.extract({
fallback:'style-loader',
use:[
{loader:'css-loader'}
]
})},
{
test:/\.less$/, use: lessExtract.extract({
fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'less-loader'}
]
})}
]
},//模塊配置
plugins:[
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin([
'./build'
]),
//new ExtractTextWebpackPlugin({
// filename:"css/index.css"
//}),
cssExtract,
lessExtract,
new HtmlWebpackPlugin({
//打包html 插件
//filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
//chunks:["index"],
title:'this is title from webpack configuration'
})],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
接著還是不滿意.因?yàn)閏ss 文件里邊可能開發(fā)的時(shí)候?qū)懥撕芏鄻邮? 但是這些樣式 根本沒(méi)有用到. 打包之后徒增體積,影響速度.
npm install purifycss-webpack purify-css glob -D
配置如下
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let webpack = require("webpack");
let ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let cssExtract = new ExtractTextWebpackPlugin({
filename:"css/css.css",
//disable:true
});
let lessExtract = new ExtractTextWebpackPlugin({
filename:"css/less.css",
//disable:true
});
let glob = require('glob');
let PurifyCssWebpack = require("purifycss-webpack");
module.exports = {
entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
//entry:{
//index:"./src/index.js",
//a:"./src/a.js"
//},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true,//自動(dòng)打開瀏覽器
hot:true
},//開發(fā)服務(wù)器
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: cssExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'}
]
})},
{
test:/\.less$/, use: lessExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'less-loader'}
]
})}
]
},//模塊配置
plugins:[
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin([
'./build'
]),
//new ExtractTextWebpackPlugin({
// filename:"css/index.css"
//}),
cssExtract,
lessExtract,
new HtmlWebpackPlugin({
//打包html 插件
//filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
//chunks:["index"],
title:'this is title from webpack configuration'
}),
//沒(méi)用的css 會(huì)消除掉.
new PurifyCssWebpack({
paths:glob.sync(path.resolve('src/*.html'))
})
],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}
下一個(gè)需求.
我們之前寫過(guò)的
transform: translateX(-50%);
-ms-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-webkit-transform: translateX(-50%);
-o-transform: translateX(-50%);
每次都這么寫感覺特別費(fèi)勁. 直接寫一個(gè)transform:translateX(-50%)
這樣的多簡(jiǎn)單
接著裝插件 ,需要自動(dòng)加前綴的功能
npm install postcss-loader autoprefixer -D
需要新建一個(gè)postcss.config.js 文件
如下
module.exports = {
plugins:[
require("autoprefixer")
]
}
webpack 配置文件更新如下
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: cssExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'postcss-loader'}
]
})},
{
test:/\.less$/, use: lessExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'less-loader'},
{loader:'postcss-loader'}
]
})}
]
},
還有一個(gè)需求, 我們項(xiàng)目中有部分的文件不需要打包, 需要保持原樣傳到server 上.
npm install copy-webpack-plugin -D
今天最后代碼
/**
* Created by admin on 2018/10/14.
*/
//基于node 的遵循commonjs規(guī)范
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let CleanWebpackPlugin = require('clean-webpack-plugin');
let webpack = require("webpack");
let ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
let cssExtract = new ExtractTextWebpackPlugin({
filename:"css/css.css",
//disable:true
});
let lessExtract = new ExtractTextWebpackPlugin({
filename:"css/less.css",
//disable:true
});
let glob = require('glob');
let PurifyCssWebpack = require("purifycss-webpack");
let CopyWebpackPlugin = require("copy-webpack-plugin");
module.exports = {
entry:'./src/index.js',//入口
//entry:['./src/index.js','./src/a.js'],
//entry:{
//index:"./src/index.js",
//a:"./src/a.js"
//},
output:{
filename:'[name].[hash:8].js', //起個(gè)名 默認(rèn)的是main.js .hash 取八位 eg: build.e6472a7e.js
//這個(gè)路徑必須是絕對(duì)路徑
path:path.resolve('./build')
},//出口
devServer:{
contentBase:'./build',
port:3000,
compress:true,//服務(wù)器壓縮
open:true,//自動(dòng)打開瀏覽器
hot:true
},//開發(fā)服務(wù)器
module:{
rules:[//從右往左寫
{
test:/\.css$/, use: cssExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'postcss-loader'}
]
})},
{
test:/\.less$/, use: lessExtract.extract({
//fallback:'style-loader',
use:[
{loader:'css-loader'},
{loader:'less-loader'},
{loader:'postcss-loader'}
]
})}
]
},//模塊配置
plugins:[
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin([
'./build'
]),
//new ExtractTextWebpackPlugin({
// filename:"css/index.css"
//}),
cssExtract,
lessExtract,
new HtmlWebpackPlugin({
//打包html 插件
//filename:"b.html",
template:'./src/index.html',
hash:true,//在打包后的文件加一個(gè)后綴: eg: build.e6472a7e.js?e6472a7ea8e1cb380cef
minify:{
//removeAttributeQuotes:true,//移除dom屬性的雙引號(hào)
//collapseWhitespace:true//不換行,
},
//chunks:["index"],
title:'this is title from webpack configuration'
}),
//沒(méi)用的css 會(huì)消除掉.
new PurifyCssWebpack({
paths:glob.sync(path.resolve('src/*.html'))
}),
new CopyWebpackPlugin([
{
//告訴從哪考到哪
from:'./src/doc',
to:"public"
}
])
],//插件的配置
mode:'development',//可以更改模式
resolve:{}//配置解析
}