好吧,做爲第一個系列第一篇的內容估計沒多少人會看,因此大概會寫的比較爛,還請看的人見諒。至於關於WMOS是什麼,在這篇文章裏不是十分重要,就先賣個關子,之後(大概吧)會慢慢跟你們說。這裏就先當作一個要作的項目就行了。回到正題。javascript
如今的前端開發不一樣之前,不是寫寫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
WMOS打算使用原生的js寫,而且使用ES2015。gulp
使用less預編譯器。
可以對圖片進行一些處理。
可以熱更新
。。。。
貌似目前就只有這些需求,雖然我知道這必定不是所有。可是我認爲項目是一點一點搭起來的。目前我尚未達到那種程度,因此一步一步來。
說了這麼久,是爲何?由於我今天在搭建webpack環境的時候,卡在HtmlWebpackPlugin
,好痛苦~~(>_<)~~。
HtmlWebpackPlugin
官網在它的指南里是這麼引出的:
在更改了入口文件的時候,會生成新的文件,而咱們的
index.html
文件仍是引用舊的問卷。這個時候就要用HtmlWebpackPlugin
。
HtmlWebpackPlugin
簡化了HTML文件的建立,以便爲您的webpack包提供服務。這對於在文件名中包含每次會隨着變異會發生變化的哈希的webpack bundle
尤爲有用。 您可讓插件爲您生成一個HTML文件,使用lodash模板提供您本身的模板,或使用您本身的loader。·
以上都是官網給出的內容。其實目前我使用以後的感受就是:能夠爲咱們生產html文件,而且直接把那些生產的bundle
文件直接寫入html中。這個在想要實現熱更新的時候是頗有用的。最後在經過下面的例子在理解一下HtmlWebpackPlugin
。
最初的時候目錄是這樣的:
你會發如今dist
文件夾下什麼都沒有,dist
文件夾是咱們生產文件的地方,src
文件夾是咱們的源文件夾。而後看一下咱們的webpack配置文件:
使用過webpack的同窗知道,在運行webpack以後應該生產在dist
文件夾裏生成main.js
,而這個js文件須要咱們手動放入html文件中。不過這裏經過HtmlWebpackPlugin
咱們就不用手動操做了。讓咱們執行一下:
原來的index.html
:
如今的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
: 它有四個值,分別爲true
、head
、'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問卷,只要多聲明幾回就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對象
webpackConfig
webpack的配置對象。
我使用了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的值能夠是字符串,正則,函數等等。看過文檔以後,我也並無發現使用它們會有什麼不一樣的結果。
今天就先寫到這裏,目前咱們遇到了一個奇葩不過不是重點的問題,因此咱們先將它記下來,在以後會去一一解決這些問題。