Webpack是什麼?
Webpack是當下比較熱門的前端資源模塊化管理和打包工具。對於webpack來講一切資源皆模塊,它可以把諸如JS(含JSX)、coffee、樣式(含less/sass)、圖片等都作爲模塊來使用和處理,將許多鬆散的模塊按照依賴和規則打包成適合生產環境部署的web前端資源。
使用webpack的優勢
1. 物理上的模塊化轉變爲邏輯上的模塊化
在編寫大型應用時,往往需要將一個部分分解爲若干個模塊分配給不同的開發人員進行編寫,每個人所編寫的模塊代碼最後都會以<script src=”/js/module”></script>引入到html頁面中,這樣做雖然使代碼結構上更加清晰,但是每個頁面都要向服務器請求多個資源。Webpack能將瑣碎的模塊打包爲一個文件,在邏輯上代碼仍然是模塊劃分,但是最終的文件會將所有的模塊統統涵蓋。
2. 可以把更多的資源當做模塊使用
Webpack支持引入多種類型資源,尤其在做插件開發的時候,爲了降低與主程序的耦合度都會在插件函數中加載該插件所有需要的資源,此時webpack就是不錯的選擇。
3. 支持多種規範編寫
webpack 是以commonJS的形式來書寫腳本滴,但對AMD/CMD的支持也很全面,方便舊項目進行代碼遷移
webpack的使用
下面介紹一個完整的項目搭建流程,首先在磁盤上創建文件夾project和相關文件,並使用cd命令進入到當前目錄。使用npm初始化一個配置文件
npm init
這裏一路默認Enter鍵即可,最後在當前目錄下回生成package.json文件
按照下圖創建工程目錄和文件
使用npm將webpack安裝到全局(這裏使用了淘寶鏡像)
npm install webpack –g –-registry=https://registry.npm.taobao.org
如果針對自己的項目使用如下命令安裝到當前項目
npm install webpack –-save-dev --registry=https://registry.npm.taobao.org
index.html簡單地引入js文件即可(暫時不考慮文件在哪裏)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript"src="./build/index.build.js"></script>
</body>
</html>
在js目錄下創建三個文件分別命名爲index.js、module1.js和module2.js
// index.js內容
var module1 = require('./module1')
var module2 = require('./module2')
console.log(module1)
console.log('=================')
console.log(module2)
// module1.js內容
module.exports = {
content: {
title: 'module1',
notes: 'i am first module'
},
other: {
name: 'Liu',
age: 22
}
}
// module2.js內容
module.exports = {
content: {
title: 'module2',
notes: 'i am second module'
},
other: {
name: 'Ding',
age: 21
}
}
在webpack.config.js中配置我們的webpack執行任務
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
index: './web/js/index.js'
},
output: {
path: path.resolve('./web/build'),
filename: '[name].build.js'
},
devtool: 'source-map'
}
在命令行執行webpack後發現web目錄下多出了build目錄
至此,一個簡單的測試案例完成,在瀏覽器中打開index.html並觀察控制檯輸出情況
我們在回過頭看看webpack.config.js文件中各項配置的具體含義
entry: {
index: './web/js/index.js'
}
entry值得是模塊的入口,其值爲一個對象,key和value分別代表着打包後的文件名和打包入口文件,若存在多個打包文件則依次定義。
output: {
path: path.resolve('./web/build'),
filename: '[name].build.js'
}
output和entry對應,是文件打包後輸出的相關配置。path指帶輸出文件目錄,filename指的是輸出的文件名稱。output只需配置一個便可以適應所有的輸入文件,而name指的就是entry中配置的key。
devtool指生成Source Maps的格式。開發總是離不開調試,如果可以更加方便的調試當然就能提高開發效率,不過打包後的文件有時候你是不容易找到出錯了的地方對應的源代碼的位置的,Source Maps就是來幫我們解決這個問題的。
通過簡單的配置後,Webpack在打包時可以爲我們生成的source maps,這爲我們提供了一種對應編譯文件和源文件的方法,使得編譯後的代碼可讀性更高,也更容易調試。
在webpack的配置文件中配置source maps,需要配置devtool,它有以下四種不同的配置選項,各具優缺點,描述如下:
接下來介紹webpack的插件功能plugins。要使用某個插件,我們需要通過npm安裝它,然後要做的就是在webpack配置中的plugins關鍵字部分添加該插件的一個實例(plugins是一個數組)繼續看例子,我們添加了一個實現壓縮的插件。
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
index: './web/js/index.js'
},
output: {
path: path.resolve('./web/build'),
filename: '[name].build.js'
},
devtool: 'source-map',
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
})
]
}
在當前工程目錄下執行webpack命令可以發現和之前沒有什麼變化,但是文件大小和之前相比變得更小了,這就是壓縮插件所實現的功能。
webpack的插件功能比較強大,對應的插件應用也比較多,需要實現什麼功能直接在百度上就可搜索到相關的插件模塊,npm引入之後就可以對着API文檔使用了。
最後來看看webpack的重頭戲——loaders
Loaders是webpack中最讓人激動人心的功能之一了。通過使用不同的loader,webpack通過調用外部的腳本或工具可以對各種各樣的格式的文件進行處理,比如說分析JSON文件並把它轉換爲JavaScript文件,或者說把下一代的JS文件(ES6,ES7)轉換爲現代瀏覽器可以識別的JS文件。或者說對React的開發而言,合適的Loaders可以把React的JSX文件轉換爲JS文件。
接下來看一個導入json模塊的例子。要想打包的時候支持json格式文件的加載,我們必須先引入json模塊:
npm install --save-dev json-loader –-registry=https://registry.npm.taobao.org
我們把webpack.config.js的內容改爲:
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
index: './web/js/index.js'
},
output: {
path: path.resolve('./web/build'),
filename: '[name].build.js'
},
devtool: 'source-map',
module: {
loaders: [{
test: /\.json$/,
loader: 'json'
}]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
})
]
}
然後在web/js目錄下創建config.json文件
{
"server": "127.0.0.1:8080",
"path": "D:/demo/vux/project",
"port": "8088",
"local": ["/web/", "/wap/","/res/"],
"map": {
"/web/wap/": "/web/wap/"
}
}
並將index.js內容改爲:
// index.js內容
var module1 = require('./module1')
var module2 = require('./module2')
var config = require('./config.json')
console.log(module1)
console.log('=================')
console.log(module2)
console.log(config)
打包後查看結果
在webpack中比較常見的加載器是html、json、style!css、babel(語法轉換器),詳細看一下babel的用法。首先npm引入babel加載器的模塊:
npm install --save-dev babel-core babel-loader babel-preset-es2015 --registry=https://registry.npm.taobao.org
爲了讓webpack支持ES6的語法webpack.config.js中配置如下
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
index: './web/js/index.js'
},
output: {
path: path.resolve('./web/build'),
filename: '[name].build.js'
},
devtool: 'source-map',
resolve: {
extensions: ['', '.js'],
alias: {
vue: 'vue/dist/vue.js'
}
},
module: {
loaders: [{
test: /\.json$/,
loader: 'json'
}, {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel', //在webpack的module部分的loaders裏進行配置即可
query: {
presets: ['es2015']
}
}]
}
}
我們將index.js改爲ES6導入的語法:
// index.js內容
import module1 from './module1'
const {content, other} = module1
console.log(module1)
console.log(content)
console.log(other)
webpack的基本操作到這裏已經差不多了,當然我們在開發項目中不只是使用webpack進行項目管理,還會藉助其他管理工具,例如grunt、gulp等。gulp擁有良好的任務操作,在項目中一般採用webpack來負責模塊管理,而gulp等負責諸如壓縮、混淆、清理、構建等多任務操作。