【Hybrid開發(fā)高級系列】AngularJS集成Webpack專題

1 集成要點

1.1 配置技巧

1.1.1 多入口配置

Multiple entry files are allowed. It is useful for a multi-page app.

// main1.js

document.write('<h1>Hello World</h1>');

// main2.js

document.write('<h2>Hello Webpack</h2>');

index.html

<html>

? <body>

????<script src="bundle1.js"></script>

? ? <script src="bundle2.js"></script>

? </body>

</html>


webpack.config.js

module.exports ={

?entry:{

???bundle1: './main1.js',

???bundle2: './main2.js'

? },

?output:{

???filename: '[name].js'

? }

};

1.1.2 CSS-loader

Demo04: CSS-loader(source)

????Webpack allows you torequire CSS in JS file, then preprocessed CSS file with CSS-loader.

main.js

require('./app.css');


app.css

body{

? background-color: blue;

}


index.html

<html>

? <head>

? ? <script type="text/javascript" src="bundle.js"></script>

? </head>

? <body>

? ? <h1>Hello World</h1>

? </body>

</html>


webpack.config.js

module.exports ={

?entry: './main.js',

?output:{

???filename: 'bundle.js'

? },

? module:{

???loaders:[

?????{ test: /\.css$/, loader: 'style-loader!css-loader'},

??? ]

? }

};


????????Attention, you have to use two loaders to transform CSS file. First is?CSS-loader?to read CSS file, and another is?Style-loader?to insert Style tag into HTML page. Different loaders are linked by exclamation mark(!).

????????After launching the server, index.html will have internal stylesheet.

<head>

? <script type="text/javascript" src="bundle.js"></script>

? <style type="text/css">

??? body{

? ? ? background-color: blue;

??? }

? </style>

</head>

1.1.3 Imageloader

Demo05: Imageloader (source)

????????Webpack could also requireimages in JS files.

main.js

var img1 = document.createElement("img");

img1.src = require("./small.png");

document.body.appendChild(img1);


var img2 = document.createElement("img");

img2.src = require("./big.png");

document.body.appendChild(img2);


index.html

<html>

? <body>

? ? <script type="text/javascript" src="bundle.js"></script>

? </body>

</html>


webpack.config.js

module.exports ={

?entry: './main.js',

?output:{

???filename: 'bundle.js'

? },

?module:{

???loaders:[

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

??? ]

? }

};


? ??url-loader?transforms image files.If the image size is smaller than 8192 bytes, it will be transformed into DataURL; otherwise, it will be transformed into normal URL. As you see, question mark(?) is used to pass parameters into loaders.

????After launching the server, small.png and big.png will have the followingURLs.

<img src="data:image/png;base64,iVBOR...uQmCC">

<img src="4853ca667a2b8b8844eb2693ac1b2578.png">

1.1.4 代碼混淆插件UglifyJs Plugin

Demo07: UglifyJsPlugin (source)

????????Webpack has a plugin system to expand its functions. For example,?UglifyJs Plugin?will minify output(bundle.js) JS codes.

main.js

var longVariableName = 'Hello';

longVariableName += ' World';

document.write('<h1>'+ longVariableName +'</h1>');


index.html

<html>

? <body>

? ? <script src="bundle.js"></script>

? </body>

</html>


webpack.config.js

var webpack = require('webpack');

var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

module.exports ={

? entry: './main.js',

? output:{

? ? filename: 'bundle.js'

? },

? plugins:[

??? new uglifyJsPlugin({

? ? ? compress:{

? ? ? ? warnings: false

? ? ? }

? ? })

? ]

};


????????After launching the server, main.js will be minified into following.

var o="Hello"; o+=" World", document.write("<h1>" + o + "</h1>")

1.1.5 HTMLWebpack Plugin and Open Browser Webpack Plugin

Demo08: HTML Webpack Plugin and Open Browser Webpack Plugin (source)

????????This demo shows you how toload 3rd-party plugins.

????????html-webpack-plugin?could createindex.htmlforyou, and?open-browser-webpack-plugin?could open a new browser tab when Webpack loads.

main.js

document.write('<h1>Hello World</h1>');


webpack.config.js

var HtmlwebpackPlugin = require('html-webpack-plugin');

var OpenBrowserPlugin = require('open-browser-webpack-plugin');


module.exports ={

? entry: './main.js',

? output:{

? ? filename: 'bundle.js'

? },

? plugins:[

??? new HtmlwebpackPlugin({

? ? ? title: 'Webpack-demos',

? ? ? filename: 'index.html'

? ? }),

??? new OpenBrowserPlugin({

? ? ? url: 'http://localhost:8080'

? ? ?})

? ?]

};


Run webpack-dev-server.

$ webpack-dev-server

????????Now you don't need to write index.html by hand and don't have to open browser by yourself. Webpack did all these things for you.


1.1.6 環(huán)境標(biāo)記

Demo09: Environmentflags (source)

????????You can enable some codes only in development environment with environment flags.

main.js

document.write('<h1>Hello World</h1>');

if (__DEV__) {

? document.write(new Date());

}


index.html

<html>

? <body>

? ? <script src="bundle.js"></script>

? </body>

</html>


webpack.config.js

var webpack = require('webpack');

var devFlagPlugin = new webpack.DefinePlugin({

? __DEV__ : JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))

});

module.exports ={

? entry: './main.js',

? output:{

? ? filename: 'bundle.js'

? },

? plugins:[devFlagPlugin]

};


Now pass environment variable into webpack.

# Linux & Mac

$ env DEBUG=true webpack-dev-server


# Windows

$ setDEBUG=true

$ webpack-dev-server

1.1.7 代碼分割Code splitting

Demo10: Codesplitting (source)

????????For big web apps it’s not efficient to put all code into a single file, Webpack allows you to split them into several chunks. Especially if some blocks of code are only required under some circumstances, these chunks could be loaded on demand.

????????At first, you use require.ensure to define a split point.(official?document)

// main.js

require.ensure(['./a'], function(require) {

? var content = require('./a');

? document.open();

? document.write('<h1>' +?content + '</h1>');

? document.close();

});


????????require.ensure tells Webpack that ./a.js should be separated from bundle.js and built into a single chunk file.

// a.js

module.exports = 'Hello World';


Now Webpack takes care of the dependencies, output files and runtime stuff. You don't have to put any redundancy into your index.html and webpack.config.js.

<html>

? <body>

? ? <script src="bundle.js"></script>

? </body>

</html>


webpack.config.js

module.exports ={

? entry : './main.js',

? output:{

? ? filename : 'bundle.js'

? }

};


????????Launch the server.

$ webpack-dev-server

????????On the surface, you won't feel any differences. However, Webpack actually builds main.js and a.js into different chunks(bundle.js and 1.bundle.js), and loads 1.bundle.js from bundle.js when on demand.

1.1.8 bundle-loader切割代碼Code splitting with bundle-loader

Demo11: Codesplitting with bundle-loader (source)

????????Another way of code splitting is using?bundle-loader.

// main.js

// Now a.js is requested, it will be bundled into another file

var load = require('bundle-loader!./a.js');


// To wait until a.js is available (and get the exports)

//?you need to async wait for it.

load(function(file) {

? document.open();

? document.write('<h1>' + file + '</h1>');

? document.close();

});

????????require('bundle-loader!./a.js') tells Webpack to load a.js from another chunk.

????????Now Webpack will build main.js into bundle.js, and a.js into 1.bundle.js.

1.1.9 用CommonsChunkPlugin提取通用代碼塊Common chunk

Demo12: Commonchunk (source)

????????When multi scripts have common chunks, you can extract the common part into a separate file withCommonsChunkPlugin.

// main1.jsx

var React = require('react');

var ReactDOM = require('react-dom');


ReactDOM.render(<h1>Hello World</h1>, document.getElementById('a'));


// main2.jsx

var React = require('react');

var ReactDOM = require('react-dom');


ReactDOM.render(<h2>Hello Webpack</h2>, document.getElementById('b'));


index.html

<html>

? <body>

? ? <div id="a"></div>

? ? <div id="b"></div>

? ? <script src="init.js"></script>

? ? <script src="bundle1.js"></script>

? ? <script src="bundle2.js"></script>

? </body>

</html>


webpack.config.js

var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");

module.exports ={

? entry:{

? ? bundle1: './main1.jsx',

? ? bundle2: './main2.jsx'

? },

? output:{

? ? filename: '[name].js'

? },

? module:{

? ? loaders:[

? ? {

???????test: /\.js[x]?$/,

???????exclude: /node_modules/,

???????loader: 'babel-loader',

???????query:{

?????????presets: ['es2015', 'react']

???????}

? ? },

??? ]

? },

?plugins:[

??? new CommonsChunkPlugin('init.js')

? ]

}

1.1.10 第三方庫代碼塊Vendorchunk

Demo13: Vendorchunk (source)

????????You can also extract the vendor libraries from a script into a separate file with CommonsChunkPlugin.

main.js

var $ = require('jquery');

$('h1').text('Hello World');


index.html

<html>

? <body>

? ? <h1></h1>

? ? <script src="vendor.js"></script>

? ? <script src="bundle.js"></script>

? </body>

</html>


webpack.config.js

var webpack = require('webpack');


module.exports ={

? entry:{

? ? app: './main.js',

? ? vendor: ['jquery'],

? },

? output:{

? ? filename: 'bundle.js'

??},

? plugins:[

??? new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js')

? ]

};

????If you want a module available as variable in every module, such as making $ and jQuery available in every module without writing require("jquery"). You should use ProvidePlugin(Official doc).

// main.js

$('h1').text('Hello World');


// webpack.config.js

var webpack = require('webpack');


module.exports ={

? entry:{

??? app: './main.js'

? },

? output:{

? ? filename: 'bundle.js'

? },

? plugins:[

??? new webpack.ProvidePlugin({

????? $: "jquery",

????? jQuery: "jquery",

????? "window.jQuery": "jquery"

??? })

? ]

};


1.1.11 暴露全局變量

Demo14: Exposingglobal variables (source)

????????If you want to use some global variables, and don't want to include them in the Webpack bundle, you can enable externals field in webpack.config.js (official?document).

????????For example, we have a data.js.

var data = 'Hello World';

We can expose data as a global variable.

// webpack.config.js

module.exports ={

? entry: './main.jsx',

? output:{

? ? filename: 'bundle.js'

? },

?module:{

? ? loaders:[

? ? ?{

???????test: /\.js[x]?$/,

???????exclude: /node_modules/,

???????loader: 'babel-loader',

???????query:{

?????????presets: ['es2015', 'react']

???????}

? ? ?},

??? ]

? },

? externals:{

??? //require('data') is external and available

??? //? on the global var data

??? 'data': 'data'

? }

};


????????Now, you require data as a module variable in your script. but it actually is a global variable.

// main.jsx

var data = require('data');

var React = require('react');

var ReactDOM = require('react-dom');


ReactDOM.render(<h1>{data}</h1>,

? document.body

);

1.1.12 熱更新HMR

Demo15: Hot ModuleReplacement (source)

? ??????Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running without a page reload.

????????You have?two ways?to enable Hot Module Replacement with the webpack-dev-server.

????(1) Specify --hot and --inline on the command line

$ webpack-dev-server --hot --inline

????????Meaning of the options:

????? --hot: adds the HotModuleReplacementPlugin and switch theserver to hot mode.

????? --inline: embed the webpack-dev-server runtime into the bundle.

????? --hot --inline: also adds the webpack/hot/dev-serverentry.


????(2) Modify webpack.config.js.

????? add new webpack.HotModuleReplacementPlugin() to the plugins field

????? add webpack/hot/dev-server and webpack-dev-server/client?http://localhost:8080 to the entry field


????????webpack.config.js looks like the following.

var webpack = require('webpack');

var path = require('path');


module.exports ={

? entry:[

??? 'webpack/hot/dev-server',

??? 'webpack-dev-server/client?http://localhost:8080',

??? './index.js'

? ],

? output:{

? ? filename: 'bundle.js',

? ? publicPath: '/static/'

? },

? plugins:[

??? new webpack.HotModuleReplacementPlugin()

? ],

?module:{

? ? loaders:[{

?????test: /\.jsx?$/,

?????exclude: /node_modules/,

?????loader: 'babel-loader',

?????query:{

???????presets: ['es2015', 'react']

?????},

?????include: path.join(__dirname, '.')

???}]

? }

};


????????Now launch the dev server.

$ webpack-dev-server


????????Visiting http://localhost:8080, you should see 'Hello World' in your browser.

????????Don't close the server. Open a new terminal to edit App.js, and modify 'Hello World' into 'Hello Webpack'. Save it, and see what happened in the browser.

App.js

import React, { Component } from 'react';


export default class App extends Component{

? render() {

??? return(<h1>Hello World</h1>);

? }

}


index.js

import React from 'react';

import ReactDOM from 'react-dom';

import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));


index.html

<html>

? <body>

? ? <div id='root'></div>

? ? <script src="/static/bundle.js"></script>

? </body>

</html>

2 參考鏈接

webpack入門級教程

http://www.tuicool.com/articles/bA3eym7

WebPack簡明學(xué)習(xí)教程

http://www.reibang.com/p/b95bbcfc590d

[新姿勢]前端革命掂林,革了再革:WebPack

https://segmentfault.com/a/1190000002507327

WebPack:更優(yōu)秀的模塊依賴管理工具砚嘴,及require.js的缺陷

http://www.kuqin.com/shuoit/20141221/344013.html

(Good)webpack解惑:多入口文件打包策略

http://www.cnblogs.com/lvdabao/p/5944420.html

webpack loader 列表

http://blog.csdn.net/keliyxyz/article/details/51649429

用Webpack打包你的一切

http://www.tuicool.com/articles/bIRBjmZ

使用 Webpack 模塊化 Angular 應(yīng)用程序

http://www.ibm.com/developerworks/cn/web/wa-modularize-angular-apps-with-webpack-trs/index.html

(Good)Angular中使用webpack基礎(chǔ)篇

http://www.tuicool.com/articles/qQJfEju

(Good)Webpack + Angular的組件化實踐

https://segmentfault.com/a/1190000003915443

AngularJS 進階(一) 按需加載controller js (轉(zhuǎn)帖)

https://my.oschina.net/sourcecoding/blog/304735

Code Splitting

https://webpack.js.org/guides/code-splitting/

(Good)webpack-demos

https://github.com/ruanyf/webpack-demos#demo12-common-chunk-source

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倦春,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唉擂,更是在濱河造成了極大的恐慌,老刑警劉巖檀葛,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玩祟,死亡現(xiàn)場離奇詭異,居然都是意外死亡屿聋,警方通過查閱死者的電腦和手機空扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門庆聘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勺卢,你說我怎么就攤上這事伙判。” “怎么了黑忱?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵宴抚,是天一觀的道長。 經(jīng)常有香客問我甫煞,道長菇曲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任抚吠,我火速辦了婚禮常潮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘楷力。我一直安慰自己喊式,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布萧朝。 她就那樣靜靜地躺著岔留,像睡著了一般。 火紅的嫁衣襯著肌膚如雪检柬。 梳的紋絲不亂的頭發(fā)上献联,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音何址,去河邊找鬼里逆。 笑死,一個胖子當(dāng)著我的面吹牛用爪,可吹牛的內(nèi)容都是我干的原押。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼项钮,長吁一口氣:“原來是場噩夢啊……” “哼班眯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起烁巫,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤署隘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后亚隙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體磁餐,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诊霹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羞延。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖脾还,靈堂內(nèi)的尸體忽然破棺而出伴箩,到底是詐尸還是另有隱情,我是刑警寧澤鄙漏,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布嗤谚,位于F島的核電站,受9級特大地震影響怔蚌,放射性物質(zhì)發(fā)生泄漏巩步。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一桦踊、第九天 我趴在偏房一處隱蔽的房頂上張望椅野。 院中可真熱鬧,春花似錦籍胯、人聲如沸竟闪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘫怜。三九已至,卻和暖如春本刽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赠涮。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工子寓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笋除。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓斜友,卻偏偏與公主長得像,于是被迫代替她去往敵國和親垃它。 傳聞我的和親對象是個殘疾皇子鲜屏,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 學(xué)習(xí)流程 參考文檔:入門Webpack,看這篇就夠了Webpack for React 一. 簡單使用webpac...
    Jason_Zeng閱讀 3,138評論 2 16
  • 版權(quán)聲明:本文為博主原創(chuàng)文章也殖,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一务热、webpack介紹 1忆嗜、由來 ...
    it筱竹閱讀 11,118評論 0 21
  • webpack 介紹 webpack 是什么 為什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert閱讀 6,464評論 2 71
  • “春蘭如美人己儒,不采羞自獻。時聞風(fēng)露香捆毫,蓬艾深不見闪湾。”一一蘇東坡 幾年前去海南游玩绩卤,正好趕上當(dāng)?shù)嘏e...
    巴根閱讀 430評論 4 3
  • 在我孩提時省艳,姥姥家院中間有兩棵桃樹娘纷,美艷的桃花根本入不了小孩子的眼睛,我眼巴眼望的是那又甜又脆的大桃跋炕。每到...
    淺一點不驚濃艷閱讀 453評論 0 1