DEMO地址:http://pan.baidu.com/s/1eR4s2uI
1.前言
現(xiàn)今的很多網(wǎng)頁其實可以看做是功能豐富的應(yīng)用,它們擁有著復(fù)雜的JavaScript代碼和一大堆依賴包驶冒。為了簡化開發(fā)的復(fù)雜度,前端社區(qū)涌現(xiàn)出了很多好的實踐方法
模塊化呀忧,讓我們可以把復(fù)雜的程序細(xì)化為小的文件;
類似于TypeScript這種在JavaScript基礎(chǔ)上拓展的開發(fā)語言:使我們能夠?qū)崿F(xiàn)目前版本的JavaScript不能直接使用的特性,并且之后還能能裝換為JavaScript文件使瀏覽器可以識別覆醇;
Scss妆够,less等CSS預(yù)處理器
這些改進(jìn)確實大大的提高了我們的開發(fā)效率,但是利用它們開發(fā)的文件往往需要進(jìn)行額外的處理才能讓瀏覽器識別,而手動處理又是非常繁瑣的迎膜,這就為WebPack類的工具的出現(xiàn)提供了需求泥技。
WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項目結(jié)構(gòu)磕仅,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss珊豹,TypeScript等),并將其打包為合適的格式以供瀏覽器使用榕订。
Webpack的工作方式是:把你的項目當(dāng)做一個整體店茶,通過一個給定的主文件(如:index.js),Webpack將從這個文件開始找到你的項目的所有依賴文件劫恒,使用loaders處理它們贩幻,最后打包為一個瀏覽器可識別的JavaScript文件。
2.安裝
webpack可以通過npm安裝,首先你得安裝nodejs(注:npm版本號最好為3.x版本以上)
//全局安裝
npm install -g webpack
在你的目錄里面創(chuàng)建一個package.json的文件段直,這是一個標(biāo)準(zhǔn)的npm說明文件吃溅,里面包含了豐富的信息溶诞,包括當(dāng)前項目的依賴模塊鸯檬,自定義的腳本任務(wù)等等。在終端中使用npm init命令可以自動創(chuàng)建這個package.json文件螺垢。
npm init
//安裝到你的項目目錄,并且添加在package.json文件里
npm install --save-dev webpack
輸入后喧务,終端會問你一系列諸如項目名稱,項目描述枉圃,作者等信息功茴,不過不用擔(dān)心,如果你不準(zhǔn)備在npm中發(fā)布你的模塊孽亲,這些問題的答案都不重要坎穿,回車默認(rèn)即可。舉個栗子返劲,這是我生成后的目錄玲昧,src目錄放置原始文件,build放置生成后文件篮绿,node_modules 放置npm下載的文件包,webpack.config.js是配置文件孵延。
3.使用webpack
首先創(chuàng)建一個webpack.config.js文件,這是一個配置項目亲配,告訴webpack需要做什么尘应。
這是一份此DEMO基礎(chǔ)的配置文件。
var?webpack= require('webpack');
var?HtmlWebpackPlugin= require('html-webpack-plugin');
var?path= require('path');
var?CleanPlugin= require('clean-webpack-plugin');//清楚目錄
var?ExtractTextPlugin= require('extract-text-webpack-plugin');
module.exports= {
entry: {
index:"./src/js/main.js",
},//入口
output: {
path:path.resolve(__dirname,'build'),//打包后文件地址
//? publicPath:'/assets/',? //指定資源文件引用的目錄
filename:"[name]-[hash].js"//可以打包為多個文件
},
module: {
loaders:[
{
test:/\.css$/,
loader:ExtractTextPlugin.extract({
fallback:'style-loader',
use: [{
loader:'css-loader',
options: {
}
}],
})},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules///需要排除的目錄
},{
test:/\.scss$/,
loader:ExtractTextPlugin.extract({
fallback:'style-loader',
use: ['css-loader','sass-loader']
})//css文件分離
},
{
test:/\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
loader:'file-loader',
options: {
name:'src/images/[name].[hash].[ext]'
}
},
{
test:/\.(png|jpg|gif|svg|ico)$/,
loader:'file-loader',
options: {
name:'src/images/[name].[hash].[ext]'
}
}
]
},
plugins: [
new?HtmlWebpackPlugin({
template:'./index.html'// 模版文件
}),
new?CleanPlugin(['build']), //刪除目錄
new?webpack.optimize.UglifyJsPlugin({//壓縮js代碼
compress: {
warnings:false
}
}),
new?ExtractTextPlugin('[name]-[hash].css')//css文件打包壓縮
]
};
entry:
entry參數(shù)定義了打包后的入口文件吼虎,可以是個字符串或數(shù)組或者是對象犬钢;如果是數(shù)組,數(shù)組中的所有文件會打包生成一個filename文件思灰;如果是對象玷犹,可以將不同的文件構(gòu)建成不同的文件:
{
entry: {
page1:"./page1",
//支持?jǐn)?shù)組形式,將加載數(shù)組中的所有模塊官辈,但以最后一個模塊作為輸出
page2: ["./entry1","./entry2"]
},
output: { path:"dist/js/page", filename:"[name].bundle.js"}
}
該段代碼最終會生成一個 page1.bundle.js 和 page2.bundle.js箱舞,并存放到 ./dist/js/page 文件夾下。
output:
這個參數(shù)為一個對象拳亿,定義了輸出文件的位置和名字:
path:打包文件存放的絕對路徑
publicPath:網(wǎng)站運行時的訪問路徑
filename:打包后的文件名
當(dāng)我們在entry中定義構(gòu)建多個文件時晴股,filename可以對應(yīng)的更改為[name].js用于定義不同文件構(gòu)建后的名字。
module:(重點)
通過使用不同的loader肺魁,webpack通過調(diào)用外部的腳本或工具可以對各種各樣的格式的文件進(jìn)行處理电湘,比如說分析JSON文件并把它轉(zhuǎn)換為JavaScript文件,或者說把下一代的JS文件(ES6,ES7)轉(zhuǎn)換為現(xiàn)代瀏覽器可以識別的JS文件寂呛。怎诫,最終返回到JavaScript上
Loaders需要單獨安裝并且需要在webpack.config.js下的module關(guān)鍵字下進(jìn)行配置.
{
test:/\.css$/,
loader:'css-loader!style-loader'
},{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules///需要排除的目錄
},{
test:/\.scss$/,
loader:'css-loader!sass-loader'
},{
test:/\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
loader:'file-loader',
options: {
name:'src/images/[name].[hash].[ext]'
}},
test:一個匹配loaders所處理的文件的拓展名的正則表達(dá)式(必須)
loader:loader項表示用來加載這種類型的資源的loader。
exclude:表示不會處理此目錄里的文件
每個模塊都需要特定的loader執(zhí)行贷痪,.css 文件使用 style-loader 和 css-loader 來處理
.js模塊需要babel來處理幻妓, .scss文件需要 css-loader sass-loader node-sass來執(zhí)行
通過npm 下載特定的loader。
//建議下載多個模塊
npm install --save-dev file-loader css-loader style-loader node-sass
PS:下一代的js標(biāo)準(zhǔn)(es6)還沒有被瀏覽器支持劫拢,需要babel編譯成es5標(biāo)準(zhǔn)肉津。
// npm一次性安裝多個依賴模塊,模塊之間用空格隔開npm
install --save-devbabel-core babel-loader babel-preset-es2015 babel-preset-stage-2
//在當(dāng)前目錄新建個.babelrc 配置文件
touch .babelrc
//打開.babelrc在里面寫入
{
"presets": [
"es2015",
"stage-2"
]
}
plugins:
插件(Plugins)是用來拓展Webpack功能的舱沧,它們會在整個構(gòu)建過程中生效妹沙,執(zhí)行相關(guān)的任務(wù)。要使用某個插件熟吏,我們需要通過npm安裝它距糖,然后要做的就是在webpack配置中的plugins關(guān)鍵字部分添加該插件的一個實例(plugins是一個數(shù)組)舉個栗子
//npm 下載
npm install html-webpack-plugin --save-dev
//載入模塊
var?HtmlWebpackPlugin= require('html-webpack-plugin');
//在plugins 使用,這是一個生成模版文件并且自動載入js文件的插件
new?HtmlWebpackPlugin({
template:'./index.html'// 模版文件
}),
4.實驗執(zhí)行webpack打包文件牵寺。
在你的package.json寫下
"scripts": {
"build":"webpack --config ./webpack.config.js"
},
然后npm run build 執(zhí)行腳本
此DEMO編譯后的目錄狀態(tài)
5.熱加載和服務(wù)器開啟
首先請加載webpack-dev-server(WDS)
npm install webpack-dev-server --save-dev
WDS:是一個小型的Node.js Express服務(wù)器悍引,它使用webpack-dev-middleware來服務(wù)于webpack的包,除此自外,它還有一個通過Sock.js來連接到服務(wù)器的微型運行時缸剪。
在你的webpack.config.js里面寫入devServer配置:
devServer:{
//WDS生成的包并沒有放入真實目錄中吗铐,而是放在服務(wù)器內(nèi)存里。
contentBase: './',//本地服務(wù)器所加載的頁面所載目錄
colors: true,
stats:"errors-only",//打印錯誤日志
port:3000,//端口
historyApiFallback: true,//不跳轉(zhuǎn)
inline: true,//自動刷新開啟
watch:true,//檢測
hot:true //熱模塊替換開啟
}
并且在plugins里面寫入
new?webpack.HotModuleReplacementPlugin(),//模塊熱替換 實時編譯
在package.json里面寫入
"scripts":{ "start":"webpack-dev-server" }
執(zhí)行npm run start后 訪問http://localhost:3000
6.多頁面生成(后續(xù)補(bǔ)充)