Webpack教程二

Webpack教程一

開發技巧

啓用source-map

如今的代碼是合併之後的代碼,不利於排錯和定位,只須要在config中添加javascript

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

這樣出錯之後就會採用source-map的形式直接顯示你出錯代碼的位置。css

配置webpack-dev-server代理

既然經常使用webpack作React一類的SPA,那麼一個典型的例子就是先後端分離。後端是一個RESTful的server無論用什麼寫的。假定在本機他是相似*這類的請求,如今添加配置讓ajax請求能夠直接proxy過去。html

    devServer: {
        hot: true,
        inline: true,
        //其實很簡單的,只要配置這個參數就能夠了
        proxy: {
          '/api/*': {
              target: 'http://localhost:5000',
              secure: false
          }
        }
    },

重啓之後 發現/api/*的請求都代理到去了~java

更多的方法能夠看官方文檔 Webpack dev server proxyjquery

使用preLoaders和postLoaders

也許你想在寫代碼的時候檢查本身的js是否符合jshint的規範,那麼隆重推薦preLoaders和postLoaders,上一節咱們已經很是瞭解loaders了,用它來處理各類類型的文件。perLoaders顧名思義就是在loaders執行以前處理的,webpack的處理順序是perLoaders - loaders - postLoaderswebpack


安裝jshint
npm install jshint-loader --save-dev

  在config文件中配置git

module: {
...
    //和loaders同樣的語法,很簡單
    perLoaders: [
        {
            test: /\.jsx?$/,
            include: APP_PATH,
            loader: 'jshint-loader'
        }
    ]
}

...
//配置jshint的選項,支持es6的校驗
jshint: {
  "esnext": true
},

好了 如今每次npm run start的時候就能夠看到jshint的提示信息啦es6

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

這個是很是有用的內容!github

你的項目有時候會要加載各類各樣的第三方庫,一些老的庫不支持AMD或者CommonJS等一些先進的格式,好比一些jQuery的插件,它們都依賴jQuery,若是直接引用就會報錯 jQuery is not undefined這類的錯誤,有幾種方法解決web

先建立一個jQuery plugin: plugin.js

(function ($) {
    const shade = "#556b2f";
    $.fn.greenify = function() {
        this.css( "color", shade );
        return this;
    };
}(jQuery));

第一種方法 使用webpack.ProvidePlugin

webpack提供一個插件 把一個全局變量插入到全部的代碼中,在config.js裏面配置

  ...
  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中引用

...
//這個也不須要了 由於$, 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();
});
...

發現咱們插入的p裏面的顏色已經變成了綠色!

第二種方法 使用imports-loader

先安裝這個loader

npm install imports-loader --save-dev

而後在入口js中

//注意這種寫法 咱們把jQuery這個變量直接插入到plugin.js裏面了
//至關於在這個文件的開始添加了 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();
});

部署上線

剛纔說的各類狀況都是在開發時候的狀況,那麼假如項目已經開發完了,須要部署上線了。咱們應該新建立一個單獨的config文件,由於部署上線使用webpack的時候咱們不須要一些dev-tools,dev-server和jshint校驗等。

複製咱們現有的config文件,命名爲 webpack.production.config.js,將裏面關於 devServer等和開發有關的東西刪掉。

在package.json中添加一個命令。

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

  當要上線的時候,運行

npm run build

  能夠發現build文件夾中生成了全部東西。

分離app.js和第三方庫

如今咱們build出來的只有一個bundle.js 若是第三方庫不少的話,會形成這個文件很是大,減慢加載速度,如今咱們要把第三方庫和咱們app自己的代碼分紅兩個文件。

修改entry入口文件

  entry: {
    app: path.resolve(APP_PATH, 'index.js'),
    //添加要打包在vendors裏面的庫
    vendors: ['jquery', 'moment']
  },

  添加CommonsChunkPlugin

  plugins: [
    //這個使用uglifyJs壓縮你的js代碼
    new webpack.optimize.UglifyJsPlugin({minimize: true}),
    //把入口文件裏面的數組打包成verdors.js
    new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js'),
    new HtmlwebpackPlugin({
      title: 'Hello World app'
    })
  ] 

添加完畢 運行npm run build

在build文件夾中發現以下結構

budle.js
index.html
vendors.js

應用不可能都是SPA,不可能只生成一個html文件,若是想生成多個html頁面這麼玩?其實也是很簡單的: 如今的需求是這樣的,有兩個頁面,一個叫index.html 它須要引用vendors.js和app.js這兩個文件,還有一個mobile.html頁面他要引用vendors.js和mobile.js這兩個文件。

首先新建一個叫mobile.js的入口文件,比app.js更簡單一些


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: {
    //三個入口文件,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 用一個數組[name]來代替,他會根據entry的入口文件名稱生成多個js文件,這裏就是(app.js,mobile.js和vendors.js)
    filename: '[name].js'
  },

  原來咱們是沒有模版文件的,原來利用的HtmlWebpackPlugin的默認模版。誰想到這偉大的插件還能夠自定義模版。 因此新建一個專門放模版的文件夾templates,在裏面加兩個模版文件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>

  繼續配置config.js,如今讓HtmlwebpackPlugin能夠生成多個文件

...
//Template的文件夾路徑
var TEM_PATH = path.resolve(ROOT_PATH, 'templates');
...
plugins: [
  ...
  //建立了兩個HtmlWebpackPlugin的實例,生成兩個頁面
  new HtmlwebpackPlugin({
    title: 'Hello World app',
    template: path.resolve(TEM_PATH, 'index.html'),
    filename: 'index.html',
    //chunks這個參數告訴插件要引用entry裏面的哪幾個入口
    chunks: ['app', 'vendors'],
    //要把script插入到標籤裏
    inject: 'body'
  }),
  new HtmlwebpackPlugin({
    title: 'Hello Mobile app',
    template: path.resolve(TEM_PATH, 'mobile.html'),
    filename: 'mobile.html',
    chunks: ['mobile', 'vendors'],
    inject: 'body'
  })
  ...
]

  而後運行

npm run build

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

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

看看引用的對應關係,完美!!

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來防止緩存

經典問題,代碼更新了,可是瀏覽器有緩存,到時候就傻了。 怎麼解決,換名字唄。能夠直接在後面加參數,也能夠直接換掉文件名字。 webpack提供給了咱們很是簡單的方法,基於文件的md5,只要把

output: {
  path: BUILD_PATH,
  //只要再加上hash這個參數就能夠了
  filename: '[name].[hash].js'
},

運行完build之後,看看生成的文件,很完美~

index.html

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

  好了,你如今瞭解webpack做爲一個module bundler的精髓了吧,把咱們的例子作成一個圖,幫助你理解一下。

結語

第二部分到這裏結束,這一節討論不少webpack的使用技巧,看起來比較瑣碎,可是在你工做中也許會很實用,下一部分會出現你們都期待的高大上的東西,Webpack和React和Backbone等的結合。

很硬的連接

repo的代碼已經更新,想看全部源碼的能夠clone下 vikingmute/webpack-basic-starter · GitHub

同時這一系列關於Webpack的文章也能夠在github找到 vikingmute/webpack-for-fools · GitHub

相關文章
相關標籤/搜索