webpack開發(fā)部署技巧

如果你還沒有看第一篇 請(qǐng)先看下第一篇的基礎(chǔ)知識(shí):webpack開發(fā)配置

開發(fā)技巧

啟用source-map

現(xiàn)在的代碼是合并以后的代碼贺辰,不利于排錯(cuò)和定位逼裆,只需要在config中添加

...
  devtool: 'eval-source-map',
 ...

這樣出錯(cuò)以后就會(huì)采用source-map的形式直接顯示你出錯(cuò)代碼的位置稽物。

配置webpack-dev-server代理

既然常用webpack做React一類的SPA巢价,那么一個(gè)典型的例子就是前后端分離倒得。后端是一個(gè)RESTful的server不管用什么寫的农渊。假定在本機(jī)他是類似[http://localhost:5000/api/@*
]這類的請(qǐng)求患蹂,現(xiàn)在添加配置讓ajax請(qǐng)求可以直接proxy過去。

 devServer: {
        hot: true,
        inline: true,
        //其實(shí)很簡(jiǎn)單的砸紊,只要配置這個(gè)參數(shù)就可以了
        proxy: {
          '/api/*': {
              target: 'http://localhost:5000',
              secure: false
          }
        }
    },

更多的方法可以看官方文檔 Webpack dev server proxy

使用preLoaders和postLoaders

也許你想在寫代碼的時(shí)候檢查自己的js是否符合jshint的規(guī)范传于,那么隆重推薦preLoaders和postLoaders,上一節(jié)我們已經(jīng)非常了解loaders了醉顽,用它來處理各種類型的文件沼溜。perLoaders顧名思義就是在loaders執(zhí)行之前處理的,webpack的處理順序是perLoaders - loaders - postLoaders游添。

在config文件中配置
module: {
...
    //和loaders一樣的語法系草,很簡(jiǎn)單
    perLoaders: [
        {
            test: /\.jsx?$/,
            include: APP_PATH,
            loader: 'jshint-loader'
        }
    ]
}

...
//配置jshint的選項(xiàng)通熄,支持es6的校驗(yàn)
jshint: {
  "esnext": true
},

好了 現(xiàn)在每次npm run start的時(shí)候就可以看到j(luò)shint的提示信息啦

加載jQuery plugin或者其他legacy第三方庫

這個(gè)是非常有用的內(nèi)容!

你的項(xiàng)目有時(shí)候會(huì)要加載各種各樣的第三方庫,一些老的庫不支持AMD或者CommonJS等一些先進(jìn)的格式找都,比如一些jQuery的插件唇辨,它們都依賴jQuery,如果直接引用就會(huì)報(bào)錯(cuò) jQuery is not undefined這類的錯(cuò)誤檐嚣,有幾種方法解決

先創(chuàng)建一個(gè)jQuery plugin: plugin.js

(function ($) {
    const shade = "#556b2f";
    $.fn.greenify = function() {
        this.css( "color", shade );
        return this;
    };
}(jQuery));
第一種方法 使用webpack.ProvidePlugin
  ...
  plugins: [
    new HtmlwebpackPlugin({
      title: 'Hello World app'
    }),
    //provide $, jQuery and window.jQuery to every script
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery"
    })
  ]
  ...

在js中引用

...
//這個(gè)也不需要了 因?yàn)?, jQuery, window.jQuery都可以直接使用了
//import $ from 'jquery';
import './plugin.js';
...
myPromise.then((number) => {
  $('body').append('<p>promise result is ' + number + ' now is ' + moment().format() + '</p>');
  //call our jquery plugin!
  $('p').greenify();
});
...

發(fā)現(xiàn)我們插入的p里面的顏色已經(jīng)變成了綠色!

第二種方法 使用imports-loader

先安裝這個(gè)loader

npm install imports-loader --save-dev

然后在入口js中

//注意這種寫法 我們把jQuery這個(gè)變量直接插入到plugin.js里面了
//相當(dāng)于在這個(gè)文件的開始添加了 var jQuery = require('jquery');
import 'imports?jQuery=jquery!./plugin.js';

//后面的代碼一樣
myPromise.then((number) => {
  $('body').append('<p>promise result is ' + number + ' now is ' + moment().format() + '</p>');
  //call our jquery plugin!
  $('p').greenify();
});

部署上線

剛才說的各種情況都是在開發(fā)時(shí)候的情況啰扛,那么假如項(xiàng)目已經(jīng)開發(fā)完了嚎京,需要部署上線了。我們應(yīng)該新創(chuàng)建一個(gè)單獨(dú)的config文件隐解,因?yàn)椴渴鹕暇€使用webpack的時(shí)候我們不需要一些dev-tools,dev-server和jshint校驗(yàn)等鞍帝。

復(fù)制我們現(xiàn)有的config文件,命名為 webpack.production.config.js煞茫,將里面關(guān)于 devServer等和開發(fā)有關(guān)的東西刪掉帕涌。

在package.json中添加一個(gè)命令。

 "scripts": {
    "start": "webpack-dev-server --hot --inline",
    "build": "webpack --progress --profile --colors --config webpack.production.config.js"
  },

當(dāng)要上線的時(shí)候,運(yùn)行

npm run build

可以發(fā)現(xiàn)build文件夾中生成了所有東西续徽。

分離app.js和第三方庫

現(xiàn)在我們build出來的只有一個(gè)bundle.js 如果第三方庫很多的話蚓曼,會(huì)造成這個(gè)文件非常大,減慢加載速度钦扭,現(xiàn)在我們要把第三方庫和我們app本身的代碼分成兩個(gè)文件纫版。

修改entry入口文件
  entry: {
    app: path.resolve(APP_PATH, 'index.js'),
    //添加要打包在vendors里面的庫
    vendors: ['jquery', 'moment']
  },
添加CommonsChunkPlugin
 plugins: [
    //這個(gè)使用uglifyJs壓縮你的js代碼
    new webpack.optimize.UglifyJsPlugin({minimize: true}),
    //把入口文件里面的數(shù)組打包成verdors.js
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js'),
    new HtmlwebpackPlugin({
      title: 'Hello World app'
    })
  ]

添加完畢 運(yùn)行npm run build

在build文件夾中發(fā)現(xiàn)如下結(jié)構(gòu)

  • budle.js
  • index.html
  • vendors.js

生成多頁面

應(yīng)用不可能都是SPA,不可能只生成一個(gè)html文件客情,如果想生成多個(gè)html頁面這么玩其弊?其實(shí)也是很簡(jiǎn)單的: 現(xiàn)在的需求是這樣的,有兩個(gè)頁面膀斋,一個(gè)叫index.html 它需要引用vendors.js和app.js這兩個(gè)文件梭伐,還有一個(gè)mobile.html頁面他要引用vendors.js和mobile.js這兩個(gè)文件。

首先新建一個(gè)叫mobile.js的入口文件仰担,比app.js更簡(jiǎn)單一些

import './main.scss';
import $ from 'jquery';
import 'imports?jQuery=jquery!./plugin.js';

$(document).ready(function() {
  let app  = document.createElement('div');
  app.innerHTML = '<h1>Hello World</h1>';
  document.body.appendChild(app);
  $('h1').greenify();
});

在config里面配置

 entry: {
    //三個(gè)入口文件糊识,app, mobile和 vendors
    app: path.resolve(APP_PATH, 'index.js'),
    mobile: path.resolve(APP_PATH, 'mobile.js'),
    vendors: ['jquery', 'moment']
  },
  output: {
    path: BUILD_PATH,
    //注意 我們修改了bundle.js 用一個(gè)數(shù)組[name]來代替,他會(huì)根據(jù)entry的入口文件名稱生成多個(gè)js文件摔蓝,這里就是(app.js,mobile.js和vendors.js)
    filename: '[name].js'
  },

原來我們是沒有模版文件的技掏,原來利用的HtmlWebpackPlugin的默認(rèn)模版。誰想到這偉大的插件還可以自定義模版项鬼。 所以新建一個(gè)專門放模版的文件夾templates,在里面加兩個(gè)模版文件index.html 和 mobile.html

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>{%= o.htmlWebpackPlugin.options.title %}</title>
  </head>
  <body>
    <h3>Welcome to webpack</h3>
  </body>
</html>
mobile.html
<!DOCTYPE html>
<html>
  <head>
    <title>{%= o.htmlWebpackPlugin.options.title %}</title>
  </head>
  <body>
    <h3>Welcome to mobile page</h3>
  </body>
</html>

繼續(xù)配置config.js,現(xiàn)在讓HtmlwebpackPlugin可以生成多個(gè)文件

...
//Template的文件夾路徑
var TEM_PATH = path.resolve(ROOT_PATH, 'templates');
...
plugins: [
  ...
  //創(chuàng)建了兩個(gè)HtmlWebpackPlugin的實(shí)例哑梳,生成兩個(gè)頁面
  new HtmlwebpackPlugin({
    title: 'Hello World app',
    template: path.resolve(TEM_PATH, 'index.html'),
    filename: 'index.html',
    //chunks這個(gè)參數(shù)告訴插件要引用entry里面的哪幾個(gè)入口
    chunks: ['app', 'vendors'],
    //要把script插入到標(biāo)簽里
    inject: 'body'
  }),
  new HtmlwebpackPlugin({
    title: 'Hello Mobile app',
    template: path.resolve(TEM_PATH, 'mobile.html'),
    filename: 'mobile.html',
    chunks: ['mobile', 'vendors'],
    inject: 'body'
  })
  ...
]

然后運(yùn)行

npm run build

看看生成好的偉大的文件,沒問題绘盟!

  • app.js
  • mobile.js
  • vendors.js
  • index.html
  • mobile.html

看看引用的對(duì)應(yīng)關(guān)系鸠真,完美C跸伞!

index.html
<body>
  <h3>Welcome to webpack</h3>
  <script src="vendors.js"></script><script src="app.js"></script>
</body>
mobile.html
<body>
  <h3>Welcome to mobile page</h3>
  <script src="vendors.js"></script><script src="mobile.js"></script>
</body>

生成Hash名稱的script來防止緩存

經(jīng)典問題,代碼更新了吠卷,但是瀏覽器有緩存锡垄,到時(shí)候就傻了。 怎么解決祭隔,換名字唄货岭。可以直接在后面加參數(shù),也可以直接換掉文件名字疾渴。 webpack提供給了我們非常簡(jiǎn)單的方法千贯,基于文件的md5,只要把

output: {
  path: BUILD_PATH,
  //只要再加上hash這個(gè)參數(shù)就可以了
  filename: '[name].[hash].js'
},

運(yùn)行完build以后搞坝,看看生成的文件搔谴,很完美~

index.html
<body>
  <h3>Welcome to webpack</h3>
  <script src="vendors.js"></script><script src="app.b6641abee64c999d95c1.js"></script>
</body>

好了,你現(xiàn)在了解webpack作為一個(gè)module bundler的精髓了吧桩撮,把我們的例子做成一個(gè)圖敦第,幫助你理解一下。

image.png

文件壓縮

//使用插件html-webpack-plugin打包合并html
//使用插件extract-text-webpack-plugin打包獨(dú)立的css
//使用UglifyJsPlugin壓縮代碼
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require("webpack");
module.exports = {
    entry: {
        bundle : './src/js/main.js'
    },
    output: {
        filename: "[name]-[hash].js",
        path: __dirname + '/dist'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: "css-loader"
                })
            }
        ]
    },
    resolve:{
            extensions:['.js','.css','.json']  //用于配置程序可以自行補(bǔ)全哪些文件后綴
    },

    plugins:[
        new HtmlWebpackPlugin({
            title: 'hello webpack',
            template:'src/component/index.html',
            inject:'body',
            minify:{ //壓縮HTML文件
                 removeComments:true,    //移除HTML中的注釋
                 collapseWhitespace:true    //刪除空白符與換行符
             }
        }),
        new ExtractTextPlugin("[name].[hash].css"),
        new webpack.optimize.UglifyJsPlugin({
            compress: {     //壓縮代碼
                dead_code: true,    //移除沒被引用的代碼
            },
            except: ['$super', '$', 'exports', 'require']    //混淆,并排除關(guān)鍵字
        })
    ]
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末店量,一起剝皮案震驚了整個(gè)濱河市芜果,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌融师,老刑警劉巖师幕,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诬滩,居然都是意外死亡霹粥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門疼鸟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來后控,“玉大人,你說我怎么就攤上這事空镜『铺裕” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵吴攒,是天一觀的道長张抄。 經(jīng)常有香客問我,道長洼怔,這世上最難降的妖魔是什么署惯? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮镣隶,結(jié)果婚禮上极谊,老公的妹妹穿的比我還像新娘诡右。我一直安慰自己,他們只是感情好轻猖,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布帆吻。 她就那樣靜靜地躺著,像睡著了一般咙边。 火紅的嫁衣襯著肌膚如雪猜煮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天败许,我揣著相機(jī)與錄音王带,去河邊找鬼。 笑死檐束,一個(gè)胖子當(dāng)著我的面吹牛辫秧,可吹牛的內(nèi)容都是我干的束倍。 我是一名探鬼主播被丧,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绪妹!你這毒婦竟也來了甥桂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤邮旷,失蹤者是張志新(化名)和其女友劉穎黄选,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體婶肩,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡办陷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了律歼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片民镜。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖险毁,靈堂內(nèi)的尸體忽然破棺而出制圈,到底是詐尸還是另有隱情,我是刑警寧澤畔况,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布鲸鹦,位于F島的核電站,受9級(jí)特大地震影響跷跪,放射性物質(zhì)發(fā)生泄漏馋嗜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一吵瞻、第九天 我趴在偏房一處隱蔽的房頂上張望嵌戈。 院中可真熱鬧覆积,春花似錦、人聲如沸熟呛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庵朝。三九已至吗冤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間九府,已是汗流浹背椎瘟。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侄旬,地道東北人肺蔚。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像儡羔,于是被迫代替她去往敵國和親宣羊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

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

  • GitChat技術(shù)雜談 前言 本文較長汰蜘,為了節(jié)省你的閱讀時(shí)間仇冯,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,698評(píng)論 7 110
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺族操,特此分享以備自己日后查看苛坚,也希望更多的人看到...
    小小字符閱讀 8,178評(píng)論 7 35
  • 一步一步學(xué)WebPack2 最近將webpack的使用總結(jié)一下,便于下一步的使用色难。本文通過若干的demo泼舱,讓你一步...
    wavesnow閱讀 569評(píng)論 0 5
  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,297評(píng)論 4 31
  • 咱們可以想下,節(jié)日的目的是什么枷莉?不就是表達(dá)了一個(gè)美好的祝愿嗎娇昙?對(duì)未來、生活依沮、愛情涯贞、親情等的一種美好的祝愿啊危喉!既然是...
    沈浪閱讀 988評(píng)論 0 2