前端靜態開發環境設計

前端開發環境設計

GitHub

目的

讓前端可以在開發期間獨立後端進行組件的開發及維護,使用react、scss、jade

功能簡介

環境準備

安裝node v7.7.3以上

1
到 [官網](https://nodejs.org/en/)下載安裝包,並安裝

使用npm全域安裝gulp

1
npm install -g gulp

使用npm全域安裝 storybook

npm install -g getstorybook

安裝react單元測試工具

1
npm install -g jest-cli

安裝所有專案需要的nodel module包:請先移動到專案目錄底下,並且在終端機輸入以下指令

1
npm isntall

安裝chrome extenstion livereload外掛

1
到chrome extension中心 ( [連結](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei?hl=zh-TW) )下載擴充

測試環境是否成功安裝

請在終端機輸入以下命令

1
gulp develop

如果環境正確運作的話,你可以在http://localhost:3002 看到你的首頁

開發環境介紹

scss

  • 原始檔在./src/scss目錄底下
  • 編譯過的css檔案在./public/css/底下

javascript(jsx)

新增一個React組件:創健一個DemoComponent.jsx,並放置在src/components/demo/目錄底下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, {Component} from 'react'
//引用node module裡的react,並使用變數"React"代表
class DemoComponent extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div>
<p>this is demo</p>
</div>
);
}
}
export default DemoComponent;
  • 組件(component)檔名一律大寫駝峰
  • 使用es6的module system

引用一個React組件,並在網頁上安裝這個組件:新增一個demo.jsx檔,放置在./src目錄底下

1
2
3
4
5
6
7
8
import DemoComponent from './components/demo/TestComponent';
import ReactDOM from 'react-dom';
import React from 'react';
ReactDOM.render(
    <DemoComponent/>,
    document.getElementById('demo')
)
  • 一個頁面通常只會有一隻初始化用的jsx檔,其他都是被引用的module。
  • 同時它也會是javascript bundle的入口,預設都在/src,第一層目錄底下。
  • bundle工具會無視第二層目錄底下的其他js或是jsx檔。
  • bundle完的檔案,會在public/js目錄底下,繼承檔名並且加上後綴:*.bundle.js

有關於es5與es6之間,react的語法差異可以參考這篇文章

使用node(express)新增一個網站頁面

首先,新增一個index.jade檔, 並放置在views/demo目錄底下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//宣告layout
extends ../_layout
//在此設定必需要在,頁面載入前引用的javascript(不含共用)
block headScripts
    //script(src="js/test.bundle.js")
block styles
    //在此設定必需要在此頁引用的樣式(不含共用)
    //link(rel="stylesheet", href="/css/test.css")
block content
    h1 This is Demo
    div#demo
block scripts
    //在此設定必需要在,頁面載入後引用的javascript(不含共用)
    //script(src="js/demo.bundle.js")
  • 引入的其他資源(腳本/樣式/圖檔)路徑階相對於public目錄底下
  • 可以利用資料夾組織及管理你的頁面
  • 可以在該視圖上載入所需腳本及樣式檔:
  • block headScripts:必需要在頁面載入前引用的javascript(不含共用)
  • block styles:必需要在此頁引用的樣式(不含共用)
  • block content:jade (html)文本
  • block scripts:頁面載入後(body結尾前)引用的javascript(不含共用)

在專案根目錄底打開server.js,在檔案中增加下列程式碼片段

1
2
3
4
app.get('/demo', function(req, res) {
    //利用res物件指定回傳視圖的路徑(相對於專案根目錄)
    res.render('demo/index.jade');
});

在沒有指定檔名的狀況,預設會讀取指定目錄底下的index.jade檔,因此我們可以省略如下:

1
2
3
4
//與上一段程式碼,會獲得一樣的結果。
app.get('/demo', function(req, res) {
    res.render('demo');
});
  • req:請求物件
  • res:回饋物件,可以在這裡指定回傳的視圖,以及資料

最後你應該能在 http://localhost:3002/demo 看見你的網頁

這裡在node express稱之為新增一個router,雷同於.net MVC在controller底下新增一個action

使用Mock.js生成隨機數據,攔載ajax

原理/思路:在開發過程中為了保持功能模組的純淨,將假資料的邏輯跟相關程式碼,集中放置在McokComponent.jsx,開發者可以依開發需求客制化這個組件,並且利用HOC的方式裝飾你的組件。

再說明實例之前,讓我們先了解一些需要知道的基本知識:

使用方式如下

1
2
3
4
5
6
7
8
9
10
11
12
import RootComponent from './components/index/RootComponent';
import MockProvider from './components/index/MockProvider'
import ReactDOM from 'react-dom';
import React from 'react';
//將模組與假資料連結在一起
var Index = MockProvider(RootComponent);
ReactDOM.render(
<Index/>,
document.getElementById('index')
)

明白使用邏輯後,讓我們看看MockProvider的程式碼長什麼樣子

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
import React from 'react'
import Mock from 'mockjs'
function AttachedToMock(WrappedComponent, configs) {
class MockComponent extends React.Component {
constructor(props) {
super(props);
//宣告假資料的長相
this.mockTemplate = {
'list|1-10': [
{
'id|+1': 1,
'email': '@EMAIL'
}
]
};
//利用mock產生初始化資料
this.state = {initData: Mock.mock(this.mockTemplate)};
}
componentWillMount = () => {
//欄截所有對*.json發送的ajax,並回傳設計好的資料結構
Mock.mock(/\.json/, this.mockTemplate);
Mock.setup({timeout: '200-600'});
}
render() {
return <WrappedComponent initData={this.state.initData} {...this.props}/>
}
}
return MockComponent;
}
export default AttachedToMock;
  • 正式發佈程式時,所有import from `/MockProvider相關的路徑,都會被替換為src/components/core/ReplaceMockProvider`,以防開發者在發佈程式的過程中,不小心打包到含有假資料的程式碼。
  • 你可以在http://localhost:3002,看見結果

啟用livereload功能

要使用livereload請安裝對應的瀏覽器外掛,需手動啟用(預設狀況為不開啟)。啟用方式以Chrome為例:點擊右上方Icon,當Icon中間的圓點為實心的灰色,代表功能正常啟用。

撰寫單元測試

src/components/demo目錄底下,新增一個DemoComponent.spec.jsx檔案,並加入以下程式碼。

1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react'
import { expect } from 'chai'; //引用斷言庫
import {mount, render, shallow} from 'enzyme'
import DemoComponent from "./DemoComponent"
describe('DemoComponent: ', () => {
    const wrapper = mount(<DemoComponent/>);
    it('應該要顯示文字,"this is demo"', () => {
        expect(wrapper.text()).to.contain('this is demo');
    })
});

打開終端機,進入專案目錄,輸入以下指令,運行測試結果

1
jest src/components/demo/DemoComponent.spec.jsx

測試結果如下

運行開發環境

使用vscode

打開偵錯頁籤 > 選擇開發模式 > 按下綠色箭頭運行

障礙排除:使用vscode時,有時無法正常停止運行,請參考這篇作法,移除被佔用的port

使用終端機指令

在vscode界面上按下快速鍵,cmd+shift+M,打開終端機輸入命令字元

1
gulp develop

發佈程式碼

由於本環境僅用作前端人員獨立的開發環境,發佈模式的目的在於:將javascript進行壓縮,其它與開發模式並無差異。

使用vscode

打開偵錯頁籤 > 選擇發佈模式 > 按下綠色箭頭運行

使用終端機機指令

在vscode界面上按下快速鍵 cmd+shift+M,打開終端機輸入命令字元

1
gulp deploy

如何將程式同步到正式環境,請參考這一篇文章(待補)

運行測試任務

在vscode界面上按下快速鍵 cmd+shift+M,打開終端機輸入命令字元

批次測試

1
npm test

指定單一測試任務

1
jest path/to/my-test.jsx

關於測試的寫作技巧,請參考這一篇文章(待補)

運行Storybook(組件展示)

1
npm run storybook

其他

專案結構及檔案說明

請參考專案底下的fileStructure.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
├── README.md
├── config //node config
├── fileStructure.txt //檔案結構說明
├── gulpfile.js
├── package.json //node專案檔
├── public //編譯完的程式碼,除了圖檔images外,開發者應該不會需要編輯
|  ├── css 
|  ├── images //圖檔
|  └── js //javascript bundle的結果,*.bundle.js
├── server.js //node express
├── src //原始程式碼(src底下的第一層jsx為程式打包的入口)
|  ├── components //react組件
|  ├── demo.jsx //bundle入口
|  ├── index.jsx //bundle入口
|  └── scss //樣式檔目錄
├── stories //模組展式
├── views //視圖
├── wdio.conf.js
└── yarn.lock

專案相關網址