一步一步學(xué)WebPack2
最近將webpack的使用總結(jié)一下牵舱,便于下一步的使用瓷翻。本文通過若干的demo仰税,讓你一步一步學(xué)會使用webpack构资。webpack中一切都是模塊,所有的一切(JS陨簇,CSS吐绵,圖片,HTML)都可以被視作模塊河绽,通過require加載己单。模塊加載器會把所有的模塊最終打包生成一個巨大的“bundle.js”文件荆针,并且會一直不停進(jìn)行加載疗垛!所以Webpack通過大量的特性去分割你的代碼,生成多個“bundle”片段孝常,并且異步地加載項目的不同部分苟跪。
- 先安裝Node環(huán)境廷痘。
- 安裝安裝一個簡單的便于測試的server,推薦簡單的http-server削咆。
- 源碼地址:https://github.com/fujusong/webpack-starter.git
npm install http-server -g
Demo1 - Start
- 建立node項目:npm init 牍疏,名字為demo1,得到package.json文件
{
"name": "demo1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fujusong/webpack-starter.git"
},
"keywords": [
"webpack",
"starter"
],
"author": "sofu",
"license": "MIT",
"bugs": {
"url": "https://github.com/fujusong/webpack-starter/issues"
},
"homepage": "https://github.com/fujusong/webpack-starter#readme",
"devDependencies": {
"webpack": "^2.6.1"
}
}
- 創(chuàng)建index.html 拨齐,并新建一個id為app的div鳞陨。
#touch index.html
#vi index.html
<!DOCTYPE html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
- 創(chuàng)建index.js
#touch index.js
var app=document.getElementById('app');
app.innerHTML="Hello My WebPack App";
- 安裝webpack開發(fā)依賴
npm install webpack –-save-dev
- 利用webpack將index.js文件打包為bundle.js文件
./node_modules/webpack/bin/webpack.js index.js bundle.js
- 修改index.html文件,加入bundle.js瞻惋。
<!DOCTYPE html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></script>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
- 運行http-server厦滤,打開瀏覽器查看頁面
http-server -p 8000
然后在瀏覽器打開http://localhost:8000
Demo2 - Data Update
- 創(chuàng)建src和dist兩個文件夾,把index.js移動到src文件夾里歼狼,bundle.js是webpack打包生成出來的掏导,使用先刪除再生成的辦法確保文件正常更新,以后會把dist作為生成文件存放的目標(biāo)文件夾羽峰。
- 安裝rimraf 用于打包前刪除舊的生成文件趟咆。
npm install rimraf –-save-dev
- 修改package.json的script啟動方式
{
"name": "demo1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"rimraf dist && webpack src/index.js dist/bundle.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fujusong/webpack-starter.git"
},
"keywords": [
"webpack",
"starter"
],
"author": "sofu",
"license": "MIT",
"bugs": {
"url": "https://github.com/fujusong/webpack-starter/issues"
},
"homepage": "https://github.com/fujusong/webpack-starter#readme",
"devDependencies": {
"rimraf": "^2.6.1",
"webpack": "^2.6.1"
}
}
- 運行 npm run build 打包一下,在dist目錄下得到了bundle.js
- 把index.html里面引用bundle.js的路徑改成./dist/bundle.js梅屉,再運行http-server值纱。
引入Module,文件監(jiān)控坯汤。
- 接下來在src目錄下新建messages.js文件
module.exports={ data:'Hello,World!', event:'APP Event'};
- 在index.js文件引入messages.js虐唠,并實例到頁面
var messages=require('./message');
var app=document.getElementById('app');
app.innerHTML = messages.data+"From "+ messages.event;
- 把package.json修改一下,build的結(jié)尾加上監(jiān)視命令–watch
"build":"rimraf dist && webpack src/index.js dist/bundle.js --watch"
- 運行npm run build重新打包惰聂,可以看到打包過程并沒有結(jié)束跳出疆偿,仍然是待命狀態(tài)咱筛。
- 另起一個cli,啟動http-server -p 8000杆故,在瀏覽器輸入localhost:8000
- 修改messages.json消息內(nèi)容迅箩,然后刷新瀏覽器,可以看到內(nèi)容隨即更新了反番。
Demo3 - Webpack-dev-server 1
- 安裝webpack-dev-server
npm install webpack-dev-server –-save-dev
- 創(chuàng)建
webpack.config.js
文件沙热,并添加基本配置
var path = require('path'); // 導(dǎo)入路徑包
module.exports={
entry:'./src/index.js',//入口文件
output:{
path:path.join(__dirname,'dist'),// 指定打包之后的文件夾
publicPath:'/dist/',// 指定資源文件引用的目錄
filename:'bundle.js'// 指定打包為一個文件 bundle.js
}
}
- 打包所需的路徑都已在
webpack.config.js
配置后,package.json
的build則去掉路徑罢缸,并添加webpack-dev-server
啟動:"dev":"webpack-dev-server"
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist && webpack --watch",
"dev": "webpack-dev-server"
},
...
- 運行npm run dev啟動webpack-dev-server進(jìn)行打包,在瀏覽器輸入localhost:8080直接打開投队。
- 修改messages.json的內(nèi)容枫疆,保存,可以看到瀏覽器實時更新了數(shù)據(jù)
Demo4 - Webpack-dev-server 2
對于webpack-dev-server敷鸦,每次修改代碼后息楔,webpack可以自動重新打包,webpack-dev-server有兩個用于自動刷新模式:iframe和inline扒披,瀏覽器可以響應(yīng)代碼變化并自動刷新(hot)值依。
iframe
頁面被嵌套在一個iframe下,代碼發(fā)生改動后碟案,iframe會重新加載
使用此模式無需額外配置愿险,只需訪問http://localhost:8080/webpack-dev-server/index.html
即可,顯然webpack-dev-server默認(rèn)的模式就是iframe价说。
inline
為整個頁面提供了“Live reloading”功能辆亏。webpack官方提供的一個小型Express服務(wù)器。
hot
提供了“模塊熱重載”功能鳖目,它會嘗試僅僅更新組件被改變的部分(而不是整個頁面)扮叨。會嘗試先去通過 HMR 更新然后可能嘗試刷新整個頁面。只需要加上一個 webpack/hot/dev-server entry point
领迈,并且在 dev-server 調(diào)用時加上參數(shù) –hot
彻磁。如果我們把inline和hot這兩個選項都寫上,那么當(dāng)文件被改動時狸捅,webpack-dev-server會先嘗試HMR衷蜓,如果這不管用,它就會重新加載整個頁面薪贫。
hot(HMR)和inline使用有兩種方式:CLI和Node.js API
CLI方式比較簡單恍箭,只需修改package.json中scripts配置,添加 –inline –hot
"dev": "webpack-dev-server –inline –hot"
node.js API方式
- 在主目錄下瞧省,新建dev-server.js文件
var WebpackDevServer=require('webpack-dev-server');
var webpack=require('webpack');
var config=require('./webpack.config');
var path=require('path');
var compiler=webpack(config);
var server=new WebpackDevServer(
compiler,
{//創(chuàng)建服務(wù)器實例
hot:true,//HMR配置
filename:config.output.filename,
publicPath:config.output.publicPath,//必填
stats:{
colors:true
}
}
);
server.listen(8080,'localhost',function(){});
- 修改webpack.config.js配置
var path=require('path');// 導(dǎo)入路徑包
var webpack=require('webpack');
module.exports={
entry:[//入口文件
'./src/index.js',
'webpack/hot/dev-server',//調(diào)用熱重載 hot
'webpack-dev-server/client?http://localhost:8080'
//添加webpack-dev-server客戶端
],
plugins:[
new webpack.HotModuleReplacementPlugin()//全局開啟熱代碼替換
],
output:{
path:path.join(__dirname,'dist'),// 指定打包之后的文件夾
publicPath:'/dist/',// 指定資源文件引用的目錄
filename:'bundle.js'// 指定打包為一個文件 bundle.js
}
}
- 在index.js最底下添加hot調(diào)用
if(module.hot){//啟用熱重載
module.hot.accept();
}
- 修改package.json啟動方式
...
"scripts": {
"build": "rimraf dist && webpack --watch",
"dev": "node dev-server.js"
},
...
- 運行npm run dev 扯夭,在瀏覽器輸入
localhost:8080
查看鳍贾,然后嘗試修改index.js
或messages.json
的數(shù)據(jù),保存交洗,瀏覽器自動刷新了
Demo5 - Development and Production
在入口處區(qū)分生產(chǎn)環(huán)境和開發(fā)環(huán)境骑科。
- 修改package.json的script項,通過set NODE_ENV來設(shè)置環(huán)境變量
...
"scripts": {
"build": "rimraf dist && set NODE_ENV=production&& webpack",
"dev": "set NODE_ENV=development&& node dev-server.js"
},
...
- 修改
webpack.config.js
构拳,在入口處添加NODE_ENV
環(huán)境判斷使用生產(chǎn)環(huán)境還是開發(fā)環(huán)境的入口文件及插件咆爽。process.env.NODE_ENV
可以獲取到啟動文件的環(huán)境變量,nodejs的app.get('env')
也可以取得置森。
var path=require('path');
var webpack=require('webpack');
var DEVELOPMENT=process.env.NODE_ENV==='development';
var PRODUCTION=process.env.NODE_ENV==='production';
var entry=PRODUCTION ? ['./src/index.js'] :
[
'./src/index.js',
'webpack/hot/dev-server',//開啟熱重載 hot
'webpack-dev-server/client?http://localhost:8080'
//添加webpack-dev-server客戶端
];
var plugins=PRODUCTION ? [] :
[
new webpack.HotModuleReplacementPlugin()
//全局開啟代碼熱替換 如果是CLI這里則不用寫
];
module.exports={
entry:entry,//入口文件
plugins:plugins,
output:{
path:path.join(__dirname,'dist'),// 指定打包之后的文件夾
publicPath:'/dist/',// 指定資源文件引用的目錄
filename:'bundle.js'// 指定打包為一個文件 bundle.js
}
}
3.然后分別運行npm run dev 和npm run build斗埂。
Demo6 - babel for es6/es7
- 安裝babel核心模塊
npm install babel-core babel-loader babel-preset-es2015 babel-preset-stage-0 -save-dev
具體各模塊的作用:
"babel-core" //轉(zhuǎn)換器
"babel-loader" //轉(zhuǎn)換器的加載器
"babel-preset-es2015" //ES2015轉(zhuǎn)碼規(guī)則
"babel-preset-stage-0" //es7支持,ES7不同階段語法提案的轉(zhuǎn)碼規(guī)則(共有4個階段)凫海,選裝一個stage-0呛凶,stage-1,stage-2行贪,stage-3
- 在項目文件添加.babelrc文件漾稀,加入轉(zhuǎn)碼規(guī)則
```json
{ "presets":["es2015","stage-0"]}
- 修改webpack.config.js文件,添加module rules模塊設(shè)置
...
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
}
]
}
...
- 在index.js中添加es6格式的方法
var messages=require('./message');
var newMessage = ()=>('<p>'+messages.data +' -From '+ messages.event+"</p>");
var app=document.getElementById('app');
app.innerHTML=newMessage();
if(module.hot){//啟用熱重載
module.hot.accept();
}
- 運行npm run dev測試建瘫,可修改數(shù)據(jù)驗證程序崭捍。
Demo7 - File Loader for Image
在
webpack.config.js
的添加devtool:'source-map'
,用于在打包代碼的同時生成一個sourcemap文件啰脚,并在打包文件的末尾添加//# souceURL殷蛇,注釋會告訴JS引擎原始文件位置在src目錄內(nèi)新建img文件夾,復(fù)制二張圖片進(jìn)來供測試用拣播。這里使用的一張名為s1.png的小圖片晾咪,大小為9k。另一張名為s2.jpg贮配,大小191k谍倦。
在src目錄內(nèi)新建Icon.js文件
const icon=require('./img/s1.png');
const Image=``;
export default Image;
- 在src目錄內(nèi)新建Img.js文件
const img=require('./img/s2.jpg');
const Image=``;
export default Image;
- 安裝文件加載器
npm install file-loader –-save-dev
- 修改webpack.config.js文件,添加file-loader加載器
...
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.(jpe?g|png)$/,
use: ['file-loader']
},
]
},
...
- 修改index.js泪勒,通過import加載圖片到頁面
import icon from './Icon';
import img from './Img';
var messages=require('./message');
var newMessage = ()=>('<p>'+messages.data +' -From '+ messages.event+"</p>");
var newMessage2=()=>(
`<p>${icon} ${img}</p>`
);
var app=document.getElementById('app');
app.innerHTML=newMessage();
app.innerHTML+=newMessage2();
if(module.hot){//啟用熱重載
module.hot.accept();
}
Demo8 - URL Loader for Images
使用URL Loader加載圖片昼蛀,limit參數(shù)可以使用base64將小圖片內(nèi)聯(lián)在代碼中,減少http請求圆存。
- 安裝url-loader
npm install url-loader –-save-dev
- 修改
webpack.config.js
叼旋,將圖片的loaders改為url-loader?limit=10000&name=images/[hash:12].[ext]
,小于10k的圖片將會以base64的形式內(nèi)聯(lián)在代碼中沦辙,并且圖片打包到images文件內(nèi)夫植,以哈希值命名。
...
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.(jpe?g|png)$/,
use: ['url-loader?limit=10000&name=images/[hash:12].[ext]']
},
]
},
...
3.輸入npm run dev
測試,可以看到s1.png已經(jīng)被base64內(nèi)聯(lián)详民。s2.jpg文件名稱也變成了hash名稱延欠。
Demo9 - Add Button
- 在src文件目錄新建button.js
const Button={
button:'<button id="myButton">Press me</button>',
attachEl:()=>{
document.getElementById('myButton').addEventListener('click',()=>{
// debugger;
console.log('clicked');
})
}};
export default Button;
- 修改webpack.config.js,添加dev-tool:’sourse-map’沈跨,打包代碼的同時生成一個sourcemap文件由捎。
...
module.exports={
entry:entry,//入口文件
devtool:'source-map',//打包代碼的同時生成一個sourcemap文件,并在打包文件的末尾添加souceURL注釋,注釋會告訴JS引擎原始文件位置
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
}
]
},
...
- 修改index.js文件饿凛,加載button模塊并實例化狞玛。
import Button from './button';
var newMessage=()=>(Button.button);
var app=document.getElementById('app');
app.innerHTML=newMessage();
Button.attachEl();
if(module.hot){
module.hot.accept();
}
- 運行測試,點擊頁面中的按鈕涧窒,可以看到控制臺輸出了測試文字
Demo10 - compress source code
- 修改webpack.config.js里的plugins變量心肪,添加生產(chǎn)模式時加載插件。
var plugins = PRODUCTION ? [
new webpack.optimize.UglifyJsPlugin(/*{//代碼壓縮
comments:true,//顯示注釋
mangle:false,//取消代碼混淆
compress:{
warnings:true//在UglifyJs刪除沒有用到的代碼時不輸出警告
}
}*/)
] : [
new webpack.HotModuleReplacementPlugin()//全局開啟代碼熱替換 如果是CLI這里則不用寫
];
plugins.push(
new webpack.DefinePlugin({
DEVELOPMENT:JSON.stringify(DEVELOPMENT),
PRODUCTION:JSON.stringify(PRODUCTION)
})
);
- 修改index.js纠吴,將環(huán)境信息輸出到頁面
var newMessage = ()=>{
return `DEV:${DEVELOPMENT.toString()} <br> PRO:${PRODUCTION.toString()}`;
}
var app=document.getElementById('app');
app.innerHTML=newMessage();
if(DEVELOPMENT){
if(module.hot){//啟用熱重載
module.hot.accept();
}
}
3.分別運行npm run dev 和 npm run build可以看到頁面上顯示的環(huán)境蒙畴,再查看bundle.js,可以看到代碼已經(jīng)按照設(shè)置輸出呜象。
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf dist && NODE_ENV=production webpack && http-server -p 3000",
"dev": "NODE_ENV=development node dev-server.js"
},
...
4.回到webpack.config.js,把UglifyJsPlugin的參數(shù)都去掉碑隆,使用默認(rèn)參數(shù)
var plugins=PRODUCTION ? [
new webpack.optimize.UglifyJsPlugin()
] : [
new webpack.HotModuleReplacementPlugin()//全局開啟代碼熱替換 如果是CLI這里則不用 寫
];
5.再次運行npm run build打包恭陡,此時bundle.js已經(jīng)被壓縮至最小化。
Demo 11 - Load CSS
- 安裝css-loader和style-loader:npm install css-loader style-loader -save-dev上煤。
- css-loader 在js文件里休玩,通過require的方式來引入css
- style-loader 在html中以style的方式嵌入css
2.在src目錄下,創(chuàng)建style文件夾劫狠,并創(chuàng)建一個css文件拴疤,這里命名為:globalStyle.css
body{
background:#ddd;
}
:local(.box){
background-color:#ff0;
padding:1em;
border:1px solid #000;
}
3.在webpack.config.js
添加css的loader,webpack的loader的配置是從右往左的独泞,就是先使用css-loader之后使用style-loader
...
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.css$/,
loaders: ["style-loader","css-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
}
]
},
...
- 修改index.js呐矾,引入css文件,并將相應(yīng)的class添加進(jìn)頁面懦砂。
var style=require('./style/globalStyle.css');
const newMessage=()=>(
`<div class="${style.box}">
DEV:${DEVELOPMENT.toString()}<br>
PRO:${PRODUCTION.toString()}<br>
</div>`
var app=document.getElementById(‘a(chǎn)pp’);
app.innerHTML=newMessage();
if(DEVELOPMENT){
if(module.hot){//啟用熱重載
module.hot.accept();
}
}
- 測試頁面蜒犯,可以看到頁面的樣式已經(jīng)更新,查看源碼荞膘,原本div的classs為box的罚随,已經(jīng)被hash名稱所代替。hash名稱可以在
webpack.config.js
里css的加載器里自定義
...
test: /\.css$/,
use: ["style-loader","css-loader?localIdentName=[path][name]--[local]"],
...
- 當(dāng)需要將生產(chǎn)環(huán)境和開發(fā)環(huán)境命名進(jìn)行區(qū)分時羽资,可以寫在一個變量或常量里
...
const cssIdentifier=PRODUCTION? '[hash:base64:10]' : '[path][name]---[local]';
...
...
use: ["style-loader","css-loader?localIdentName=" + cssIdentifier],
...
...
查看頁面源碼時淘菩,可以看到webpack打包時,是把樣式文件以style的方式嵌在head里的
Demo12 - CSS Load Seprate
- 安裝插件用于將css樣式打包成獨立的文件屠升。
npm install extract-text-webpack-plugin -save-dev
- 需求是在開發(fā)環(huán)境樣式還是嵌在頁面上不變潮改,只在打包到生產(chǎn)環(huán)境時狭郑,才單獨打包到一個叫
style.css
的文件里,因此webpack.config.js
里进陡,先引入extract-text-webpack-plugin
插件愿阐,然后在插件欄設(shè)置打包時的名稱以及提取css加載時的路徑
...
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var DEVELOPMENT=process.env.NODE_ENV==='development';
var PRODUCTION=process.env.NODE_ENV==='production';
var entry=PRODUCTION ? ['./src/index.js'] : [
'./src/index.js',
'webpack/hot/dev-server',//開啟熱重載 hot
'webpack-dev-server/client?http://localhost:8080'//添加webpack-dev-server客戶端
];
var plugins = PRODUCTION ? [
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('style.css'),
] :
[
new webpack.HotModuleReplacementPlugin()//全局開啟代碼熱替換 如果是CLI這里則不用寫
];
plugins.push(
new webpack.DefinePlugin({
DEVELOPMENT:JSON.stringify(DEVELOPMENT),
PRODUCTION:JSON.stringify(PRODUCTION)
})
);
const cssIdentifier=PRODUCTION? '[hash:base64:10]' : '[path][name]--[local]';
const cssLoader=PRODUCTION ? ExtractTextPlugin.extract('css-loader?localIdentName=' + cssIdentifier) :
['style-loader','css-loader?localIdentName=' + cssIdentifier];
module.exports={
entry:entry,//入口文件
module: {
rules:[
{
test: /\.js$/,
use: ["babel-loader"],
exclude: path.resolve(__dirname, 'node_modules'),
},
{
test: /\.css$/,
//use: ["style-loader","css-loader"],
use: cssLoader,
exclude: path.resolve(__dirname, 'node_modules'),
}
]
},
...
- index.html頁面要單獨加載打包生成的樣式文件style.css
<link rel="stylesheet" href="./dist/style.css">
然后運行運行npm run build 查看,此時style.css是單獨生成的趾疚。
style.css的名稱也可以用hash表示
new ExtractTextPlugin(
'style-[contenthash:10].css'//根據(jù)內(nèi)容生成hash值
,{allChunks: true}//所有分離文件的樣式也會全部壓縮到一個文件上
)
Demo13 - HTML Template
- 安裝模板插件
npm install html-webpack-plugin -save-dev
2.創(chuàng)建html模版:index-template.html
<!DOCTYPE html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="app"></div>
</body>
</html>
- 在
webpack.config.js
頂部導(dǎo)入模版插件
var HTMLWebpackPlugin=require('html-webpack-plugin');
- 在plugins處實例化缨历,并將模版文件設(shè)置為
index-template.html
var plugins=PRODUCTION ? [
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin(
'style-[contenthash:10].css'//根據(jù)內(nèi)容生成hash值
),
new HTMLWebpackPlugin({// webpack 指定目錄(package內(nèi)設(shè)置)生成靜態(tài)HTML文件
template:'index-template.html'
})
] : [
new webpack.HotModuleReplacementPlugin()//全局開啟代碼熱替換 如果是CLI這里則不用寫
- 靜態(tài)文件在dist內(nèi)生成名為index.html的文件,其他資源路徑將和開發(fā)環(huán)境不同糙麦,所以需要設(shè)置區(qū)分判斷辛孵。
output:{
path:path.join(__dirname,'dist'),// 指定打包之后的文件夾
publicPath: PRODUCTION ? '/' : '/dist/',
filename: PRODUCTION ? 'bundle.[hash:12].min.js' : 'bundle.js'// 指定打包為一個文件 bundle.js
}
- 修改package.json,運行npm run build打包測試赡磅。
...
"scripts": {
"build": "rimraf dist && NODE_ENV=production webpack && http-server ./dist -p 3000 ",
"dev": "NODE_ENV=development node dev-server.js"
},
...
demo14 - Tabs Pages
- 在src文件內(nèi)新建
page1.js
const page=`<h1>頁面1</h1>`;
export default page;
- 在src文件內(nèi)新建
page2.js
const page=`<h1>頁面2</h1>`;
export default page;
- 修改index.js魄缚,創(chuàng)建兩個按鈕,并添加相應(yīng)的點擊事件焚廊,事件觸發(fā)時使用System導(dǎo)入頁面并將頁面的的內(nèi)容復(fù)制到content內(nèi)冶匹。
var app=document.getElementById('app');
app.innerHTML=`
<div id="menu">
<button id="loadPage1">Load1</button>
<button id="loadPage2">Load2</button>
</div>
<div id="content">
<h1>home</h1>
</div>`;
document.getElementById('loadPage1').addEventListener('click',()=>{
//System.import 會令每個可能的模塊都產(chǎn)生一個獨立的塊(chunk)。
System.import('./page1').then(pageModule=>{
document.getElementById('content').innerHTML=pageModule.default;
})
});
document.getElementById('loadPage2').addEventListener('click',()=>{
System.import('./page2').then(pageModule=>{
document.getElementById('content').innerHTML=pageModule.default;
})
});
if(DEVELOPMENT){
if(module.hot){//啟用熱重載
module.hot.accept();
}}
- 運行npm ren dev測試咆瘟,在這之前嚼隘,別忘記把index.html引用css和js的路徑改回來
- 打開瀏覽器的network,來回點擊按鈕1和按鈕2袒餐,觀察network加載的內(nèi)容飞蛹,可以發(fā)現(xiàn),0.bandle.js和1.bandle.js是異步加載灸眼,并且不會被重復(fù)加載卧檐。
Demo15 - Jquery
- 安裝jquery插件
npm install jquery –-save-dev
- 在index.js中導(dǎo)入jquery,并創(chuàng)建一個jquery實例
import $ from 'jquery';
$('#app').css('background','#ff0');
- 運行測試時焰宣,app背景已經(jīng)發(fā)生改變霉囚。運行打包后,jquery也被打包進(jìn)了bundle.js宛徊,這并不是我們想要的佛嬉。而且,jquery并非全局闸天,僅可在index.js使用暖呕,想要將jquery加載為全局模塊,需要在webpack.config.js中設(shè)置externals
...
module.exports={
externals:{
'jquery':'jQuery'
},
devtool:'source-map',
entry:entry,//入口文件
plugins:plugins,
...
- 然后jquery需要從外部加載進(jìn)來苞氮,分別添加到
index.html
和index-template.html
的head中湾揽,建議使用網(wǎng)上的jquery的CDN。如:
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
- 分別運行開發(fā)環(huán)境和生產(chǎn)環(huán)境查看,jquery從外部加載库物,沒有被打包進(jìn)bundle.js霸旗。