什么是自動(dòng)化的前端構(gòu)建流?

   1. 自動(dòng)補(bǔ)全css私有前綴,自動(dòng)轉(zhuǎn)化less\sass為css,自動(dòng)轉(zhuǎn)化es6\vue\jsx語法為js,自動(dòng)打包小圖片為base64以減少http請(qǐng)求,自動(dòng)給js,css,甚至img加hash值,以避免瀏覽器緩存,自動(dòng)合并壓縮代碼,自動(dòng)刷新實(shí)時(shí)預(yù)覽效果(甚至免刷新),可以按照自己喜歡的目錄結(jié)構(gòu)存放原始資源文件,為了方便手機(jī)等訪問,不需要搭建apache、nginx等服務(wù)器實(shí)現(xiàn)http訪問......

如何快速開始

 首先 git clone https://github.com/bjtqti/font-end-boilerplate.git  一份到本地

 然后 npm install && npm run start

 最后打開瀏覽器,運(yùn)行http://localhost:4000

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計(jì)算培訓(xùn),高端軟件開發(fā)培訓(xùn),項(xiàng)目經(jīng)理培訓(xùn)

接下來看看目錄結(jié)構(gòu):

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計(jì)算培訓(xùn),高端軟件開發(fā)培訓(xùn),項(xiàng)目經(jīng)理培訓(xùn)

解析一下這些目錄的用途:

|-  dist下面存放發(fā)布的js、css 文件 (自動(dòng)生成)

|- node_modules 下面是npm安裝的包文件 (自動(dòng)創(chuàng)建)

|- src 存放具體的業(yè)務(wù)代碼

|- task 存放webpack的配置代碼

|- task

     |- webpack.api.conf.js 用于webpack的api方式的配置文件 server.js用到

     |- webpack.dev.conf.js 用于CLI方式使用webpack 的配置

     |- webpack.prod.conf.js 用于生產(chǎn)環(huán)境打包輸出的配置

|- .postcssrc.js  post-loader的插件配置文件,由于后面用了postcss.config.js所以重命名了這個(gè)

|- .babelrc babel的配置文件,為了解析es6語法

|- .gitignore git的配置,指出要不參與版本控制的文件及文件夾

|- .package.json 包配置文件

|- postcss.config.js  post-loader配置

|- README.md github.com自動(dòng)創(chuàng)建的項(xiàng)目說明文件

|- server.js  本地開發(fā)調(diào)式用的web服務(wù)器

需要重點(diǎn)掌握的是package.json 其次是server.js 和 task相關(guān)的配置內(nèi)容

先看看package.json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
  "name""shop",
  "version""1.0.0",
  "description""webapp frontend shop",
  "main""index.js",
  "scripts": {
    "start""node server.js",
    "dev""webpack-dev-server --config ./task/webpack.dev.conf.js",
    "build""webpack --config ./task/webpack.prod.conf.js",
    "test""echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "mall",
    "shop"
  ],
  "author""frog",
  "repository""https://github.com/bjtqti/font-end-boilerplate.git",
  "license""MIT",
  "devDependencies": {
    "babel-core""^6.25.0",
    "babel-loader""^7.1.1",
    "babel-plugin-transform-runtime""^6.23.0",
    "babel-preset-env""^1.5.2",
    "css-loader""^0.28.4",
    "express""^4.15.3",
    "extract-text-webpack-plugin""^2.1.2",
    "html-webpack-plugin""^2.29.0",
    "postcss-loader""^2.0.6",
    "style-loader""^0.18.2",
    "webpack""^2.6.1",
    "webpack-dev-middleware""^1.11.0",
    "webpack-dev-server""^2.5.0",
    "webpack-hot-middleware""^2.18.0"
  },
  "dependencies": {
    "babel-plugin-transform-runtime""^6.15.0"
  }
}

  

這個(gè)文件其實(shí)就是一個(gè)json對(duì)象,里邊重點(diǎn)掌 scripts 的用法。比如start:node server.js  對(duì)應(yīng) npm run start (或 npm start)  這條命令就相當(dāng)于是在node環(huán)境下運(yùn)行了server.js

那么server.js(文件名可以自已定)里邊保存了一些什么內(nèi)容?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var express = require("express");
var webpack = require("webpack");
var path = require('path')
var app = express();
var webpackConfig = require("./task/webpack.api.conf.js");
var compiler = webpack(webpackConfig);
  
var devMiddleware = require('webpack-dev-middleware')(compiler, {
      contentBase: webpackConfig.output.path,
    publicPath: webpackConfig.output.publicPath,
    //hot: true,
    //stats: { colors: true },
    quiet: true
})
 
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
    //lazy: true,
    //path:'/hmr',
    log: () => {}
})
 
app.use(express.static('./dist'));
app.use(hotMiddleware)
app.use(devMiddleware)
 
app.listen(4000, function () {
  console.log("Listening on port 4000!");
});

  

其實(shí)就是使用了express來搭建一個(gè)小型的開發(fā)服務(wù)器。然后引用webpack-dev-middleware和webpack-hot-middleware兩個(gè)中間件,結(jié)合webpack.api.conf.js的配置,實(shí)現(xiàn)打包和熱加載src下面的代碼。由于這里涉及到express的知識(shí),不打算涉及全棧的前端只需了解一下即可,因?yàn)楹竺孢€有一個(gè)封裝好的工具可以替代這些工作--webpack-dev-server

所以我在script中添加了一個(gè)dev:webpack-dev-server 的命令,這全完是為了方便學(xué)習(xí)這兩種方式的應(yīng)用,實(shí)際上任選其中一種就好了,這一種可能會(huì)感覺更簡(jiǎn)單,因?yàn)樗堑谝环N方式的封裝,但是要深入的了解,還是建議看看第一種方式,Vue-cli也是采用的第一方式,因?yàn)樗晒╅_發(fā)者自由支配的空間更大。唯一需要注意的是,如果使用webpack-dev-server的話,目前還不能用webpack3.0+。

接下來運(yùn)行npm run build  看看,dist目錄下是不是多了一些文件?這就是將來可以直接發(fā)布到線上的代碼了。

到這里,打包,發(fā)布 都介紹完了,下面簡(jiǎn)單演示一下熱替換(也就是所謂的無刷新替換效果)。為了演示方便,我在src下放了一些代碼. 

當(dāng)我們打開http://localhost:4000的時(shí)候,瀏覽器上有一段綠色的文字:Hello world 還有一個(gè)時(shí)間毫秒數(shù),加這個(gè)毫數(shù)的目的是為了演示,如果頁面刷新了,數(shù)字會(huì)改變。

然后修改style.css中的內(nèi)容,比如把字體顏色改成紅色,瀏覽器上的字體顏色也相應(yīng)的變化了,而數(shù)字沒有發(fā)生改變。如果手動(dòng)刷新的話,可以看到數(shù)字是會(huì)變化的。

這不僅會(huì)節(jié)省時(shí)間,而且對(duì)于要保存頁面狀態(tài)(比如某按鈕選中)的情況非常有用。當(dāng)我們修改hello.es6的時(shí)候,頁面變成了自動(dòng)刷新,這是因?yàn)槲覜]有使用js的熱替換加載器。

如果對(duì)html的修改,也想要自動(dòng)刷新的話,需要用到插件,發(fā)出相應(yīng)的事件。比如vue-cli中的方式:

1
2
3
4
5
6
7
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation'function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit'function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})

這里只是發(fā)出一個(gè)通知:action:'reload',要使頁面自動(dòng)重新加載,還需要有一個(gè)接收通知的代碼:

比如在入口中加入:

/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')

hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})

這個(gè)地方比較深?yuàn)W,沒有弄明白也沒關(guān)系,有其它方式同樣可以實(shí)現(xiàn)。比如webpack-dev-server 內(nèi)部已經(jīng)自動(dòng)完成了對(duì)不支持熱替換的加載器,自動(dòng)降為刷新。

這也是為什么在開發(fā)環(huán)境下使用了extract-text-webpack-plugin(提取css的插件)后,樣式的熱替換變成了刷新效果的原因。

 

小結(jié):

   通過對(duì)webpack的運(yùn)用,搭建一個(gè)前端自動(dòng)化構(gòu)建工作流程,做到學(xué)以致用。對(duì)一些常用的webpack配置和插件有了實(shí)踐經(jīng)驗(yàn)之后,即便去用vue-cli這樣現(xiàn)成的工具,也可以放心的按照自己的實(shí)際情況去修改了。自動(dòng)化構(gòu)建的過程,其實(shí)就是對(duì)webpack插件和加載器的學(xué)習(xí)和運(yùn)用的過程,紙上得來終覺淺 絕知此事要躬行,動(dòng)手試試吧

http://www.cnblogs.com/afrog/p/7145111.html