從零開始建立 angularjs-gulp-es5 專案

Silence發表於2019-02-16

原始碼地址:https://github.com/silence717/angular-gulp-seed

建立一個空資料夾名字任意,此專案為angular-gulp-seed

mkdir angular-gulp-seed

初始化工程

npm init

建立專案基本目錄結構如下:

+src
    +app            // 業務模組
        -app.js    // 應用入口
        +demo   // 業務模組目錄,所有子模組均遵循此目錄
            - module.js      // 模組宣告檔案
            - controller.js  // vm層
            - index.html     // 主入口模板
            - router.js      // 模組路由檔案
            - style.css      // 模組樣式
        +home
    +assets            // 靜態資源目錄
        -images
        -css
    +common            // 公共服務
    +components    // 公共元件
    +scripts         // gulp指令碼
        - gulp.build.js   // build任務
        - gulp.common.js  // dev,build公共任務
        - gulp.config.js  // 基礎配置
        - gulp.dev.js     // dev任務
    index.html  // 主頁面

package.json

正式開始coding

gulp配置部分

1. 安裝gulp
npm install  gulp -D
2. 新建gulpfile檔案,安裝browser-sync包,配置第一個任務
var browserSync = require(`browser-sync`);
gulp.task(`browserSync`, function () {
    browserSync({
        server: {
            baseDir: `./`,
            index: `src/index.html`
        }
    });
});
gulp.task(`default`, [`browserSync`]);
// 執行gulp命令,瀏覽器啟動,可以看到大致頁面結構

更多browser-sync的資訊:http://www.browsersync.cn/

3. 為了動態插入新加的js和css檔案,且新增的檔案有一定順序,安裝gulp系列包。  
npm install gulp-watch gulp-inject gulp-order -D
4. 新建一個gulp.config.js檔案,配置一些基本檔案路徑和順序
module.exports = function () {

    var src = `./src/`;
    var build = `./dist/`;

    var config = {
        src: src,
        build: build,
        index: src + `index.html`,
        css: [src + `**/*.css`],
        appJs: [src + `app/**/*.js`],
        commonJs: [src + `common/**/*.js`],
        componentJs: [src + `components/**/*.js`],
        jsOrder: [
            `**/app.js`,    // 專案主入口
            `**/app.*.js`,  // 主入口相應配置
            `**/module.js`, // 模組宣告
            `**/router.js`, // 模組路由
            `**/index.js`,  // 元件、resource入口
            `**/*.js`       // 其他
        ],
        cssOrder: [
            `**/app.css`,       // 專案主模組
            `**/*.module.css`,  // 業務子模組
            `**/*.css`          // 其他
        ]
    }
    return config;
}();
5. 使用gulp-inject動態插入css和js  
  • js任務編寫

var config = require(`./gulp.conf.js`);
gulp.task(`inject`, function() {

    var js = gulp.src(config.js, {read: false}).pipe(order(config.jsOrder));
    var css = gulp.src(config.css, {read: false}).pipe(order(config.cssOrder));

    return gulp
        .src(config.index)
        .pipe(inject(js, {addPrefix: `../src`, relative: true}))
        .pipe(inject(css, {addPrefix: `../src`, relative: true}))
        .pipe(gulp.dest(config.src))
        .pipe(browserSync.reload({stream: true}));
});
  • 頁面新增inject標識

<!-- css -- >
<!-- inject:css -->
<!-- endinject -->

<!-- js -- >
<!-- inject:js -->
<!-- endinject -->
  • 新增到default任務中

gulp.task(`default`, [`inject`, `browserSync`]);
  • 執行gulp命令,可看到如圖頁面效果,同時index.html頁面內容發生變化

<!-- inject:css -->
<link rel="stylesheet" href="../src/assets/css/app.css">
<!-- endinject -->

<!-- inject:js -->
<script src="../src/app/app.js"></script>
<!-- endinject -->
6. 開發過程中會不斷新增新的css和js檔案,為了優化開發體驗,引入gulp-watch包新增watch任務,當js和css檔案發生變化的時候,去執行inject任務
var watch = require(`gulp-watch`);
gulp.task(`watch`, function() {
    watch(`src/**/*.js`, function() {
        gulp.run(`inject`);
    });
    watch(`src/**/*.css`, function() {
        gulp.run(`inject`);
    });
});
gulp.task(`default`, [`inject`, `browserSync`, `watch`]);

編寫業務程式碼

1. 安裝angular相關包
npm install  angular angular-ui-router --save
2. 由於程式碼量過大,不貼出具體參見src/spp下面程式碼實現
  • src/index.html

  • src/app.js 專案主入口

  • src/app.router.js 專案路由配置

mock資料服務

為了前端保持獨立,使用express搭建一個mock服務,然後我們就能愉快的開始開發了。

1. 首先安裝依賴包:
npm install express body-parser json-server http-proxy-middleware -D
2. 建立server.js,內容如下:
var jsonServer = require(`json-server`);
var server = jsonServer.create();
var middlewares = jsonServer.defaults();
var bodyParser = require(`body-parser`);
var mockRouter = require(`./mock/index`);

// 新增預設的中介軟體 logger, static, cors and no-cache
server.use(middlewares);

// 解析 body
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({
    extended: false
}));

server.use(mockRouter);

server.listen(4000, function() {
    console.log(`God bless me no bug, http://localhost:4000`);
});
3. mock資料夾下建立index.js,內容如下:
var fs = require(`fs`);
var express = require (`express`);
var router = express.Router();

fs.readdirSync(`mock`).forEach(function(route) {
    if (route.indexOf(`index`) === -1) {
        require(`./` + route)(router);
    }
});

module.exports = router;
4. 引入angular-resource.js,使用$resource服務
npm install angular-resource --save

在common/resource/建立一個utils,具體檔案為resourceUtils,為所有請求新增統一字首

(function() {
    angular
        .module(`app.resource`)
        .factory(`resourceUtils`, resourceUtils)
        .factory(`webResource`, webResource);

    resourceUtils.$inject = [`$resource`];

    function resourceUtils($resource) {
        return function(apiPrefix) {
            return function(url, params, actions) {
                return $resource(apiPrefix + url, params, actions);
            };
        };
    }

    webResource.$inject = [`resourceUtils`];
    function webResource(resourceUtils) {
        // 其中***為後端服務的統一字首
        return resourceUtils(`/***/`); 
    }

})();

關於$resource服務的使用,請參考這篇文章。https://silence717.github.io/2016/09/28/creating-crud-app-minutes-angulars-resource/

5. 在gulpfile.js中統一配置代理,並且修改browserSync任務:
// 引入http-proxy-middleware
var proxyMiddleware = require(`http-proxy-middleware`);

// 配置代理路徑,是否為本地mock
var isLocal = true;
var target = ``;

if (isLocal) {
    target = `http://localhost:4000`;
} else {
    // API address
}
// browserSync任務新增代理
gulp.task(`browserSync`, function() {
    var middleware = proxyMiddleware([`/***/`], {target: target, changeOrigin: true});
    browserSync({
        server: {
            baseDir: `./`,
            index: `src/index.html`,
            middleware: middleware
        }
    });
});
6. 你可能需要新增一些公共的interceptor去處理後端返回的資料或者請求出錯的統一處理。具體參見[https://docs.angularjs.org/api/ng/service/$http](https://docs.angularjs.org/api/ng/service/$http).  

至此已經可以在本地愉快的開發了。

配置gulp編譯任務

開發完成以後程式碼需要build上線,繼續建立一些task。

1. 安裝相關依賴包
npm install gulp-angular-templatecache gulp-minify-css gulp-if gulp-useref gulp-uglify gulp-replace -D
2. 配置build任務,具體在scripts/gulp.build.js檔案中.

3. 頁面html遇到build的地方配置
 ...
 <!-- build:css css/app.css -->
 <!-- endbuild -->
 
 <!-- build:js js/common.js -->
 <!-- endbuild -->
 ...

我將gulp的任務全部獨立出去管理,這樣使得gulpfile.js更加清晰

var gulp = require(`gulp`);
var del = require(`del`);
var runSequence = require(`run-sequence`);
var config = require(`./scripts/gulp.conf.js`);
var buildTask = require(`./scripts/gulp.build.js`);
var devTask = require(`./scripts/gulp.dev.js`);
var commonTask = require(`./scripts/gulp.common.js`);

// 動態新增css和js到index.html
gulp.task(`inject`, function() {
    commonTask.inject();
});
// 新增監聽任務
gulp.task(`watch`, function() {
    devTask.watch();
});
// 使用browerSync啟動瀏覽器
gulp.task(`browserSync`, function() {
    devTask.browserSync();
});
// 清除dist檔案
gulp.task(`clean`, function() {
    del(config.build);
});
// 打包元件模板
gulp.task(`build:components-templates`, function() {
    buildTask.componentsTemplate();
});
// 打包業務模板
gulp.task(`build:app-templates`, function () {
    buildTask.appTemplate();
});
// build index檔案
gulp.task(`build`, [`build:components-templates`, `build:app-templates`], function() {
    buildTask.buildIndex();
});
// 本地開發
gulp.task(`default`, [`inject`, `browserSync`, `watch`]);
// 線上環境打包
gulp.task(`dist`, [`clean`], function() {
    runSequence(`inject`, `build`);
});

在package.json中配置指令碼

"scripts": {
    "start": "concurrently "gulp" "node server.js""
  }
  • 執行npm start即可本地啟動專案

  • 上線合併程式碼的時候執行gulp dist命令即可

拖延症晚期,終於寫完了。有時間會加入eslint校驗,新增md5,新增sass等等。。。需要做的還有很多,看心情吧!

相關文章