webpack筆記

聲明:摘自  keliyxyz的博客javascript

(一)webpack介紹css

現在的網站正在演化爲web應用程序: 
1. 愈來愈多的使用JavaScript。 
2. 現代瀏覽器提供更普遍的接口。 
3. 整頁刷新的狀況愈來愈少,甚至更多代碼在同一個頁面。(SPA)html

所以有不少代碼在客戶端! 
一個體量龐大的代碼庫須要好好組織。模塊系統提供代碼庫劃分紅模塊的選項。java

目前有多個標準定義依賴和輸出: 
1. script標籤(不要模塊系統) 
2. CommonJS 
3. AMD和它的一些變種 
4. ES 6 
5. 其它node

 

script 標籤的樣式

下面這種就是不用模塊系統,你會怎麼去管理你的代碼。jquery

<script src="module1.js"></script> <script src="module2.js"></script> <script src="libraryA.js"></script> <script src="module3.js"></script>

模塊接口導出到全局對象,即window對象。模塊的接口能夠訪問全局對象的依賴關係 webpack

常見問題es6

全局衝突 
嚴重依賴加載的順序 
開發人員必須人工解決模塊/庫的依賴關係 
大型項目,script一溜下來能夠很長,難以管理web

CommonJs: 同步加載

這種風格用同步require 的方法去加載一個依賴並用暴露一個接口。 一個模塊能夠經過給export對象添加屬性或給module.exports設置值 來指定導出。npm

require("module"); require("../file.js"); exports.doStuff = function() {}; module.exports = someValue;

服務器端node.js用的就是這種標準。 

優勢
1. 服務器端模塊能夠重用 
2. 已經有許多模塊用這種風格(npm)。生態圈良好 
3. 很是簡單和容易使用。 

劣勢 
1. 阻塞調用不適用網絡。網絡請求是異步的。 
2. 沒有並行加載機制。 

哪些在用? 
1. 服務端 -node.js 
2. browserify 
3. modules-webmake -編譯到一個包 
4. wreq -客戶端

AMD: 異步加載

其它模塊系統(例如 瀏覽器) 同步加載有困難(CommonJS) 而引入的一個異步版本(和定義模塊和輸出值的一種方法 )。

require(["module", "../file"], function(module, file) { /* ... */ }); define("mymodule", ["dep1", "dep2"], function(d1, d2) { return someExportedValue; });
  • 1
  • 2
  • 3
  • 4

優勢
1. 適合網絡的異步請求的風格 
2. 並行加載多個模塊。 
劣勢 
1. 編碼費力,更難讀和寫 
2. 看起來只是權宜之計。 

哪些在用? 
1. require.js 
2. curl

ES6模式

ES6借鑑其它語言給javascript新加了一些語法結構,有import語法。

import "jquery"; export function doStuff() {} module "localModule" {}
  • 1
  • 2
  • 3

優勢
1. 靜態分析很容易。 
2. 不會過期的ES標準 。 
劣勢 
1. 瀏覽器支持須要時間。(早晚的事) 
2. 不多有模塊用這種風格。生態圈 

目前沒有公開的方案

開發者應當本身選擇適合本身的風格。容許現有的代碼和包能正常工做,能夠很容易地添加自定義模塊風格。

傳輸

模塊應該在客戶端執行,因此他們必須從服務器傳輸到瀏覽器。 
傳輸模塊有兩個極端: 
1. 一個一個地傳。 
2. 所有打包在一個裏傳。

兩種用法都氾濫,可是兩種都太low了。

一個一個地傳 
優勢:只有確實須要的模塊纔會傳輸過去。 
缺點:許多請求意味着不少開銷。 
缺點:應用程序啓動緩慢,由於請求延遲 
所有一個地傳 
優勢:請求的開銷更少,更少的延遲 
缺點:不少暫時不須要的模塊給傳輸過去了。

分塊傳輸

更靈活的傳輸可能會更好。大多數狀況下在這兩種極端之間的折中比較好。 

=>在編譯全部模塊時:把模塊切分紅小塊兒(chunks)。 
這樣容許多個更小、更快的請求。有些模塊不是一開始就須要的,含有這些模塊的分塊在須要的時候能夠加載到。這樣加快了初始化速度,可是在須要用那些模塊時仍然讓你去抓更多的代碼。

開發者怎麼作「切分點」,能夠根據狀況自由抉擇。 
=》一個代碼庫是可能的喲。

注意:這些觀點來自谷歌 GWT.

=>在編譯全部模塊時:把模塊切分紅小塊兒(chunks)。 
這樣容許多個更小、更快的請求。有些模塊不是一開始就須要的,含有這些模塊的分塊在須要的時候能夠加載到。這樣加快了初始化速度,可是在須要用那些模塊時仍然讓你去抓更多的代碼。

開發者怎麼作「切分點」,能夠根據狀況自由抉擇。 
=》一個代碼庫是可能的喲。

注意:這些觀點來自谷歌 GWT.

靜態分析

當編譯全部這些模塊時,一個靜態分析試圖找到本身的依賴。 
傳統上這隻能找到簡單的東西沒有表達 。可是 
require("./template/" + templateName + ".jade") 這樣是常見的結構。 
有些庫是用一些不同的風格寫的。它們有些很奇怪(難以想象)。

策略

聰明的解析辦法容許現存代碼能跑起來,若是程序猿用了一些怪異的東西,它能試圖找到兼容的解決方案。

什麼是webpack

webpack是一個模塊打包器。webpack把模塊(s)連同它的依賴一塊兒打包生成包含這些模塊的靜態資源。

爲何另用一個打包器?

現有的模塊打包器不適合大項目(大單頁面應用)程序。代碼分割和靜態資源無縫模塊化的迫切需求,催生了一個新的模塊打包器。 
我試圖擴展示有的模塊打包器,可是它沒能實現全部的目標。 

目標以下: 
1. 把依賴樹切分紅塊,實現按需加載。 
2. 保持低初始加載時間 
3. 每一個靜態資源都能是一個模塊 
4. 具有把第三方庫集成爲模塊的能力 
5. 具有打包器每一個部分幾乎都能本身定製的特色。 
6. 適合大型項目。

webpack有什麼不一樣?

代碼分割

webpack依賴樹中有兩個依賴類型:同步和異步。異步模塊切分紅一個新的塊。在塊樹(chunk tree)優化以後,文件會爲每一個chunk發文件。

loader

webpack能夠處理javascript自己,但loader用來將其它資源轉換爲javascript。這樣一來,全部資源都被格式化成模塊了。

智能解析

webpack有一個智能解析器,它能處理幾乎全部的第三方庫。它甚至容許你在依賴中像這樣加表達式 require("./templates/" + name + ".jade") 。它能夠處理最多見的模塊化標準風格:CommonJS和AMD。

安裝

node.js

安裝node.js 
包管理工具 npm會一塊兒裝上。

webapck

webpack 能夠用npm 命令來裝

$ npm install webpack -g

webpack 已經全局安裝了,如今 webpack 命令可用了。

項目中使用webpack

你的項目最好也有webpack 依賴。 這樣你能夠在項目中自由決定用webpack哪一個版本而沒必要去用全局那個webpack。 
用 npm 命令添加一個 package.json文件

$ npm init

若是你不發佈npm包,Init過程當中的問題不重要,均可以忽略。 
安裝webpack 並添加到package.json中:

$ npm install webpack --save-dev

版本

有兩個webpack版本可用。穩定版本和beta版。beta版 在版本字符中標記爲 -beta 。beta版本可能包含脆弱的或者實驗功能,都沒進行過多少測試。正式場景下應該用穩定版。

$ npm install webpack@1.2.x --save-dev

開發工具

若是你想用開發工具,先安裝它

$ npm install webpack-dev-server --save-dev

(二)webpack 使用

安裝

能夠用 npm 安裝

npm install webpack -g

注意: 這裏全局安裝是出於演示的目的。在真實的項目中,建議安裝爲你的項目依賴。

開始

首先,咱們將只使用webpack的命令行界面學習基本webpack 。

新建一個 模塊化的javascript 項目

cats.js

var cats = ['dave', 'henry', 'martha']; module.exports = cats;

app.js (入口文件)

cats = require('./cats.js'); console.log(cats);

入口文件就是你項目啓動點。也是webpack追蹤模塊之間依賴關係的入口點。

5秒 打包

給webpack指定一個入口文件(app.js)和輸出文件(app.bundle.js)

webpack ./app.js app.bundle.js

webpack將讀取和分析入口點及其依賴(包括傳遞的依賴)。而後它會把它們都打包到app.bundle.js。 
如今你打好的包能夠跑起來了。 運行一下 node app.bundle.js ,你會發現,哇,你有好多貓。

node app.bundle.js ["dave", "henry", "martha"]

你也能夠在 瀏覽器端使用打好的包。

來點嚴肅的

webpack是一個很是靈活的模塊打包器。它提供了不少高級功能,但並不是全部功能都經過命令行界面實現。要得到所有webpack的靈活性,咱們須要建立一個 config 文件

項目結構

在真實的webpack項目中,咱們會把源文件和打包文件用文件夾分開。在這個例子中,咱們把源文件放在src中,把打包後的文件放在bin中。 
結構以下

project
└─webpack.config.js └─src └─app.js └─app.js └─node_modules └─bin └─app.bundle.js

大千世界,無奇不有。有很多不同的結構。有些項目用app而不是src,用些用dist 或者 build而不是bin.項目測試學用 test,tests,spec,specs或者把測試文件放在源文件夾一塊兒。

1.建立 bin 和 src 文件夾。

mkdir bin mkdir src

2.原始源文件移動到src文件夾

mv app.js cats.js src

3.初始化一個新項目。

npm init # (answer the questions)

4.安裝webpack爲你的項目開發依賴。這將聲明你的項目適用webpack版本。

npm install --save-dev webpack

遷移到config文件

隨着你項目愈來愈大,你的配置文件也會愈來愈複雜。從命令行配置webpack就顯得很不科學。咱們來建立一個配置文件。 
1.建立 webpack.config.js

module.exports = { entry: './src/app.js', output: { path: './bin', filename: 'app.bundle.js' } };

webpack 配置文件是 node 風格的模式。因此您能夠運行任何類型的代碼,只要一個配置對象,導出了配置模塊。

2.在放了配置文件的地方,你能夠簡單地運行一下 webpack:

webpack

3.運行 bin/app.bundle.js ,你又能夠拿到你的貓了

node bin/app.bundle.js ["dave", "henry", "martha"]

你也能夠 require 用npm安裝過的模塊,而不須要額外的配置。

 

使用loader

webpack原生只支持javascript模式。可是許多人會用像es 2015 ,coffeeScript ,typeScript 等語言。這些語言是能夠用的,要用「loader」處理它們。 
loader是一種用來加載其它語言到javascript(webapck可以理解)的特殊的模塊 。例如,babel-loader 用Babel 加載 ES2015文件。json-loader 加載JSON文件(簡單地在前面加上 module.exports= 來把它轉換成 CommonJS模式) 
。loader能夠鏈式調用,並且你一般須要這麼作。例如,yaml-loader 只把 YAML轉換爲 JSON,所以你須要 把它鏈到 json-loader 這樣就能夠用啦。

用 babel-loader 轉換 ES2015

在這個例子中, 咱們會告訴 webpack 用 babel 跑咱們的源碼,這樣就能夠用 ES2015新特性了。 

1.先安裝 babel 和 預設。

npm intall  --save-dev babel-core babel-preset-es2015

2.安裝 babel-loader

npm install --save-dev babel-loader

3.添加 .babelrc 文件來配置 babel 使用 規範。

4.修改 webpack.config.js 用babel-loader 處理 .js文件。

module.exports = { entry: './src/app.js', output: { path: './bin', filename: 'app.bundle.js', }, module: { loaders: [{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', }] } }

咱們排除 node_modules中的文件,由於要否則的話全部外部庫都會經過babel編譯,將會下降 編譯速度。

 

5.安裝你想用的第三方庫。(例如 jQuery)

npm install --save jquery babel-polyfill

這裏用 –save 而不是 –save-dev, 是由於這些庫在執行時會用到。咱們也安裝了babel-polyfill 這樣在一些老式瀏覽中能夠用 ES2015了。

6.編輯 src/app.js

 import 'babel-polyfill'; import cats from './cats'; import $ from 'jquery'; $('<h1>Cats</h1>').appendTo('body'); const ul = $('<ul></ul>').appendTo('body'); for (const cat of cats) { $('<li></li>').text(cat).appendTo(ul); }

7.用webpack 打包

webpack

8.添加 index.html,這樣app能跑起來。

<!DOCTYPE html><body> <script src="bin/app.bundle.js"></script>

當你打開 index.html 時你應該能看到你的貓了。

有許多不一樣的loders你能夠用在app打包中,包括 css 和 image loader。

用插件

一般你須要在你的打包工做流中作一些額外的事情。一個簡單的例子是你會壓縮文件來使客戶端加載起來更快,這就能夠用插件來作。咱們將添加 uglify 插件到配置中。

用插件

一般你須要在你的打包工做流中作一些額外的事情。一個簡單的例子是你會壓縮文件來使客戶端加載起來更快,這就能夠用插件來作。咱們將添加 uglify 插件到配置中。

const webpack = require('webpack'); module.exports = { entry: './src/app.js', output: { path: './bin', filename: 'app.bundle.js', }, module: { loaders: [{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', }] }, plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, }, output: { comments: false, }, }), ] }

uglify 插件在webpack包中已經包含了,因此你不須要另外添加,但也有可能出現例外。你能夠編寫本身的自定義插件。在這個例子中, uglify 插件就把文件從1618b壓縮到了308b。

相關文章
相關標籤/搜索