口耳相傳的建置方式

  1. 不應該!!
  2. Open source 世界,也有的默契
  3. 來看看雷神之鎚
  4. 用問的建置方式就是糙!!!
  5. 先來看看 npm
  6. 要怎麼正確的留下建置方式
    1. 寫文件
    2. 依循慣例

良好程式碼的優點大同小異。
不好的程式碼的糙點卻各有巧妙之處。

在開始之前,先聽一首歌 辛曉琪 Winnie Hsin【女人何苦為難女人 Women shouldn’t be hard on women】Official Music Video

不應該!!

  1. 不應該覺得,同學拿到程式碼,就會自然的使用它 (重點是,怎麼會跟同學要程式碼?)
  2. 不應該覺得,同事交接程式碼,用本能就可以跑起來。(除非有寫文件!!但是,既然連解釋都懶得做,那麼寫文件怎麼辛苦的事,自然不會想到了)
  3. 不應該等著別人來問「怎麼把程式 build 起來呀?」,這怎麼跑起來
  4. 當別人問「程式怎麼 build 呀」不應該因為對方問這問題而生氣!! (對方生氣才是正常的吧?)

Open source 世界,也有的默契

在 OpenSource 世界的起初。
是否想過,在不盛行 IDE 的世界。只靠著 GNU 的工具,怎麼知道這個 project 的 build 怎麼下?

gcc main.c -o main

如果專案很大,相依性很複雜,又如何知道該如何 build?
仔細觀察這些 C/C++ 的大型專案,都有 makefile 。

沒有人有義務,應該知道或一眼就看得出專案用什麼指令編譯或執行誰可以跑起來。
如果用英文說,就是「No, One!!..」後面自行翻譯

makefile

build:
	gcc main.c -o main

將指令放進來,在可執行文件中,暗示了開發者「用 gcc main.c -o main 可以 build 專案」,所以,可以用這樣的指令 build

make build

來看看雷神之鎚

來源: https://github.com/id-Software/Quake/blob/master/QW/Makefile.Linux

第 66 行可以看到 SETUP AND BUILD 段落,裡面有 build_debugbuild_release
可以找到一些蛛絲馬跡。

#############################################################################
# SETUP AND BUILD
#############################################################################

ifeq ($(ARCH),axp)
TARGETS=$(BUILDDIR)/qwsv 
#$(BUILDDIR)/qwcl.x11
else
TARGETS=$(BUILDDIR)/qwsv $(BUILDDIR)/qwcl $(BUILDDIR)/qwcl.x11 $(BUILDDIR)/glqwcl $(BUILDDIR)/glqwcl.glx
endif

build_debug:
	@-mkdir $(BUILD_DEBUG_DIR) \
		$(BUILD_DEBUG_DIR)/client \
		$(BUILD_DEBUG_DIR)/glclient \
		$(BUILD_DEBUG_DIR)/server 
	$(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)"

build_release:
	@-mkdir $(BUILD_RELEASE_DIR) \
		$(BUILD_RELEASE_DIR)/client \
		$(BUILD_RELEASE_DIR)/glclient \
		$(BUILD_RELEASE_DIR)/server
	$(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)"

all: build_debug build_release

targets: $(TARGETS)

用問的建置方式就是糙!!!

如果對這件事沒有警覺心,那來舉個例子。

AngularJS 通常是用 gulp + closure 做 JS 相依性問題的處理。

img/
js/
pages/
partial/
stylesheets/
.bowerrc
.gitignore
README.md
all.js
app.js
bower.json
gulpfile.js
index.html
package-lock.json
package.json

先來看看 npm

為什麼呢?前端有了打包工具之後,就要靠 node 執行,並且用 npm 管理套件相依
所以,有 npm 先看 npm

package.json

{
  "name": "erp_front",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-livereload": "^3.8.1"
  },
  "dependencies": {
    "gulp-concat": "^2.6.0"
  }
}

看見 script 了嗎?什麼都沒有,如同 npm init -y 的結果。
只有 test ,指令還是預設的樣子。

大驚!!!
沒有 AngularJS 的套件,沒有其它的套件!!!

驚嚇之餘
發現有安裝 gulp,來看看 gulpfile.js

gulpfile.js

var gulp = require('gulp');
var concat = require('gulp-concat');
var gulpLivereload = require('gulp-livereload');

gulp.task('all', function() {
  return gulp.src(['./js/**/*.js','./app.js'])
        .pipe(concat('all.js'))
        .pipe(gulp.dest('./'))
        .pipe(gulpLivereload())
});

gulp.task('watch', function() {
  gulpLivereload.listen();
  gulp.watch("./js/**/*.js", ["all"]);
  gulp.watch("./app.js", ["all"]);
})

不懂 gulp 的,就不知道怎麼用了,對吧?
(現在 gulp 用起來還比 webpack 難搞呀!!)

然後…
就沒有然後了。
有啦!可以以看一下 gulp 在寫什麼。

不過,這就像是「去看程式碼」一樣。糙!!!

千萬別以為,已經很清楚的暗示了對方了。
不然,找尋專案的編譯方式,就像是命案推理一樣,剝繭抽絲還不一定可以。

要怎麼正確的留下建置方式

開發者要先辨認,這是什麼樣子的專案?

如果是前端開發者

  • 原生語法切版
    • 開 index.html
  • 有用 SASS
    • sass watch
  • 有用 Compass (有 config.rb + .sass-cache)
    • compass watch
  • npm 專案 (大型專案)
    • 找 package.json 的 script

以 npm 為例

  • npm start 專案執行
  • npm run build 建置、編譯
  • npm run dev 開發模式執行

這些都是很常見的默契,不管你的 npm run dev 是要跑 gulp、docker、webpack…都行一套優良的專案管理工具,是可以靈活的抽象化專案使用方式。

寫文件

請不要以為,留下文件 = npm 專案使用教學。
因為不寫文件,也不照好的慣例做,只有通靈可以知道用什麼方式將專案跑起來

原因很簡單,請參考正在使用的框架或套件的文件。
會懂得怎麼用它,不是自己很強,而是套件或框架的文件很好

依循慣例

可以看看 Angular 在 npm 的文件怎麼寫的。Install,還分兩種。

也許會說 我的專案很簡單呀!不用這麼複雜的文件也很清楚。
請把第一個「不是自己,而且對專案第一次接觸的開發者」當作測試,在進行過這樣的測試之前,請不要有這種「哪來的信心」。受測試的開發者所問的問題,都是命案推理過程的謎團。

總之,女人何苦為難女人。那「開發者何苦為難開發者」呢?
好好的把 DX 提高吧