第一次接觸webpack是學(xué)react的時候,然而被嚇跑了,完全理解不了啊。之后學(xué)vue,把官方配置文件看了下,vue相關(guān)的配置大概了解了,也寫了一篇文章。最近看vue-ssr,又被webpack搞懵逼了,下定決心跟著文檔走了一遍。本文主要還是以配置文件字段介紹為主,畢竟用的最多還是這些。關(guān)于安裝什么的就不再介紹了。
1.首先配置文件四大塊
1.1入口
入口呢是webpack開始檢測文件的起點,用過vue的一般都只有一個入口,main.js,當然這么強悍的工具怎么可能只有這么點功能。你也可以使用多入口。
//單入口
entry:"./main.js"
//多入口數(shù)組方式
entry:['main.js'...]
//多入口對象方式
entry:{
main:'./main.js'
}
多入口兩種寫法,但是數(shù)組方式不利于擴展,推薦使用對象方式。
1.2輸出
輸出這里就可以配置一堆東西了,一個一個來。
//輸出文件的名字 可以自定義名字,也可以使用入口文件的名字只需要寫成[name].js即可,你還可以添加hash:[name].[hash].js
filename:'bundle.js'
//路徑,就是你打包之后的文件放到哪里,這里放到dist目錄中,注意,這里沒有dist目錄是會自動創(chuàng)建的
path:path.resolve(__dirname, 'dist')
//設(shè)置公共目錄
publicPath:'/dist/'
chunkFilename著重介紹下
首先它在config中可以這么寫
//id:表示一個序號,hash不必說,chunkhash:n,這里n可以自己配置,生成n位的hash,name就是文件名,具體下面介紹
chunkFileName:[id].[hash].[chunkhash:3].[name].js
這個會單獨輸出一個包,并不會跟filename中的內(nèi)容打包到一起,比如有些文件你并不想打包到主文件中,或者減輕首頁負擔,只在引入的時候才加載。
這個時候你只需要在引入文件的時候使用require.ensure來引入你需要的模塊,然后config中配置上面的信息就可以了。
require.ensure(['./add'], function(require){
add = require('./add');
},'name');//這里這個name就會跟上面的[name]同步,不寫的話就按照序號來了。
關(guān)于library和libraryTarget我也沒搞清,就不坑人了。
sourceMapFilename
當你使用sourceMap的時候你可以配置你的輸出文件名,就是這個參數(shù)
sourceMapFilename:'[file].[id].[hash].map'
1.3module
module中主要是各種loader的配置(loader是對不同文件處理的東西)
module:{
//這里是個數(shù)組
rules:[
{
//test是匹配文件的正則表達式
test:/\.js$/,
//使用loader兩種方式,loader或者use
loader:'babel-loader',
// use:'babel-loader'
//這里是做一些額外的配置,比如轉(zhuǎn)es2015
//options和query是use:[{options}]的代替
query: {
presets: ['es2015']
}
}
1.4plugin
webpack還支持各種插件,來擴展功能,當然你也可以自己寫插件,webpack本身自帶有一些插件,比如丑化代碼。其他的你只需要安裝,并new一個實例即可,這個是個數(shù)組
plugins:[
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
})
]
2.其他重要配置項
2.1devtool
這個很簡單,比如你在打包的時候,壓縮了代碼但為了調(diào)試你可以輸出sourceMap
dev:'sourceMap'
2.2resolve
這個主要是alias選項,作為優(yōu)化打包性能,在vue的官方配置中你一定見過下面這個
resolve:{
alias:{
'vue$': 'vue/dist/vue.js'
}
}
這里你可以指定引入文件的別名(vue$)以及具體路徑,這樣webpack就不用在目錄中一層一層的查找。
在resolve中你還可以配置下面兩項
aliasFields:['browser'],//默認解析規(guī)范
extensions:['.js','.json','.css'],//自動解析確定的擴展
2.3externals
這個主要是防止某些包打入bundle中
3.關(guān)于開發(fā)
在開發(fā)中我們都對其提供的熱更新最為感興趣,我們只需要安裝webpack-dev-server,然后我們就可以在config中配置了,也就是devServer,直接看代碼了
devServer:{
clientLogLevel:"none",
//提供的內(nèi)容路徑
// contentBase:path.join(__dirname, "dist"),
//是否啟用gzip壓縮
compress:true,
//port 在命令行中,端口號,實際在非命令行中也可以使用
port:9000,
//output.filename設(shè)置bundle.js,惰性模式,每個請求結(jié)果都會產(chǎn)生全新的編譯,使用filename可以只為某個文件被請求時編譯
//webpack不會監(jiān)聽任何文件改動,只有請求的時候才編譯,watchOptions無效,內(nèi)聯(lián)模式應(yīng)該禁用。
/*lazy: true,
filename: "bundle.js",*/
//請求添加首部內(nèi)容
headers:{
'X-Custom-Foo':'bar'
},
//任意的404頁面可以使用index.html來替換,所以可以直接用localhost:port/index.html來,此時dist目錄是個虛擬目錄并不會真實的的創(chuàng)建出來,只有webpack命令才會,也就是在build的時候
historyApiFallback: true,
//只用在命令行,指定host,如果希望在外部服務(wù)器訪問,指定host:"0.0.0.0"
host:"",
//啟用熱替換
// hot:true,
// hotOnly:true,
//使用https
https:true,
/*https的配置
* https:{
* key:fs.readFileSync(),
* cert:fs.readFileSync(),
* ca:fs.readFileSync(
* }
* */
//兩種模式,默認內(nèi)聯(lián)模式(inline),處理時重載的腳本會插入到你的包(bundle)中,并且構(gòu)建消息會出現(xiàn)到瀏覽器控制臺
//iframe inline:false 只在命令行中使用--inline
//noInfo啟用 noInfo 后,諸如「啟動時和每次保存之后,那些顯示的 webpack 包(bundle)信息」的消息將被隱藏。錯誤和警告仍然會顯示。
noInfo:false,
//如果你有單獨的后端開發(fā)服務(wù)器 API,并且希望在同域名下發(fā)送 API 請求 ,那么代理某些 URL 會很有用。
// proxy:{
// '/api':"http://localhost:3000"
// },
//請求/api/user會代理到http://localhost:3000/api/user
//如果你不想始終傳遞 /api ,則需要重寫路徑:
/*proxy: {
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^/api" : ""}
}
}*/
//命令行使用,內(nèi)聯(lián)模式連接指定服務(wù)器。
// public:{
//
// },
//啟動后除了啟動信息都不會顯示
/*
* quit:true,
* */
//可以接受一個app對象(express)處理一些請求
// setup(app){
// app.get('/some/path', function(req, res) {
// res.json({ custom: 'response' });
// });
// },
}
4node中使用
我們不止可以在命令行中使用,也可以在node中使用,只需要把webpack和配置文件引入即可
var webpack = require('webpack');
var config = require('./webpack.config');
//這里會返回一個compiler對象
let compiler = webpack(config);
使用插件
compiler.apply(new webpack.ProgressPlugin());
compiler對象主要提供兩個方法,run和watch
compiler.run(function(err, stats) {
console.log(stats);
if(err||stats.hasErrors()){
//編譯錯誤不在err中
}
});
watch有兩個參數(shù),第一個是配置對象watchOptions,第二個是回調(diào)函數(shù)handler
watchOptions{
aggregateTimeout:300,//延遲重新構(gòu)建時間
poll:1000,//輪詢間隔(多久檢測一次)
ignored:/node_modules/, //也可以使用anymatch方式 "files\/**\/*.js",可以忽略檢測某些文件
}
compile.watch()會返回一個watching對象,暴露close(callback)方法,用來結(jié)束監(jiān)聽。
我們還可以將編譯到內(nèi)存中,如下
//編譯到內(nèi)存中
const MemoryFS = require("memory-fs");
const webpack = require("webpack");
const fs = new MemoryFS();
const compiler = webpack({ /* options*/ });
compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
// 之后讀取輸出:
const content = fs.readFileSync("...");
});
其實還是有諸多不理解之處,但是對于我們基本的使用,以及看別人的配置還是有一定幫助的。