看了不少webpack的教程,大可能是上來就講一堆配置,一堆插件的使用。這種文章看起來有點相似於官方文檔,或者新華字典。我想回歸初心,換一種方式,基於實際使用出發,一步一步介紹webpack。javascript
從一個最簡單的例子開始,這個例子只爲了描述最簡單的webpack功能,實現一個最簡單的需求:在瀏覽器上顯示一段文字。html
首先咱們有一個index.html
,這個html中只是引入了index.js
,a.js
和b.js
。java
<!Doctype html>
<html>
<head>
<meta name="charset" content="utf-8">
<title>webpack</title>
</head>
<body>
<script type="text/javascript" src="./a.js"></script>
<script type="text/javascript" src="./b.js"></script>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>
複製代碼
在a.js
中聲明瞭變量var a = 1;
,在b.js
中聲明瞭變量var b = 2;
。因爲這種方式下,做用域是共享的,a和b至關於都是掛載在window上,因此在index.js
中能夠直接訪問到a和b的值。node
在index.js
中,咱們建立一個DOM並掛載到HTML上:webpack
var dom = document.createElement('p');
dom.innerHTML = `a=${a}; b=${b}`;
document.body.appendChild(dom);
複製代碼
最後,在瀏覽器上就會顯示a=1; b=2
。web
這種使用方式雖然簡單,可是會有潛在的問題:npm
index.js
加載完了,但它所依賴的a.js
還沒加載。固然,這個問題能夠用require.js
解決。a.js
中聲明的a就直接掛載到了window上,其餘文件中若是再聲明a變量,就會有衝突。這個問題能夠用當即執行函數的方式解決。雖然有辦法解決,但總感受不是那麼完美,治標而不治本。迴歸到js的運行環境上,這都是由於js代碼須要在瀏覽器中運行。若是是在node環境中運行,那能夠直接使用CommonJS規範,每一個文件就是一個模塊,各個模塊之間的做用域是獨立的,經過require能夠解決模塊依賴和加載問題。甚至還能夠在node中利用ES6的模塊機制,也一樣能夠解決這個問題。顯然,這種寫代碼的方式要簡單不少,但只能在node環境下。而webpack的一個重要做用,就是可讓你這種方式寫出來的代碼能在瀏覽器中運行。json
a.js
和b.js
分別做爲2個模塊,經過ES6的export導出變量a和b,在index.js中經過import引入:gulp
//a.js
export var a = 1;
//b.js
export var b = 2;
//index.js
import {a} from './a.js';
import {b} from './b.js';
var dom = document.createElement('p');
dom.innerHTML = `a=${a}; b=${b}`;
document.body.appendChild(dom);
複製代碼
最後,咱們但願用webpack,將其打包成一個單獨的文件,直接掛載到index.html
中。從零開始,安裝webpack。瀏覽器
新建一個文件夾,在這個文件夾中npm init
,初始化。
安裝webpack
和webpack-cli
,運行npm install webpack webpack-cli -D
。webpack-cli
爲webpack提供了命令行工具,讓咱們能夠直接在命令行中使用webpack
創建src文件夾,將a.js
,b.js
和index.js
存放在src文件夾下。這個文件夾存放的是原始文件
創建dist文件夾,用來存放編譯後的文件,也就是打包後的單個文件
將index.html
放到src文件夾下,這時引用的不是index.js
,而是打包後的位於dist目錄下的bundle.js
文件
<script type="text/javascript" src="../dist/bundle.js"></script>
複製代碼
配置webpack。webpack的配置就是在根目錄下直接新建一個webpack.config.js
,配置以下:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
}
}
複製代碼
index.js
。因爲在index.js
中import
了a.js
和b.js
,因此webpack在打包時會同時將a.js
和b.js
引入。從這裏能夠看到,只用告訴webpack入口文件便可,全部的依賴文件webpack會本身尋找和解決。bundle.js
在package.json
中的script下作個配置:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
複製代碼
直接運行npm run build
,node就會自動執行webpack,這時在dist目錄下就能夠看到生成的js文件(只有一個),將index.html
放到瀏覽器中,就會看到最後顯示的效果。
從上面的例子看到,使用了webpack以後,咱們解決了傳統方式裏面遇到的各類問題。固然,webpack能作的,遠不止這些。好比在寫代碼時,可能還會有這些需求:
咱們須要一個工具來幫咱們解決這些問題,完成整個構建流程。使用構建工具的目的,是爲了讓咱們寫代碼更加方便,能夠用更新的特性而不用過多關心瀏覽器的兼容問題;讓咱們能夠省去不少機械重複性的工做,好比修改代碼後瀏覽器會自動刷新,提升咱們的開發效率。
固然,在webpack以前,已經有不少優秀的構建工具了,好比grunt、gulp等。稱webpack是當下最流行的構建工具絕不爲過。webpack強大不只在其自己,還在於不少基於webpack的插件,提供了一個強大的生態系統。webpack能作的事情還有不少,將在後面一步步繼續學習。