一、什麼是webpackjavascript
Webpack是前端一個工具,可讓各個模塊進行加載,預處理,再進行打包。現代的前端開發不少環境都依賴webpack構建,好比vue官方就推薦使用webpack。
css
二、簡單使用下webpackhtml
2.一、首先我在 c 盤下新建一個webpack-demo1的文件夾,而後命令行進入該目錄,執行 npm init --yes 項目初始化,該命令會在文件下生成一個package.json文件,該命令也能夠是 npm init ,這樣的話它會詢問你一系列諸如項目名稱,項目描述,做者等信息,若是你不許備在npm中發佈你的模塊,這些問題的答案都不重要,一路回車默認便可。package.json以下:前端
{ "name": "webpack-demo1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
接下來在該環境中安裝一下3.5.6版本webpack,命令 npm install webpack@3.5.6 --save-dev,接下來再全局安裝一下,npm install webpack@3.5.6 -g,安裝成功以後,package.json文件會出現webpack的版本信息:vue
{ "name": "webpack-demo1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^3.5.6" } }
實現打包功能:java
打包一個js文件node
在根目錄下新建一個index.js,和index.html文件,index.js文件內容:webpack
function say(){ alert("hello webpack"); } say();
輸入命令:webpack index.js index.bundle.js,該命令含義:es6
#webpack {entry file} {destination for bundled file}web
# {extry file}出填寫入口文件的路徑,本文中就是上述main.js的路徑,
# {destination for bundled file}處填寫打包文件的存放路徑
# 填寫路徑的時候不用添加{}
結果自動生成了一個 index.bundle.js 的文件,咱們能夠在index.html中引入,在瀏覽器中順利彈出 「hello webpack」
打包多個文件:
在根目錄下又新建一個calc.js文件,內容:
function add(a,b){ return a+b; } module.exports = { //導出這個模塊 add: add }
把index.js文件內容更改:
var oCalc = require("./calc"); //引入模塊 function say(){ alert("hello webpack"); } say(); alert(oCalc.add(10,20)); //使用該模塊的功能
執行打包:webpack index.js index.bundle.js,成功後,打開index.html,彈出倆次 一、「hello webpack」 二、「30」
webpack打包,後面能夠跟不少參數:
好比我使用 --watch:webpack index.js index.bundle.js --watch,這樣的話會自動監測,只要與index.js相關的文件發生了變化,自動打包。
webpack.config.js
Webpack擁有不少其它的比較高級的功能(好比說本文後面會介紹的loaders
和plugins
),這些功能其實均可以經過命令行模式實現,可是正如前面提到的,這樣不太方便且容易出錯的,更好的辦法是定義一個配置文件,這個配置文件其實也是一個簡單的JavaScript模塊,咱們能夠把全部的與打包相關的信息放在裏面。演示,新建一個基本目錄結構webpack-demo2如圖:
其中main.js文件隨便寫一些內容:
function say(){ alert("今天是星期五"); } say();
接下來,配置一下webpack.config.js文件:
module.exports = { entry: "./src/js/main.js", output: { path: __dirname + "/dist/", filename: "js/index.bundle.js" } }
這裏參數作一下解釋,entry就是入口,項目被運行時,第一個被查找的文件,output就是出口,path是輸出路徑,要使用絕對路徑,__dirname是當前文件的絕對路徑,「E:\webpack-demo2\src\js」,filename是輸出文件的文件名,能夠在前面加上路徑,稍後它會自動生成該路徑,配置好以後,進行打包,命令行:webpack(這裏不用再寫後面的倆個參數了,由於咱們已經在webpack.config.js裏已經配置好了),成功後依照咱們配置好的路徑,在dist/js目錄下,生成了index.bundle.js文件
在index.html中引入該文件,而後運行,順利彈出「今天是星期五」
咱們還能夠經過package.json文件的scripts部分,簡化打包操做:
好比咱們進行打包時後面跟着的幾個參數(上面有說),咱們能夠在package.json裏配置下:
"dev" : "webpack --config webpack.dev.config.js --progress --display-modules --colors --display-reasons"
這樣的話咱們在執行打包時直接命令:npm run dev 就會執行相應的打包,後面幾個參數也會生效。簡化了操做。
咱們上面是打包一個js文件,若是想打包多個文件呢,這裏有倆種狀況:
一、多個文件打包成一個文件,這裏要用數組配置entry了,好比,咱們在main.js同目錄下新建一個calc.js文件,內容:
function add(a,b) { alert(a + b); } add(10,20);
把webpack.config.js文件內容更新爲:
module.exports = { entry: ["./src/js/main.js","./src/js/calc.js"], //entry用數組配置 output: { path: __dirname + "/dist/", filename: "js/index.bundle.js" } }
執行打包後成功將倆個文件打包在dist/js.index.bundle.js,預覽index.js,彈出倆次 「今天是星期五」 「30」
二、多個文件打包成多個文件,這裏entry要採用字面量(json)方式配置
module.exports = { entry: { main: "./src/js/main.js", calc: "./src/js/calc.js" }, output: { path: __dirname + "/dist/", filename: "js/[name].bundle.js" //filename支持多種動態起名字的方式( id, name, hash, chunkhash, query ) name就是entry裏寫的文件的名字 } }
執行打包,成功在dist/js裏生成倆個文件
html-webpack-plugin插件的使用
咱們打包後的js文件,默認不會自動插入到模板文件中的,咱們能夠安裝html-webpack-plugin插件,先安裝這個插件 npm install html-webpack-plugin --save-dev,接下來在webpack.config.js中引入並配置一下:
var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { main: "./src/js/main.js", calc: "./src/js/calc.js" }, output: { path: __dirname + "/dist/", filename: "js/[name].bundle.js" //filename支持多種動態起名字的方式( id, name, hash, chunkhash, query ) name就是entry裏寫的文件的名字 }, plugins: [new HtmlWebpackPlugin()] }
弄好以後,執行打包,與以前不一樣的是此次直接在dist目錄下生成了index.html文件,該html文件自動引入了打包後的倆個js文件。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Webpack App</title> </head> <body> <script type="text/javascript" src="js/main.bundle.js"></script><script type="text/javascript" src="js/calc.bundle.js"></script></body> </html>
可是有一個問題,咱們在根目錄下原本就建好了一個html文件,此次從新生成的文件和以前的沒有任何的聯繫,咱們須要讓生成的html文件內容參照原有html文件。從新配置下webpack.config.js。
plugins: [new HtmlWebpackPlugin( { template : './index.html' } )]
此次打包的話,就是參照原模板html文件,進行生成了。並自動引入了js文件。
插件的其餘配置選項:
filename:打包生成的文件名,還能夠加目錄,默認沒有寫的時候是index.html
inject:有4個值:
舉慄:從新配置下webpack.config.js文件中的plugins:
plugins: [new HtmlWebpackPlugin( { template : './index.html', filename : 'index-bundle.html', inject : 'head' } )]
而後打包,此次在dist目錄下生成的html文件名爲index.bundle.html,而且自動引入的js文件在head標籤內。
插件的另外一個選項title,就是設置一個標題,用法以下,webpack.config.js文件中的plugins:
plugins: [new HtmlWebpackPlugin( { template : './index.html', filename : 'index-bundle.html', inject : 'head', title: 'hello webpack~' } )]
接下來在原html文件中的title標籤內寫入:
<title><%= htmlWebpackPlugin.options.title %></title>
如今打包後的html文件的標題爲 「hello webpack~」
html-webpack-plugin插件中的options除了本身定義了一些基本配置外,咱們是能夠任意的添加自定義的數據:
plugins: [ new HtmlWebpackPlugin({ template : './index.html', title : 'hello webpack', inject : true, date : new Date(), userName : '張三', age : 22 }) ]
在原始模板html文件中讀取:
<h3><%= htmlWebpackPlugin.options.date %></h3> <h3><%= htmlWebpackPlugin.options.userName %></h3> <h3><%= htmlWebpackPlugin.options.age %></h3>
這樣的話,在生成的html文件中就會添加相應的數據。
minify選項,壓縮html文件:
new HtmlWebpackPlugin({ template : './index.html', title : 'ghostwu教你學webpack', inject : false, minify : { removeComments : true, //去掉註釋 collapseWhitespace : true, //去掉空行 } })
再次打包,此次html文件都被壓縮。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>我是原有的模板文件~</body></html>
chunks選項
這個屬性很是有用,能夠指定某個頁面加載哪些chunk( 能夠簡單的把他理解成js文件 ),咱們能夠用他作多個頁面模板的生成. 好比,咱們在實際開發中,作一個博客網站,通常來講有首頁,文章列表頁,文章詳情頁等等,這些頁面都有一個特色,都要引入一些公共的js文件以及該頁面特有的js文件,好比:
傳統方式,一個個的打開文件,拷貝修改,若是後期維護,又是一堆文件中,查找,拷貝,修改。很容易出錯,並且效率低下,能夠用webpack解決,
咱們先在src/js中建立對應js,而後webpack.config.js配置:
var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry : { main : './src/js/main.js', index : './src/js/index.js', list : './src/js/list.js', detail : './src/js/detail.js' }, output : { //__dirname,就是當前webpack.config.js文件所在的絕對路徑 path : __dirname + '/dist', //輸出路徑,要用絕對路徑 filename : 'js/[name].bundle.js', //打包以後輸出的文件名 }, plugins: [ new HtmlWebpackPlugin({ template : './index.html', title : '博客首頁-', filename : 'index.html', inject : true, chunks : ['main', 'index'] }), new HtmlWebpackPlugin({ template : './index.html', title : '列表頁-', filename : 'list.html', inject : true, chunks : ['main', 'list'] }), new HtmlWebpackPlugin({ template : './index.html', title : '文章詳情頁-', filename : 'detail.html', inject : true, chunks : ['main', 'detail'] }) ] };
執行打包,成功以後,會在dist目錄下生成3個html文件,而且在引入main.js的同時,各自引入屬於本身的js。
loader
官方解釋爲文件的預處理器,通俗點說webpack在處理靜態資源的時候,須要加載各類loader,好比,html文件,要用html-loader,要讓js識別css文件要用css-loader,讓文件在頁面中生效要用style-loader等等.
babel-loader的做用---打包時把es6語法轉爲瀏覽器認識的es5語法,用法:
先建一個webpack-demo3的基本機構
須要安裝的插件等:
1,npm init --yes( 初始化項目的package.json )
2,npm install webpack@3.5.6 -g ( 全局安裝webapck )
3,npm install webpack@3.5.6 --save-dev (局部安裝webpack )
4,npm install html-webpack-plugin --save-dev ( 安裝html-webpack-plugin插件 )
webpack.config.js文件:
var htmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry : './src/main.js', output : { path : __dirname + '/dist', filename : 'js/[name].bundle.js', }, plugins : [ new htmlWebpackPlugin({ filename : 'index.html', template : 'index.html', inject : true }) ] }
modal.js文件
let modal = function(){ return { 'component-name' : 'modal' } } export default modal;
main.js文件
import modal from './components/modal.js'; let App = function(){ console.log( '項目入口文件main.js' ); } new App();
進行打包,而後查看dist/js/下的main.bundle.js文件,發現是引入了es6的語法,這樣的話瀏覽器是不認識的,咱們能夠在打包以前用babel.loader解決。
安裝babel-loader:npm install --save-dev babel-loader babel-core babel-preset-env webpack
配置一下babel-loader:
var htmlWebpackPlugin = require('html-webpack-plugin'); let path = require('path'); module.exports = { entry: './src/main.js', output: { path: __dirname + '/dist', filename: 'js/[name].bundle.js', }, plugins: [ new htmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }) ], module: { rules: [ { test: /\.js$/, exclude: /(node_modules)/, include: [ path.resolve(__dirname, "src"), ], use: { loader: 'babel-loader', options: { presets: ['env'] } } } ] } }
rules就是配置規則,他是一個數組,每一項爲一個對象,若是有多個loader,那就用多個對象,
test: /\.js$/ 就是以.js結尾的文件,exclude:排除node_modules這個目錄,意思就是不要去這個目錄下處理.js的文件,有什麼好處呢?大大提升打包的速度. include裏面的配置意思就是把src目錄下面的js文件做爲處理的目標,
use配置就是使用babel-loader
再進行打包,成功以後查看打包後生成的main.bundle.js文件中,發現已經轉成es5語法了。
var App = function App() { console.log('項目入口文件main.js'); }; new App();
css-loader 和 style-loader,
在src目錄下建一個css目錄,裏面有一個sytle.css文件,
body{ background-color: bisque; }
在main.js中導入css文件
import modal from './components/modal.js'; import './css/style.css'; let App = function(){ console.log( '項目入口文件main.js' ); } new App();
執行打包,會報錯 「你可能須要一個loader來處理這個文件類型」,咱們能夠安裝對應loader解決,npm install css-loader style-loader --save-dev,安裝完以後,配置一下webpack.config.js:
var htmlWebpackPlugin = require('html-webpack-plugin'); let path = require('path'); module.exports = { entry: './src/main.js', output: { path: __dirname + '/dist', filename: 'js/[name].bundle.js', }, plugins: [ new htmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }) ], module: { rules: [ { test: /\.js$/, exclude: /(node_modules)/, include: [ path.resolve(__dirname, "src"), ], use: { loader: 'babel-loader', options: { presets: ['env'] } } }, { test: /\.css$/, exclude: /(node_modules)/, use: [ 'style-loader', 'css-loader' ] } ] } }
執行webpack打包,就能看到css內嵌到main.bundle.js中了,css-loader是處理css文件,style-loader是把css內嵌到瀏覽器。
less-loader 首先在src/css/裏建一個less.less,內容:
@w:200px; @h:200px; *{ margin: 0; padding: 0; } #box{ div{ width:@w; height:@h; } }
在main.js中引入,打包,直接報錯,咱們能夠安裝一個less-loader來解決,安裝,npm install --save-dev less-loader less,同樣的,配置一下webpack.config.js:
{
test: /\.less$/, use: [ { loader: "style-loader" //最後交由style-loader處理 }, { loader: "css-loader" //而後交給css-loader處理, }, { loader: "less-loader" //當碰到less文件時,交給less-loader處理, } ]
}
如今打包的話,less文件就被嵌入進去了。
html-loader
若是想把html內容引入的話就須要html-loader了,在src/components目錄下新建一個modal.html,內容:
<div class="modal"> <div class="modal-heading">模態框頭部 - by ghostwu</div> <div class="modal-body">模態框內容部分 - by ghostwu</div> </div>
此次就不錯誤示範了,直接安裝html-loader,npm install html-loader --save-dev,而後配置一下webpack.config.js:
{ test: /\.(html)$/, use: { loader: 'html-loader', } }
modal.js文件引入modal.html
import tpl from './modal.html'; let modal = function(){ return { 'component-name' : 'modal', 'tpl' : tpl } } export default modal;
main.js對webpack_demo3目錄下的index.html文件插入模板(modal.html)
import modal from './components/modal.js'; let App = function(){ var oApp = document.querySelector("#app"); var oModal = new modal(); oApp.innerHTML = oModal.tpl; } new App();
在index.html模板文件中建一個id爲app的div,打包,
此次在dist目錄下生成的index文件中,就有了modal.html的內容。
file-loader
圖片資源的打包,圖片在靜態排版中,常常出現的兩個位置1,css經過background引入背景,2,還有一種就是在html模板文件中用img標籤引入的方式,若是要在webpack使用圖片資源,咱們須要用file-loader來處理.若是不使用的話,就會報錯。
安裝,安裝 npm install file-loader --save-dev,配置:
{ test: /\.(png|gif|jpg|svg|jpeg)$/i, use: { loader: 'file-loader', query : { name : 'assets/[hash].[ext]' } } }
query部分的配置,是爲打包的圖片設置一個自定義的存儲路徑和文件名稱
注意:在模板中引入圖片路徑,
若是是相對路徑要這樣引入${require(圖片的相對路徑)},不然打包路徑會出現問題
<img src="${ require('../img/dm.jpg') }" alt="">