一步一步學(xué)WebPack 2

一步一步學(xué)WebPack2

最近將webpack的使用總結(jié)一下牵舱,便于下一步的使用瓷翻。本文通過若干的demo仰税,讓你一步一步學(xué)會使用webpack构资。webpack中一切都是模塊,所有的一切(JS陨簇,CSS吐绵,圖片,HTML)都可以被視作模塊河绽,通過require加載己单。模塊加載器會把所有的模塊最終打包生成一個巨大的“bundle.js”文件荆针,并且會一直不停進(jìn)行加載疗垛!所以Webpack通過大量的特性去分割你的代碼,生成多個“bundle”片段孝常,并且異步地加載項目的不同部分苟跪。

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.jsmessages.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=`![](${icon})`; 
export default Image;
  • 在src目錄內(nèi)新建Img.js文件
const img=require('./img/s2.jpg'); 
const Image=`![](${img})`; 
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.htmlindex-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霸旗。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戚揭,隨后出現(xiàn)的幾起案子诱告,更是在濱河造成了極大的恐慌,老刑警劉巖民晒,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件精居,死亡現(xiàn)場離奇詭異,居然都是意外死亡潜必,警方通過查閱死者的電腦和手機靴姿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磁滚,“玉大人佛吓,你說我怎么就攤上這事〈谷粒” “怎么了维雇?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晒他。 經(jīng)常有香客問我谆沃,道長,這世上最難降的妖魔是什么仪芒? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮耕陷,結(jié)果婚禮上掂名,老公的妹妹穿的比我還像新娘。我一直安慰自己哟沫,他們只是感情好饺蔑,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗜诀,像睡著了一般猾警。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隆敢,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天发皿,我揣著相機與錄音,去河邊找鬼拂蝎。 笑死穴墅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玄货,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼皇钞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了松捉?” 一聲冷哼從身側(cè)響起夹界,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隘世,沒想到半個月后可柿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡以舒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年趾痘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔓钟。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡永票,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滥沫,到底是詐尸還是另有隱情侣集,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布兰绣,位于F島的核電站世分,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缀辩。R本人自食惡果不足惜臭埋,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臀玄。 院中可真熱鬧瓢阴,春花似錦、人聲如沸健无。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽累贤。三九已至叠穆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臼膏,已是汗流浹背硼被。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留渗磅,地道東北人祷嘶。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓屎媳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親论巍。 傳聞我的和親對象是個殘疾皇子烛谊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

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