WMOS之webpack篇(一)

關於WMOS

好吧,做爲第一個系列第一篇的內容估計沒多少人會看,因此大概會寫的比較爛,還請看的人見諒。至於關於WMOS是什麼,在這篇文章裏不是十分重要,就先賣個關子,之後(大概吧)會慢慢跟你們說。這裏就先當作一個要作的項目就行了。回到正題。javascript

Webpack

如今的前端開發不一樣之前,不是寫寫html,css,js就OK的。隨着項目的複雜就會考慮一些工程化的東西,由於若是有不少東西都須要咱們本身去作會費不少時間。webpack就是一個相似gulp或者grunt的工具,不過它的核心可不僅是自動化這麼簡單。css

版本

目前webpack最新的版本是v3.4.1,而我也是在此基礎上進行學習和開發的。html

不直接聊原理

因爲我以前也用過webpack而且也深刻去學習了原理的東西,不過那個時候的我太年輕因此只是理解然而讓我說出個一二三四,大概我會想個好幾天(其實就是當時學的不紮實,嗚嗚)。因此此次作WMOS的目的其實就是在實現的過程當中來深入理解一些以前學過或者學習沒接觸的東西。這也就是探索式學習。前端

看文檔

我在使用webpack以前,首先看了一下當前的版本,這是必定要注意的事。由於有些api在不一樣的版本可能有所差別,在以後的使用的時候頗有可能成爲坑點。java

而在看完文檔的概念和指南以後,雖然對如何使用有了大體的瞭解,但是實際使用的話總感受本身沒看同樣,emmmmmm。webpack

不過看過文檔起碼在看別人的webpack配置文件的時候就能夠稍微讀懂了。es6

你想作什麼

看過不少遍文檔(中文)後,發現本身依然沒有頭緒(撓頭)。忽然就想到我到底用webpack作什麼?用webpack作什麼?作什麼?這是很重要的一件事,說三遍。web

因而我從新開始,想一想我目前到底想要什麼功能?npm

  1. WMOS打算使用原生的js寫,而且使用ES2015。gulp

  2. 使用less預編譯器。

  3. 可以對圖片進行一些處理。

  4. 可以熱更新

  5. 。。。。

貌似目前就只有這些需求,雖然我知道這必定不是所有。可是我認爲項目是一點一點搭起來的。目前我尚未達到那種程度,因此一步一步來。

乾貨來了

說了這麼久,是爲何?由於我今天在搭建webpack環境的時候,卡在HtmlWebpackPlugin,好痛苦~~(>_<)~~。

什麼是HtmlWebpackPlugin

官網在它的指南里是這麼引出的:

在更改了入口文件的時候,會生成新的文件,而咱們的index.html文件仍是引用舊的問卷。這個時候就要用HtmlWebpackPlugin

HtmlWebpackPlugin簡化了HTML文件的建立,以便爲您的webpack包提供服務。這對於在文件名中包含每次會隨着變異會發生變化的哈希的webpack bundle尤爲有用。 您可讓插件爲您生成一個HTML文件,使用lodash模板提供您本身的模板,或使用您本身的loader。·

以上都是官網給出的內容。其實目前我使用以後的感受就是:能夠爲咱們生產html文件,而且直接把那些生產的bundle文件直接寫入html中。這個在想要實現熱更新的時候是頗有用的。最後在經過下面的例子在理解一下HtmlWebpackPlugin

最初的時候目錄是這樣的:

clipboard.png

你會發如今dist文件夾下什麼都沒有,dist文件夾是咱們生產文件的地方,src文件夾是咱們的源文件夾。而後看一下咱們的webpack配置文件:

clipboard.png

使用過webpack的同窗知道,在運行webpack以後應該生產在dist文件夾裏生成main.js,而這個js文件須要咱們手動放入html文件中。不過這裏經過HtmlWebpackPlugin咱們就不用手動操做了。讓咱們執行一下:

clipboard.png

clipboard.png

原來的index.html:

clipboard.png

如今的index.html:

下面來詳細講一下HtmlWebpackPlugin插件。

安裝

npm install --save-dev html-webpack-plugin

基本用法

該插件會爲您生成一個HTLM5文件,其中會包括使用script標籤引用的js輸出文件。最進本的用法就是將插件直接添加到webpack配置中,以下:

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

var webpackConfig = {
  entry: 'index.js',
  output: {
    path: 'dist',
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin()]
};

這將會產生一個包含如下內容的文件 dist/index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>webpack App</title>
  </head>
  <body>
    <script src="index_bundle.js"></script>
  </body>
</html>

若是有多個webpack入口,就會生成多個script標籤引用這些文件。

若是你有任何CSS assets 在webpack的輸出中(例如,利用ExtractTextPlugin提取CSS),那麼這些將被包含在HTML head中的<link>標籤內。

配置

下面是HtmlWebpackPlugin插件的一些配置選項:

    • title: 生成的html文檔的title標籤之間的內容。

    • filename: 生成html文件的名字,默認爲index.html。你可使用子目錄的形式,像asset/admin.html是OK的。

    • template: webpack會require這個路徑的文件做爲模板。(我就卡這裏了,稍後會詳細講一下)

    • inject: 它有四個值,分別爲truehead、'body'、'false',功能是在將全部的資源輸出到template或者templateContent指定的文件裏的時候,當inject的值爲true或者body的時候,全部JavaScript資源將放置在body元素的下面;當值爲head的時候,將放置在head元素內。

    • favicon: 將給定的favicon路徑下的文件輸出到html文件裏。

    • minify: 經過使用一個以html-minifier的配置選項做爲內容的對象的時候會壓縮輸出html文件。使用false你懂得。

    • hash: 值爲true | false。若是爲true的時候添加一個惟一的webpack編寫的hash值到全部的script文件和css文件。對於緩存清除頗有用。

    • cache: true | false。若是爲true(默認)則只有當文件內容改變的時候,會生成一個新的文件。

    • showErrors: true' | false。若是爲true`(默認),則錯誤信息寫入html頁面。

    • chunks: Allows you to add only some chunks (e.g. only the unit-test chunk)

    • chunksSortMode: Allows to control how chunks should be sorted before they are included to the html. Allowed values: 'none' | 'auto' | 'dependency' |'manual' | {function} - default: 'auto'

    • excludeChunks: Allows you to skip some chunks (e.g. don't add the unit-test chunk)

    • xhtml: true | false If true render the link tags as self-closing, XHTML compliant. Default is false

    生成多個HTML文件

    若是要生成多個html問卷,只要多聲明幾回就OK了。

    {
      entry: 'index.js',
      output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
      },
      plugins: [
        new HtmlWebpackPlugin(), // Generates default index.html
        new HtmlWebpackPlugin({  // Also generate a test.html
          filename: 'test.html',
          template: 'src/assets/test.html'
        })
      ]
    }

    編寫本身的模板

    若是它默認生成的模板不能知足咱們,咱們能夠本身去編寫本身的模板。咱們能夠經過template屬性傳遞咱們本身的html文件。html-webpack-plugin將會自動將全部必要的css,js,manifest和favicon文件注入裏面。

    模板默認使用ejs模板。以下方式:

    plugins: [
      new HtmlWebpackPlugin({
        title: 'Custom template',
        template: 'my-index.ejs', // Load a custom template (ejs by default see the FAQ for details)
      })
    ]
    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title><%= htmlWebpackPlugin.options.title %></title>
      </head>
      <body>
      </body>
    </html>

    若是你打算使用其餘的模板,就須要使用對應的loader進行解析。以下使用了hbs模板:

    module: {
      loaders: [
        { test: /\.hbs$/, loader: "handlebars" }
      ]
    },
    plugins: [
      new HtmlWebpackPlugin({
        title: 'Custom template using Handlebars',
        template: 'my-index.hbs'
      })
    ]

    注意一點就是若是你使用了.html文件做爲模板,那麼就會使用html-loader去解析,因此不要忘記使用html-loader。(我就卡到這裏,不過緣由並非這樣。)

    注入的對象

    在模板中可使用一下變量:

    • htmlWebpackPlugin: 這個插件的對象(我理解)

      • htmlWebpackPlugin.files: webpack的stats對象的assetsByChunkName
        表示。它包含輸入的文件名到bundle文件名,例如:

      "htmlWebpackPlugin": {
        "files": {
          "css": [ "main.css" ],
          "js": [ "assets/head_bundle.js", "assets/main_bundle.js"],
          "chunks": {
            "head": {
              "entry": "assets/head_bundle.js",
              "css": [ "main.css" ]
            },
            "main": {
              "entry": "assets/main_bundle.js",
              "css": []
            },
          }
        }
      }
      • htmlWebpackPlugin.options: 轉遞給插件的options選項,除了插件使用的
        選項之外,你能夠經過這個hash列表傳遞任何數據給模板。也就是說你在設置插件選項

      的時候,能夠添加一些本身的數據。而後能夠在模板中經過插件的options來使用。

    • webpack: webpack的stats對象

    • webpackConfigwebpack的配置對象。

    我遇到的坑點

    我使用了html文件做爲模板,它須要使用html-loader進行解析,html-loader支持es6模板的寫法,也就是${}這樣。在寫loader的時候,我是這樣寫的:

    module: {
        rules: [
          {
            test: /\.html$/,
            loader:'html-loader'
          }
        ]
    },

    咱們模板是醬紫:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>${ htmlWebpackPlugin.options.title }</title>
    </head>
    <body>
        <h1>WMOS</h1>    
    </body>
    </html>

    可是這樣寫以後,它並無把title解析掉:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>${ htmlWebpackPlugin.options.title }</title>
    <link rel="shortcut icon" href="/dist/favicon.ico"></head>
    <body>
        <h1>WMOS</h1>
        
    <script type="text/javascript" src="/dist/main.js?6c414fd062ee36677caf"></script></body>
    </html>

    而將test那部分改成`test: '/.html$/'的時候,就完美的解析了。

    What?我也很懵逼。test的做用是來匹配相應的文件。而test的值能夠是字符串,正則,函數等等。看過文檔以後,我也並無發現使用它們會有什麼不一樣的結果。

    over day

    今天就先寫到這裏,目前咱們遇到了一個奇葩不過不是重點的問題,因此咱們先將它記下來,在以後會去一一解決這些問題。

    相關文章
    相關標籤/搜索