這篇文章是本身在整理webpack相關的東西時候突發奇想,想整理出一套由淺入深的博文以此鞭策本身學習,也但願可以幫助想學習webpack的同窗,目前都是入門級別的,大佬請出門右轉。javascript
學習完本篇文章,我但願您可以掌握如下幾點:css
統一說明,本文中所用到的npm包管理工具均採用淘寶鏡像(cnpm),緣由你懂得。html
webpack版本基於3.0版本,本文中具體是3.8.1版本。前端
webpack是一個用以對現代Javascript應用程序模塊打包工具,它和gulp、grunt的不一樣之處在於webpack提供了一整套前端模塊化開發的解決法案;webpack把資源做爲模塊來處理,這裏的資源不止於javascript,還包括html、css、圖片、字體等等。java
一、初始化, 新建一個文件夾,取名叫webpackDemo,經過控制檯或者git bash定位到當前文件下面,執行命令:node
npm init //淘寶鏡像用 cnpm init複製代碼
而後一路enter,初始化後,會在該文件夾下面生成一個package.json文件,而後,再次在命令行內執行:webpack
npm install //淘寶鏡像用 cnpm install複製代碼
二、項目結構搭建, 在webpackDemo文件夾下:git
新建.babelrc文件,放置babel相關配置,和webpack.config.js同樣,babel的配置文件名稱,也是固定的,即:.babelrces6
注意: webpack默認會讀取webpack.config.js 中的相關配置,若是更換其餘名字,webpack默認是找不到配置信息的。(固然咱們也能夠去指定webpack讀取的配置文件,在現階段,咱們暫不考慮);web
最終的項目結構以下:
一、代碼編寫,打開根目錄下的index.html,引入webpack最後編譯的的js文件,我麼定義js名稱叫作bundle.js。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack demo</title>
</head>
<body>
<!-- 咱們給最終編譯出的js叫作bundle.js-->
<script src="./dist/js/bundle.js"></script>
</body>
</html>複製代碼
二、在src/js文件夾下面,新建app.js,做爲webpack編譯的入口文件,並添加一個方法,在控制檯打印出hello world
// app.js
function Hello() {
console.log('hello world')
}
Hello()複製代碼
三、接下來,咱們打開webpack.config.js,給webapck編譯指定規則:
// webpack.config.js
var path = require('path');
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),//指定webpack打包的入口是app.js
output: {
path: path.resolve(__dirname, './dist/js'),//指定打包後js文件放置的位置
filename: 'bundle.js'//指定打包後的js名稱,這個就是index.html最終引入的js的名稱
}
}複製代碼
一、配置路徑用path.resolve()處理,是爲了確保路徑是從根目錄開始絕對定位到指定位置,webpack3.0要求咱們在配置路徑相關的時候使用絕對路徑;
二、path模塊是nodejs內置的處理路徑相關的模塊。
如今讓咱們打開命令行,執行webpack編譯
//若是還未安裝webpack,則先執行安裝
cnpm i webpack --save-dev
// 安裝完成後執行編譯
webpack複製代碼
編譯執行完成後,控制檯輸出如下則表示執行成功。
此時查看dist/js目錄,會發現新增了一個bundle.js的文件,在瀏覽器中打開index.html,再打開控制檯,成功輸出hello world。
看到這裏,估計有人要打人了,就這玩意有啥用,浪費我青春!我要輸出的hello world要你這麼麻煩幹啥。額!騷年,先放下你手上的磚頭,有話好好說。
大名鼎鼎的webpack固然不止這就完了,接下來,讓咱們一步一步真正開始認識webpack。
如今,咱們來看一下webpack配置文件中的output選項的相關配置,細心的你也許發現,咱們最終生成的的bundle.js是咱們設定好的,每次打包後生成的名字是不會改變的,可是在實際項目中,爲了確保代碼更改先後無衝突以及版本回退等一系列問題,每次打包後的包文件,咱們會給他打上一個獨一無二的標記,用以區分版本,這又是怎麼實現的呢?
實際上,webpack在打包編譯的時候,會把不一樣模塊的代碼分別指定一個chunkhash值,最後總體打包後的js會生成一個hash值 (須要注意chunkhash和hash是不同的),咱們只須要在output配置項中給filename屬性一個填寫hash的佔位符,這樣在每次編譯的時候,就會生成帶有hash值得js文件:
var path = require('path')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle-[hash].js'//[hash]爲編譯時填寫hash的佔位符,也能夠填寫chunkhash等
}
}複製代碼
再次執行編譯,咱們會發現,新生成的文件已經帶有hash值了:
上面咱們已經動態生成了帶有不一樣hash值得js了,那麼問題又來了,既然每次生成的js文件都不同,咱們如何去加載生成的js呢,要知道,在index.html裏面,咱們寫的是bundle.js啊!
爲了解決這個問題,咱們就想,若是每次webpack打包編譯後自動將生成的js注入到咱們的index.html模板中,這樣咱們就不用在咱們的index.html中手動添加bundle.js了,不就解決了這個問題麼。
實際上!這種思想正是webpack爲咱們提供的解決方案-- html-webpack-plugin。
首先,咱們經過命令行安裝這個插件
cnpm install html-webpack-plugin --save-dev複製代碼
而後,咱們在配置文件裏新增對html-webpack-plugin的相關配置
var path = require('path');
//引入html-webpack-plugin模塊
var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle-[hash].js'
},
//初始化插件
plugins:[
new htmlWebpackPlugin({
template:'index.html',//定義插件讀取的模板文件是根目錄下的index.html
filename:'index.html'//定義經過模板文件新生成的頁面名稱
})
]
}複製代碼
在配置文件中,咱們新增了plugins這個配置屬性,並初始化html-webpack-plugin插件,如今咱們去index.html中刪除js的引用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack demo</title>
</head>
<body>
<!-- <script src="./dist/js/bundle.js"></script>-->
</body>
</html>複製代碼
再次執行webpack命令,編譯成功後!再看看咱們的dist目錄下,果真生成了index.html。
html-webpack-plugin插件運行的時候,須要在項目安裝webpack,若是是全局安裝的webpack,在此處運行會報錯:Cannot find module 'webpack/lib/node/NodeTemplatePlugin'。
。
解決辦法就是在本地安裝webpack,定位到項目的根目錄下執行如下命令便可。
cnpm install webpack複製代碼
細心的你可能又發現,生成的index.html也在dist/js文件夾下面,這和咱們想要的結果不同,由於咱們想要在dist文件夾下把html、js以及後面的css都分開來,爲了解決這個問題,咱們須將配置文件的output選項更改一下:
var path = require('path')
var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
// path: path.resolve(__dirname, './dist/js'),
path: path.resolve(__dirname, './dist'),//將輸出的路徑定位到dist一級就好,而後再filename配置項中,指定二級目錄。
//filename: 'bundle-[hash].js'
filename: 'js/bundle-[hash].js'
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html',
filename:'index.html'
})
]
}複製代碼
在配置中,咱們將output中的path路徑指定到dist一級就好,至於生成的js路徑,咱們就將js放置在filename選項下,配置完成後,咱們再次在命令行執行"webpack"命令,最終發現,dist目錄下新生成了index.html頁面,而js,則依然在js文件夾下生成。
到目前爲止,咱們的案例能夠動態的生成帶有本身hash命名的js文件,可是咱們發現文件在一直增長,新生成編譯文件以前並無刪除上一次編譯的文件,這會讓項目原來越大。爲了解決這個問題,咱們須要再次引入一個插件---clean-webpack-plugin。
老規矩,首先是安裝,在命令行執行:
cnpm install clean-webpack-plugin --save-dev複製代碼
而後在配置文件中引入插件並實例化
var path = require('path');
var htmlWebpackPlugin = require('html-webpack-plugin');
//引入插件模塊
var cleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/bundle-[hash].js'
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html'
}),
//初始化插件配置項
new cleanWebpackPlugin(
['dist'], //匹配要刪除的文件,這裏則指定每次對dist文件夾進行清理
{
root: __dirname,//指定插件根目錄位置
verbose: true, //開啓在控制檯輸出信息
dry: false //啓用刪除文件
}
)
]
}複製代碼
在配置中,咱們將引入的clean-webpack-plugin實例化,並設置了要刪除文件的目錄和一些顯示設置,再次在命令行執行"webpack"命令,發現以前的文件被刪除了,只剩下最新生成的相關文件。
;這一節,咱們向你們初步介紹了webpack的使用,而且從頭開始搭建了一個webpack運行的編譯環境,初次體驗了一下webpack,固然,webpack的功能遠遠不止於此,它的最重要的功能loader咱們還沒開始,目前筆者所展現的這些,只是webpack很小很小的一部分。
再次提醒讀者盆友,讀完本篇文章您應該瞭解如下內容:
下一節,咱們將在此基礎上學習webpack的加載器用法,包括babel編譯es六、css預處理、autoprefixer用法、css與js文件分割等,歡迎你們提出寶貴意見,一塊兒學習。
這是前端最好的時代,也是前端最壞的時代,前端不止,學習不停,願各位讀者努力向前,早日成爲前端高手。