起步
在此之前我們先npm init
初始化一個項目,本地安裝webpack
和webpack-cli
,然后在根目錄創建index.html
、webpack.config.js
和src
文件夾,在文件夾內再創建一個main.js
作為入口文件
准備工作完成后如圖所示:
main.js
function Component(){
var div=document.createElement('div')
div.innerHTML="來一起學習出口配置吧~"
return div
}
document.body.appendChild(Component())
index.html
<body>
<script src="./dist/bundle.js"></script>
</body>
packag.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack" //加上
},
接下來就是配置部分:webpack.config.js
輸出
配置 output
選項可以控制 webpack 如何向硬盤寫入編譯文件。
注意,即使可以存在多個入口
起點,但只指定一個輸出
配置
下面是輸出配置的幾個概念:
path
path指定資源輸出的位置,要求值必須為絕對路徑,如:
const path=require('path')
module.exports={
entry:'./src/main.js',
output:{
filename:'bundle.js',
//將資源輸出位置設置為該項目的dist目錄
path: path.resolve(__dirname, 'dist')
},
}
在Webpack 4之后,output.path已經默認為dist目錄。除非我們需要更改它,否則不必單獨配置,所以如果是webpack4以上,你可以寫成:
module.exports={
entry:'./src/main.js',
output:{
filename:'bundle.js',
},
}
filename
filename的作用是控制輸出資源的文件名,其形式為字符串。在這里我把它命名為bundle.js
,意為我希望資源輸出在一個叫bundle.js的文件中:
module.exports={
entry:'./src/main.js',
output:{
filename:'bundle.js',
},
}
打包后如圖,會自動生成一個dist
文件夾,里面有個bundle.js
文件
filename可以不僅僅是bundle的名字,還可以是一個相對路徑
即便路徑中的目錄不存在也沒關系,Webpack會在輸出資源時創建該目錄,比如:
module.exports = {
output: {
filename: './js/bundle.js',
},
};
打包后如圖:
在多入口的場景中,我們需要對產生的每個bundle指定不同的名字,Webpack支持使用一種類似模板語言的形式動態地生成文件名
在此之前,我們再去src
中創建一個新的入口文件
vender.js:
function Component(){
var div=document.createElement('div')
div.innerHTML="我是第二個入口文件"
return div
}
document.body.appendChild(Component())
webpack.config.js:
module.exports = {
entry:{
main:'./src/main.js',
vender:'./src/vender.js'
},
output: {
filename: '[name].js',
},
};
打包后如圖:
filename中的[name]
會被替換為chunk name即main和vender。因此最后會生成vendor.js
與main.js
此時如果你希望看到內容,你還需在index.html
中改下內容,將路徑對應上最后打包出來的bundle
<body>
<script src="./dist/main.js"></script>
<script src="./dist/vender.js"></script>
</body>
[問題]這時候就會有個需求了,如何讓
index.html
自動幫我們將生成的bundle添加到html中呢?這里可以用到插件 HtmlWebpackPlugin,詳細看下方
其他
除了[name]
可以指代chunk name以外,還有其他幾種模板變量可以用於filename的配置中:
- [hash]:指代Webpack此次打包所有資源生成的hash
- [chunkhash]:指代當前chunk內容的hash
- [id]:指代當前chunk的id
- [query]:指代filename配置項中的query
它們可以:控制客戶端緩存
[hash]
和[chunkhash]
都與chunk內容直接相關,如果在filename中使用,當chunk的內容改變時,可以同時引起資源文件名的更改,從而使用戶在下一次請求資源文件時會立即下載新的版本而不會使用本地緩存。
[query]
也可以起到類似的效果,但它與chunk內容無關,要由開發者手動指定。
publicPath
publicPath是一個非常重要的配置項,用來指定資源的請求位置
以加載圖片為例
import Img from './img.jpg';
function component() {
//...
var img = new Image();
myyebo.src = Img //請求url
//...
}
{
//...
query: {
name: '[name].[ext]',
outputPath: 'static/img/',
publicPath: './dist/static/img/'
}
}
由上面的例子所示,原本圖片請求的地址是./img.jpg
,而在配置上加上publicPath
后,實際路徑就變成了了./dist/static/img/img.jpg
,這樣就能從打包后的資源中獲取圖片了
publicPath有3種形式:
-
HTML相關
我們可以將publicPath指定為HTML的相對路徑,在請求這些資源時會以當前頁面HTML所在路徑加上相對路徑,構成實際請求的URL
//假設當前html地址為:https://www.example.com/app/index.html //異步加載的資源名為 1.chunk.js pubilicPath:"" //-->https://www.example.com/app/1.chunk.js pubilicPath:"./js" //-->https://www.example.com/app/js/1.chunk.js pubilicPath:"../assets/" //-->https://www.example.com/assets/1.chunk.js
-
Host相關
若publicPath的值以“/”開始,則代表此時publicPath是以當前頁面的host name為基礎路徑的
//假設當前html地址為:https://www.example.com/app/index.html //異步加載的資源名為 1.chunk.js pubilicPath:"/" //-->https://www.example.com/1.chunk.js pubilicPath:"/js/" //-->https://www.example.com/js/1.chunk.js
-
CDN相關
上面兩個都是相對路徑,我們也可以使用絕對路徑的形式配置publicPath
這種情況一般發生於靜態資源放在CDN上面時,由於其域名與當前頁面域名不一致,需要以絕對路徑的形式進行指定
當publicPath以協議頭或相對協議的形式開始時,代表當前路徑是CDN相關
//假設當前html地址為:https://www.example.com/app/index.html //異步加載的資源名為 1.chunk.js pubilicPath:"http://cdn.com/" //-->http://cdn.com/1.chunk.js pubilicPath:"https://cdn.com/" //-->https://cdn.com/1.chunk.js pubilicPath:"//cdn.com/assets" //-->//cdn.com/assets/1.chunk.js
應用
單個入口
在 webpack 中配置 output
屬性的最低要求是將它的值設置為一個對象,包括以下兩點:
filename
用於輸出文件的文件名。- 目標輸出目錄
path
的絕對路徑
module.exports={
entry:'./src/main.js',
output:{
filename:'bundle.js',
},
}
//webpack4以后dist會默認生成,於是這里省略了path
多個入口
如果配置創建了多個單獨的 "chunk",則應該使用占位符來確保每個文件具有唯一的名稱
這里用到了上面所講的filename的[name]
另外,如果想將這些資源放進指定的文件夾,可以加上path
配置
module.exports={
entry: {
main: './src/main.js',
vender: './src/vender.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist/assets' //指定打包后的bundle放在/dist/assets目錄下
}
}
// 打包后生成:./dist/assets/main.js, ./dist/assets/vender.js
HtmlWebpackPlugin
本章上方遺留的問題可以通過使用插件HtmlWebpackPlugin
解決
安裝插件
npm install --save-dev html-webpack-plugin
配置插件
const HtmlWebpackPlugin=require('html-webpack-plugin') //加載模塊
module.exports = {
entry:{
main:'./src/main.js',
vender:'./src/vender.js'
},
//添加插件
plugins:[
new HtmlWebpackPlugin({
title:'output management'
})
],
output: {
filename: '[name].js',
},
};
打包
打包完成后你會發現dist中出現了一個新的index.html
,上面自動幫我們添加所生成的資源,打開后會發現瀏覽器會展示出內容
這意味着,以后初始化一個項目就不必寫index.html
了
源碼可從這里獲取