webpack 打包

React自發布以來吸引了愈來愈多的開發者,React開發和模塊管理的主流工具webpack也被你們所熟知。那麼webpack有哪些優點,能夠成爲最主流的React開發工具呢?javascript

webpack是什麼

CommonJS和AMD是用於JavaScript模塊管理的兩大規範,前者定義的是模塊的同步加載,主要用於NodeJS;然後者則是異步加載,經過requirejs等工具適用於前端。隨着npm成爲主流的JavaScript組件發佈平臺,愈來愈多的前端項目也依賴於npm上的項目,或者自身就會發布到npm平臺。所以,讓前端項目更方便的使用npm上的資源成爲一大需求。css

web開發中經常使用到的靜態資源主要有JavaScript、CSS、圖片、Jade等文件,webpack中將靜態資源文件稱之爲模塊。webpack是一個module bundler(模塊打包工具),其能夠兼容多種js書寫規範,且能夠處理模塊間的依賴關係,具備更強大的js模塊化的功能。Webpack對它們進行統一的管理以及打包發佈,其官方主頁用下面這張圖來講明Webpack的做用:html

webpack特性

webpack具備requireJs和browserify的功能,但仍有不少本身的新特性:前端

1. 對 CommonJS 、 AMD 、ES6的語法作了兼容 2. 對js、css、圖片等資源文件都支持打包 3. 串聯式模塊加載器以及插件機制,讓其具備更好的靈活性和擴展性,例如提供對CoffeeScript、ES6的支持 4. 有獨立的配置文件webpack.config.js 5. 能夠將代碼切割成不一樣的chunk,實現按需加載,下降了初始化時間 6. 支持 SourceUrls 和 SourceMaps,易於調試 7. 具備強大的Plugin接口,大可能是內部插件,使用起來比較靈活 8.webpack 使用異步 IO 並具備多級緩存。這使得 webpack 很快且在增量編譯上更加快

React-sample

以 react-sample 爲例,簡單說明 webpack 如何打包一個 React 組件,其目錄結構以下:java

其中Hello.js定義了一個簡單的React組件,使用ES6語法:node

/** * Created by pomy on 15/11/4. */ import React, {Component} from 'react'; class Hello extends Component { render(){ return ( <div>Hello, {this.props.name}!</div> ); } }

entry.js是入口文件,將一個Hello組件輸出到界面:python

/**
 * Created by pomy on 15/11/4. */ import React from 'react'; import Hello from './hello'; React.render(<Hello name="Nate" />, document.body);

index.html的內容以下:react

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>React Sample</title> </head> <body> <script src="./assets/bundle.js"></script> </body> </html>

webpack.config.js文件一般放在項目的根目錄中,它自己也是一個標準的Commonjs規範的模塊:jquery

/** * Created by pomy on 15/11/4. */ var path = require('path'); module.exports = { entry: path.resolve(__dirname, './src/entry.js'), output: { path: path.resolve(__dirname, './assets'), filename: 'bundle.js' }, module: { loaders: [ { test: /\.js?$/, loaders: ['babel'], exclude: /node_modules/ }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/} ] }, resolve:{ extensions:['','.js','.json'] }, };

整個代碼在 這裏,clone以後,切換到react-sample目錄下,在終端運行 npm i && npm run build 進行打包,打包後的文件名是 bundle.js, 所在相對目錄是 /assets。至此,webpack打包過程就Ok了。webpack

Webpack安裝和配置

安裝

webpack 能夠做爲全局的npm模塊安裝,也能夠在當前項目中安裝。

npm install -g webpack npm install --save-dev webpack

對於全局安裝的webpack,直接執行此命令會默認使用當前目錄的webpack.config.js做爲配置文件。若是要指定另外的配置文件,能夠執行:

webpack —config webpack.custom.config.js

配置

每一個項目下都必須配置有一個 webpack.config.js ,它的做用如同常規的 gulpfile.js/Gruntfile.js ,就是一個配置項,告訴 webpack 它須要作什麼。

前文說了,webpack.config.js文件一般放在項目的根目錄中,它自己也是一個標準的Commonjs規範的模塊。在導出的配置對象中有幾個關鍵的參數:

entry

entry參數定義了打包後的入口文件,能夠是個字符串或數組或者是對象;若是是數組,數組中的全部文件會打包生成一個filename文件;若是是對象,能夠將不一樣的文件構建成不一樣的文件:

{ entry: { page1: "./page1", //支持數組形式,將加載數組中的全部模塊,但以最後一個模塊做爲輸出 page2: ["./entry1", "./entry2"] }, output: { path: "dist/js/page", publicPath: "/output/", filename: "[name].bundle.js" } }

該段代碼最終會生成一個 page1.bundle.js 和 page2.bundle.js,並存放到 ./dist/js/page 文件夾下

output

output參數是個對象,定義了輸出文件的位置及名字:

output: { path: "dist/js/page", publicPath: "/output/", filename: "[name].bundle.js" }

path: 打包文件存放的絕對路徑
publicPath: 網站運行時的訪問路徑
filename:打包後的文件名

當咱們在entry中定義構建多個文件時,filename能夠對應的更改成[name].js用於定義不一樣文件構建後的名字。

module

在webpack中JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,圖片等靜態文件都是模塊,不一樣模塊的加載是經過模塊加載器(webpack-loader)來統一管理的。loaders之間是能夠串聯的,一個加載器的輸出能夠做爲下一個加載器的輸入,最終返回到JavaScript上:

module: { //加載器配置 loaders: [ //.css 文件使用 style-loader 和 css-loader 來處理 { test: /\.css$/, loader: 'style-loader!css-loader' }, //.js 文件使用 jsx-loader 來編譯處理 { test: /\.js$/, loader: 'jsx-loader?harmony' }, //.scss 文件使用 style-loader、css-loader 和 sass-loader 來編譯處理 { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, //圖片文件使用 url-loader 來處理,小於8kb的直接轉爲base64 { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }

test項表示匹配的資源類型,loaderloaders項表示用來加載這種類型的資源的loader,loader的使用能夠參考 using loaders,更多的loader能夠參考 list of loaders

用來定義loader的串聯關係,"-loader"是能夠省略不寫的,多個loader之間用「!」鏈接起來,但全部的加載器都須要經過 npm 來加載。

此外,還能夠添加用來定義png、jpg這樣的圖片資源在小於10k時自動處理爲base64圖片的加載器:

test: /\.(png|jpg)$/,loader: 'url-loader?limit=10000'}

給css和less還有圖片添加了loader以後,咱們不只能夠像在node中那樣require js文件了,咱們還能夠require css、less甚至圖片文件:

require('./bootstrap.css'); require('./myapp.less'); var img = document.createElement('img'); img.src = require('./glyph.png');

注意,require()還支持在資源path前面指定loader,即require(![loaders list]![source path])形式:

require("!style!css!less!bootstrap/less/bootstrap.less"); // 「bootstrap.less」這個資源會先被"less-loader"處理, // 其結果又會被"css-loader"處理,接着是"style-loader" // 可類比pipe操做

require()時指定的loader會覆蓋配置文件裏對應的loader配置項。

resolve

webpack在構建包的時候會按目錄的進行文件的查找,resolve屬性中的extensions數組中用於配置程序能夠自行補全哪些文件後綴:

resolve: {
        //查找module的話從這裏開始查找 root: '/pomy/github/flux-example/src', //絕對路徑 //自動擴展文件後綴名,意味着咱們require模塊能夠省略不寫後綴名 extensions: ['', '.js', '.json', '.scss'], //模塊別名定義,方便後續直接引用別名,無須多寫長長的地址 alias: { AppStore : 'js/stores/AppStores.js',//後續直接 require('AppStore') 便可 ActionType : 'js/actions/ActionType.js', AppAction : 'js/actions/AppAction.js' } }

而後咱們想要加載一個js文件時,只要require('common')就能夠加載common.js文件了。

注意一下, extensions 第一個是空字符串! 對應不須要後綴的狀況.

plugin

webpack提供了[豐富的組件]用來知足不一樣的需求,固然咱們也能夠自行實現一個組件來知足本身的需求:

plugins: [ //your plugins list ]

在webpack中編寫js文件時,能夠經過require的方式引入其餘的靜態資源,可經過loader對文件自動解析並打包文件。一般會將js文件打包合併,css文件會在頁面的header中嵌入style的方式載入頁面。但開發過程當中咱們並不想將樣式打在腳本中,最好能夠獨立生成css文件,之外鏈的形式加載。這時extract-text-webpack-plugin插件能夠幫咱們達到想要的效果。須要使用npm的方式加載插件,而後參見下面的配置,就能夠將js中的css文件提取,並以指定的文件名來進行加載。

npm install extract-text-webpack-plugin –save-dev
plugins: [ new ExtractTextPlugin('styles.css') ]

externals

當咱們想在項目中require一些其餘的類庫或者API,而又不想讓這些類庫的源碼被構建到運行時文件中,這在實際開發中頗有必要。此時咱們就能夠經過配置externals參數來解決這個問題:

externals: { "jquery": "jQuery" }

這樣咱們就能夠放心的在項目中使用這些API了:var jQuery = require("jquery");

context

當咱們在require一個模塊的時候,若是在require中包含變量,像這樣:

require("./mods/" + name + ".js");

那麼在編譯的時候咱們是不能知道具體的模塊的。但這個時候,webpack也會爲咱們作些分析工做:

1.分析目錄:'./mods'; 
2.提取正則表達式:'/^.*\.js$/';

因而這個時候爲了更好地配合wenpack進行編譯,咱們能夠給它指明路徑,像在cake-webpack-config中所作的那樣(咱們在這裏先忽略abcoption的做用):

var currentBase = process.cwd(); var context = abcOptions.options.context ? abcOptions.options.context : path.isAbsolute(entryDir) ? entryDir : path.join(currentBase, entryDir);

關於 webpack.config.js 更詳盡的配置能夠參考這裏

webpack經常使用命令

webpack的使用一般有三種方式:

一、命令行使用:webpack <entry.js> <result.js> 其中entry.js是入口文件,result.js是打包後的輸出文件
二、node.js API使用:

var webpack = require('webpack'); webpack({ //configuration }, function(err, stats){});

三、默認使用當前目錄的webpack.config.js做爲配置文件。若是要指定另外的配置文件,能夠執行:webpack --config webpack.custom.config.js

webpack 的執行也很簡單,直接執行

$ webpack --display-error-details

便可,後面的參數「--display-error-details」是推薦加上的,方便出錯時能查閱更詳盡的信息(好比 webpack 尋找模塊的過程),從而更好定位到問題。
經常使用命令
webpack的使用和browserify有些相似,下面列舉幾個經常使用命令:

webpack 最基本的啓動webpack命令
webpack -w 提供watch方法,實時進行打包更新
webpack -p 對打包後的文件進行壓縮
webpack -d 提供SourceMaps,方便調試
webpack --colors 輸出結果帶彩色,好比:會用紅色顯示耗時較長的步驟 webpack --profile 輸出性能數據,能夠看到每一步的耗時 webpack --display-modules 默認狀況下 node_modules 下的模塊會被隱藏,加上這個參數能夠顯示這些被隱藏的模塊

前面的四個命令比較基礎,使用頻率會比較大,後面的命令主要是用來定位打包時間較長的緣由,方便改進配置文件,提升打包效率。

圖片打包和靜態資源服務器

圖片打包

webpack中對於圖片的處理,能夠經過url-loader來實現圖片的壓縮。

div.img{
    background: url(../image/xxx.jpg)
}

//或者 var img = document.createElement("img"); img.src = require("../image/xxx.jpg"); document.body.appendChild(img);

針對上面的兩種使用方式,loader能夠自動識別並處理。根據loader中的設置,webpack會將小於指點大小的文件轉化成 base64 格式的 dataUrl,其餘圖片會作適當的壓縮並存放在指定目錄中。

module: { { test: /\.(png|jpg)$/, loader: 'url-loader?limit=10000&name=build/[name].[ext]' }] }

對於上面的配置,若是圖片資源小於10kb就會轉化成 base64 格式的 dataUrl,其餘的圖片會存放在build/文件夾下。

靜態資源服務器

除了提供模塊打包功能,Webpack還提供了一個基於Node.js Express框架的開發服務器,它是一個靜態資源Web服務器,對於簡單靜態頁面或者僅依賴於獨立服務的前端頁面,均可以直接使用這個開發服務器進行開發。在開發過程當中,開發服務器會監聽每個文件的變化,進行實時打包,而且能夠推送通知前端頁面代碼發生了變化,從而能夠實現頁面的自動刷新。

Webpack開發服務器須要單獨安裝,一樣是經過npm進行:

npm install -g webpack-dev-server

可使用webpack-dev-server直接啓動,也能夠增長參數來獲取更多的功能,具體配置能夠參見官方文檔。默認啓動端口8080,經過localhost:8080/webpack-dev-server/能夠訪問頁面,文件修改後保存時會在頁面頭部看到sever的狀態變化,而且會進行熱替換,實現頁面的自動刷新。

原文手發:http://www.ido321.com/1646.html

前端開發者手冊

相關文章
相關標籤/搜索