您好,登錄后才能下訂單哦!
Webpack在生產環境中有一個重要的作用就是減少http的請求數,就是把多個文件打包到一個js里,這樣請求數就可以減少好多
一、安裝
1、先裝好node和npm,因為webpack是一個基于node的項目。然后npm install -g webpack webpack-cli
全局安裝webpack webpack-cli
2、新建項目文件夾,比如webpack_demo,然后新建一個package.json的文件在項目根目錄下
npm init //詢問一些問題:按回車選擇默認值 自動生成文件package.json
npm i webpack webpack-cli--D //這行命令中, i 是 install 的縮寫。 --D 是 --save-dev 的縮寫。
(--save-dev作用是安裝的插件的同時,將插件名寫入package.json的devDependencies列表中)
目前是開發環境,所以需要加上-dev,用戶運行不需要依賴這個包
如果用戶運行需要依賴這個包,那么就不加-dev,直接是--save,保存到生產環境
需要補充的是,剛才輸入的 --save-dev 的含義是:
①將所安裝的包分類到開發模式下
②將安裝過的包寫入到 package.json 配置文件
至此,webpack安裝完成
3、在項目根目錄下,建立
項目目錄:
./index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./dist/main.js"></script>
<!-- src引入的文件將在接下來由 webpack 打包創建 -->
</body>
</html>
./src/index.js:
import {name} from './init';//引入 init.js 存于 name , (js后綴可以省略)
alert(name);
./src/init.js:
var name = "newApp";
export {//ECMAScript 6 語法 , 向外暴露接口供其他文件調用時使用
name//將變量 name 指定為向外暴露成員
};
4、執行打包(直接打包,沒有配置文件的情況下),上面多個文件文件執行打包:webpack
5、在package.json里面配置
可以在在package.json文件的"scripts"屬性下增加了"build"屬性,即
"build": "webpack --mode production --progress --display-modules --colors --display-reasons"
這樣使用npm run build,即可執行webpack打包
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode deveplopment",
"build": "webpack --mode production"
}
就可以在命令行使用npm run dev執行打包操作了
不管有沒有使用index.js,都會打包該文件放到main.js里面,這是沒有配置文件的情況下,默認入口文件是index.js,如果沒有創建index.js,那么打包就會報錯
如果有配置文件,那么就嚴格按照配置文件配置的入口文件來
我們先創建src文件,還有一個dist文件,存放默認的打包生成的文件,然后在src里再創建index.js文件
這樣就可以使用npm run dev進行打包了
6、總結:
7、webpack的一些相關命令
如果我們更改我們寫的代碼的時候,就需要重新進行打包,那就是更改一次又手動進行打包一次,那是很麻煩的,所以我們可以使用如下命令監聽這個事件,源文件一更新,就會進行自動打包;一開始watch時關閉地,我需要將它打開:npx webpack --mode development --watch
注意: 這個命令只是單純監聽了默認的打包路徑,也就是能監聽到src下index.js的變化,也能夠隨將變化時進行保存刷新后其自動打包,但是,并不能監聽到demo.js. 還有就是你的執行這個命令的時候,它必需屬于一直監聽的狀態, 如果被停止了,那監聽狀態也停止.
二、下面介紹使用配置文件進行打包
1、創建webpack.config.js
舉例:
const path = require('path');
module.exports = {
entry: './src/index.js', //入口文件的配置項
output: { //出口文件的配置項
path: path.resolve(__dirname, 'dist'), //dist目錄所在的絕對路徑
filename: 'main.js'
},
module: {//配置 loader 模塊:例如解讀CSS,圖片如何轉換,壓縮
rules: [//相關規則寫在這里
{
test: /\.css$/,//正則表達式:根據后綴為 .css 的文件來匹配 css 文件
use: [//匹配搭配 css 文件后,打包時使用以下 loader 來處理文件
{ loader: 'style-loader' },//loader 名稱
{
loader: 'css-loader',//loader 名稱
options: {
modules: true
}
}
]
}
]
},
plugins:[], //插件,用于生產模版和各項功能
mode: 'development' //打包模式,默認生產者模式,
devServer:{} //配置webpack開發服務功能
};
2、在當前目錄下(package.json所在文件夾)執行:npx webpack,即可自動執行打包
3、各種參數說明:
4、如果入口文件有多個,如果output只定義一個出口文件,那么所有的入口文件都會被打包到這一個出口文件;如果想各自生成自己對應的出口文件,那么就得重新配置出口文件,如:
const path = require('path');
module.exports = {
entry:{
main:'./src/script/main.js',
a:'./src/script/a.js'
},
output: { //出口文件的配置項
path: path.resolve(__dirname, 'dist'), //dist目錄所在的絕對路徑
filename: '[name]-[hash]-[chunkhash].js' //[name]:名字和入口文件一樣 【hash】:隨機生成的本次打包的hash值 [chunkhash]:要打包文件的版本號,除非文件修改了,否則都是不變的
}
};
5、打包過后的文件名是變化的,那么在index.html中引入該文件,難道每次都需要修改路徑名稱嗎,可以使用插件來自動生成:npm install html-webpack-plugin --save-dev
在webpack.config.js中
var htmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path');
module.exports = {
entry:{
main:'./src/script/main.js',
a:'./src/script/a.js'
},
output: { //出口文件的配置項
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name]-[hash]-[chunkhash].js' ,
publicPath:'static' //當項目需要上線時,加上這個,那么打包后生成的js文件,前面都會加上static,如:<script type="text/javascript" src="static/js/0e8f76480769da375fb2.js"></script></body>
},
plugins:[
new htmlWebpackPlugin({
template:'index.html', //以根目錄下面的index.html為模板文件進行更新
filename:'index-[hash].index', //生成的html文件的名稱包含hash值,自定義生成的html文件名,這樣每次都會生成一個不同hash的 index文件,不建議這樣使用,直接是index.html就好,默認就是index.html,可以不用設置
inject:'head', //打包后的js文件放置于頭部,即</head>上面
title:'webpack is good', //設置html的title,在模板文件使用:<title><%= htmlWebpackPlugin.options.title %></title> 獲取到
minify:{ //上線前壓縮index.html文件
removeComments:true, //刪除注釋
collapseWhitespace:true //刪除空格
}
})
]
};
這樣,就在輸出路徑dist下,生成了index.html(以根目錄下的index為模板),并且也把打包后的js文件引入進去了,全自動,在filename后面加上js/,這樣就使得js文件都打包到dist/js目錄下,而html文件是直接打包到dist目錄下
6、loader,和plugin不同,是專門用來處理資源文件,如轉es6,less、圖片壓縮、圖片轉base64等的處理
★轉es6
首先安裝babel:npm install -D babel-loader babel-core babel-preset-env
然后再package.json里面配置:
"babel":{
"presets": ["env"]
}
在webpack.config.js里面配置
let htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: "production",
entry: './src/index.js', //入口文件的配置項
output: { //出口文件的配置項 ,輸出路徑為dist目錄,即所有文件都要打包到該目錄下
path: path.resolve(__dirname, './dist'),
filename: 'js/bundle.js',
},
module: {//配置 loader 模塊:例如解讀CSS,圖片如何轉換,壓縮
rules: [//相關規則寫在這里
{
test: /\.js$/,//正則表達式:根據后綴為 .css 的文件來匹配 css 文件
loader:'babel-loader'
}
]
},
plugins:[
new htmlWebpackPlugin({
filename:'index.html',
template:'index.html'
})
], //插件,用于生產模版和各項功能
mode: 'development', //打包模式,默認生產者模式,
devServer:{} //配置webpack開發服務功能
};
★剛剛webpack打包提示錯誤:
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
解決:需要使用絕對路徑。
Error: Cannot find module '@babel/core'
解決:babel-loader的版本不一樣,之前的是@7.1.5版本,而現在是@8.0.0版本。所以卸載當前版本,重新安裝之前的版本
★打包css文件
首先安裝對應的loader,npm install style-loader css-loader --save-dev
webpack視所有資源都是一個模塊,所有的資源文件都可以打包到webpack中,需要在入口文件import該資源文件
比如:入口文件是index.js,在里面 import './src/style.css'
配置webpack.config.js文件
module: {//配置 loader 模塊:例如解讀CSS,圖片如何轉換,壓縮
rules: [//相關規則寫在這里
{
test: /\.js$/,//正則表達式:根據后綴為 .js 的文件來匹配 js 文件
loader:'babel-loader'
},
{
test: /\.css$/,//正則表達式:根據后綴為 .css 的文件來匹配 css 文件
loader:'style-loader!css-loader!less-loader' //css-loader使得在js里面可以處理css文件,style-loader使得js處理完的樣式插入到index.html頁面中
}
]
},
★遇見一系列錯誤,以安裝npm install babel-core@7.0.0-bridge.0 --save-dev結束,成功打包了css文件
★轉換less文件 npm install less-loader --save-dev
創建app.less文件,在入口文件引入:import './app.less'
配置webpack.config.js文件
{
test:/\.less$/,
loader:'style-loader!css-loader!less-loader'
}
★打包圖片文件 npm install file-loader --save-dev
1、在css文件中引入圖片
配置webpack.config.js文件
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'file-loader' ,
query:{
name:'img/[hash].[ext]'
}
}
默認是打包到dist目錄下,如果要想打包到dist/img下,可以添加query,如上所示。
【注意】要查看loader的用法,可以去https://www.npmjs.com/,搜索對應的loader查看用法
loader:'style-loader!css-loader!less-loader
loader的處理方式是從右到左,先處理less-loader,然后依次到左
★url-loader,可以處理圖片和文件,當原始文件大小大于指定的值的時候,會交給file-loader處理,小于指定的值的時候,會轉為base64位編碼,不再是url了,而是一段編碼
合理分配圖片,是base64嵌入頁面,還是通過http求求過來,http請求過來的圖片可以緩存,base64編碼不行
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'url-loader' ,
query:{
limit:20000, //即20k
name:'img/[hash].[ext]'
}
}
★img-webpack-loader,配合file-loader、url-loader一起使用,壓縮通過http請求的圖片大小
{
test:/\.(png|jpg|gif|svg)$/i,
loaders:[
'url-loader?limit=20000&name=img/[hash].[ext]',
'image-webpack-loader'
]
}
三、熱更新
1、在webpack.config.js里面配置devServer
devServer:{
contentBase:path.resolve(__dirname,'dist') //基本目錄結構,監聽哪里的代碼
host:'10.1.28.102', //ip地址,不建議填localhost 命令行ipconfig查看ipv4的值即是ip地址
compress:true, //服務器壓縮參數,是否啟用服務器壓縮,一般啟用
port:1717 //任何喜歡的數字
}
2、安裝服務:npm install webpack-dev-server --save-dev
3、配置package.json
"scripts": {
"server": "webpack-dev-server",
},
4、運行命令:npm run server
注意:是conteneBase,不是contentPath
運行命令是npm run server,不是webpack-dev-server
四、live-server
本地開發常常需要搭建臨時的服務,第一時間我們會想到用http-server。
但現在流行修改文件瀏覽器自動刷新hot socketing(熱拔插),如live-reload。
若想瀏覽器自動打開項目,用opener。
現在live-server實現了三個插件的所有功能,并且很簡單就能啟動一個看起來很專業的本地服務
"scripts": {
"server": "live-server ./ --port=9090"
}
然后執行 npm run server
瀏覽器會自動打開,并且當你修改本地文件,瀏覽器都會立即同步
五、案例之打包css文件
1、模塊:CSS文件打包Loaders
Loaders是Webpack最重要的功能之一,他也是Webpack如此盛行的原因。通過使用不同的Loader,Webpack可以利用腳本和工具,從而對不同的文件格式進行特定處理。
注意:所有的Loaders都需要在npm中單獨進行安裝,并在webpack.config.js里進行配置。
Loaders的配置參數:
2、打包css文件,
首先在src文件夾下,建立一個css文件夾,在文件夾下需要打包的css文件
css文件建立好后,需要引入到入口文件中,才可以打包到,這里我們引入到entry.js中。
style-loader:用來處理css文件中的url()等
安裝:npm install style-loader --save-dev
css-loader:用來將css插入到頁面的style標簽
安裝:npm install css-loader --save-dev
兩個loader都下載安裝好后,我們就可以配置我們loaders了。
修改webpack.config.js中module屬性中的配置代碼如下(三種寫法):
第一種寫法:直接用use。
module:{
rules:[
test:'/\.css$/',
use:['style-loader','css-loader']
]
}
第二種寫法:把use換成loader。
module:{
rules:[
test:'/\.css$/',
loader:['style-loader','css-loader']
]
}
第三種寫法:用use+loader的寫法:
module:{
rules:[
{
test:/\.css$/,
use:[
{
loader:'style-loader'
},
{
loader:'css-loader'
}
]
}
]
}
9、插件配置:配置JS壓縮
上線前,壓縮js代碼,通過使用插件的方式來實現
引入一個uglifyjs-webpack-plugin(JS壓縮插件,簡稱uglify)。
注意:雖然uglifyjs是插件,但是webpack版本里默認已經集成,不需要再次安裝,但是是需要引入的
在webpack.config.js里面引入
const uglify = require('uglifyjs-webpack-plugin');
引入后,在plugins配置里new一個uglify對象即可使用,
plugins:[ //注意是[],不是{}
new uglify() //后面不加分號,多個的話加逗號
]
最后,在終端命令行,使用webpack進行打包,壓縮js文件
npm run server用在開發環境,啟動服務器,是對代碼進行預覽的,此時的代碼不需要壓縮,否則無法調試
所以上面的開發完畢之后,使用下面的進行打包壓縮,然后直接上線,不需要再進行熱更新在調試什么的了
webpack是打包壓縮,用于生產環境,打包壓縮之后就上線了
webpack打包的時候發生錯誤:Error: Cannot find module 'uglifyjs-webpack-plugin'
執行即可npm install --save-dev html-webpack-plugin
在實際開發中,webpack配置文件是分開的,開發環境一個文件,生產環境一個文件
10、插件配置:HTML文件的發布
此時,將dist里面的index.html剪切到src目錄下面,并去掉我們的JS引入代碼(webpack會自動為我們引入JS),
<script src="./bundle.js" type="text/javascript" charset="utf-8"></script>
因為這才是我們真實工作的目錄文件結構。
然后配置webpack.config.js文件
引入html-webpack-plugin插件
const htmlPlugin = require('html-webpack-plugin');
再進行安裝該插件
npm install --save-dev html-webpack-plugin
在webpack.config.js文件,添加參數
plugins:[
new htmlPlugin({
minify:{
removeAttributeQuotes:true
},
hash:true,
template:'.src/index.html'
})
]
說明:
此時,完全不需要創建dist目錄,dist目錄下也不需要創建任何文件,全部webpack自動
index.html文件已經被打包到我們的dist目錄下了,并且自動為我們引入了路口的JS文件。
執行完webpack之后,文件已經被打包壓縮了,然后執行npm run server,即可在本地查看效果
11、圖片邁坑:CSS中的圖片處理
第一在src目錄下新建一個images文件夾,把圖片放入images文件夾
第二然后安裝loader:file-loader url-loader
npm install --save-dev file-loader url-loader
file-loader:解決引用路徑的問題,拿background樣式用url引入背景圖來說,我們都知道,webpack最終會將各個模塊打包成一個文件,因此我們樣式中的url路徑是相對入口html頁面的,而不是相對于原始css文件所在的路徑的。這就會導致圖片引入失敗。這個問題是用file-loader解決的,file-loader可以解析項目中的url引入(不僅限于css),根據我們的配置,將圖片拷貝到相應的路徑,再根據我們的配置,修改打包后文件引用路徑,使之指向正確的文件。
第三使用loader,記得在loader使用時不需要用require引入,使用plugins才需要使用require引入。
module:{
rules:[
{
test:/\.(png|jpg|gif)/,
use:[{
loader:'url-loader',
options:{
limit:5000
}
}]
}
]
}
之所以只引入url-loader,是因為url-loader已經包含了file-loader的功能
12、圖片邁坑:CSS分離與圖片路徑處理
12.1、把CSS從JavasScript代碼中分離出來
第一安裝extract-text-webpack-plugin插件
npm install --save-dev extract-text-webpack-plugin
第二在配置文件里引入
const extractTextPlugin = require(''extract-text-webpack-plugin);
第三在plugins配置文件里new一下
plugins:[
new extractTextPlugin('css/style.css'); //這里的css/style.css是分離后的路徑位置,位于dist目錄下
]
第四修改原來我們的style-loader和css-loader。
module:{
rules:[
{
test:/\.css$/,
use:extractTextPlugin.extract({
fallback:'style-loader',
use:'css-loader'
})
}
]
}
利用extract-text-webpack-plugin插件很輕松的就把CSS文件分離了出來,但是CSS路徑并不正確
12.2圖片路徑問題
第一在webpack.config.js 上方聲明一個對象,叫website。
var website ={
publicPath:"http://10.1.28.102:1717/"
}
第二在output選項中引用這個對象的publicPath屬性。
//出口文件的配置項
output:{
//輸出的路徑,用了Node語法
path:path.resolve(__dirname,'dist'),
//輸出的文件名稱
filename:'[name].js',
publicPath:website.publicPath
}
第三使用webpack進行打包
如何把圖片放到指定的文件夾下,如images下面
修改modules里面的圖片url-loader選項
modules:{
rules:[
test:'\/.(png|jpg|gif)\',
options:{
limit:5000,
outputPath:'/images/'
}
]
}
13、圖片邁坑:處理HTML中的圖片
第一安裝 html-withimg-loader
npm install --save-dev html-withimg-loader
第二配置webpack.config.js
{
test:'/\.(htm|html)$/i', //注意(htm|html)加括號
use:['html-withimg-loader']
}
14、給webpack增加babel支持
安裝相關依賴包
npm c install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
在webpack.config.js里面進行配置
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
options:{
presets:[
"es2015","react"
]
}
},
exclude:/node_modules/
}
但是不建議直接在webpack.config.js中進行配置,而是把配置寫在.babelrc文件里
在項目根目錄新建.babelrc文件,并把配置options寫到文件里。
.babelrc //json格式 presets-渲染器
{
"presets":["react","**es2015**"]
}
.webpack.config.js里的loader配置
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
},
exclude:/node_modules/ //不轉node_modules里面的es6語法
}
ENV:
現在網絡上已經不流行babel-preset-es2015,現在官方推薦使用的是babel-preset-env,那我們緊跟潮流
安裝最新的env
npm n install --save-dev babel-preset-env
然后修改.babelrc里的配置文件。其實只要把之前的es2015換成env就可以了。
{
"presets":["react","env"]
}
15、打包后如何調試
調試只針對于開發環境
上線前,一定要刪除devtool: 'eval-source-map',然后再進行打包,否則有安全隱患
個人意見是,如果大型項目可以使用source-map,如果是中小型項目使用eval-source-map就完全可以應對,需要強調說明的是,source map只適用于開發階段,上線前記得修改這些調試設置。
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
}
}
16、實戰技巧:開發和生產并行設置
依賴dependencies
開發環境
開發依賴devDependencies
生產環境 (上線環境)
生產依賴dependencies
npm install jquery //安裝到全局環境,本項目下面是沒有的,如果別人拷走了,那么拷走的文件里面是不包含jquery,可能會報錯
npm install jquery --save,安裝到本項目下面,并且寫入dependencies
拿到別人的項目,比如從github上下載下來了一個新項目,首先需要npm install進行初始化安裝
會搜索package.json,搜索里面的包進行安裝。如果全局里面有相關的包,那么直接就從本機全局里面拷貝,不用下載
拿到別人的項目,比如從github上下載下來了一個新項目,首先需要npm install進行初始化安裝,如果只安裝生產環境的包,那么就是npm install --production,而不是npm install
☆☆☆☆配置生產和開發環境并行
webpack.config.js是存在于node環境中,都是用node命令運行
局部安裝webpack npm install --save-dev-webpack,webpack被安裝到了項目文件夾node_modules文件夾下面
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。