日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端基于gulp后端基于freemarker的工作流程总结

發布時間:2025/6/16 HTML 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端基于gulp后端基于freemarker的工作流程总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近在做一個PC端的項目,由于項目需要兼容到IE8,所以從技術選型上采取了公司之前一直沿用的前端基于gulp后端基于freemarker的模式來進行開發。

那么gulp+freemarker這種開發模式的流程到底是怎樣的呢?我這邊就來簡單的分析一下。

一、前端基于gulp

前端技術棧:

  • gulp
  • jquery
  • ajax
  • less...

前端項目結構:

├── README.md 項目介紹 ├── src 源碼目錄 │ ├── common ├── less 公共樣式├── js 公共js├── plugins 插件 項目公共文件 │ ├── img 圖片 │ ├── js js │ ├── less 樣式 ├── .eslintrc.js eslint規則配置 ├── package.json 工程文件 ├── gulpfile.js 配置文件 ├── server.js 本地服務 復制代碼

從目錄來看,非常簡單,我這邊就主要來分析一下gulpfile.js和server.js

gulpfile.js

熟悉gulp的同學都知道,一般我們會將整個項目兩種環境來調用,即開發環境和生產環境

開發環境的配置:

var gulp = require("gulp"),less = require("gulp-less"),clean = require("gulp-clean"),header = require("gulp-header");/*** less 編譯* @return {[type]} [description]* 開發環境調用*/ gulp.task("less", ["cleanCss"], function() {gulp.src(['src/less/*.less','src/common/less/*.less']).pipe(plumber({errorHandler: errorHandler})).pipe(less()).pipe(addHeader()).pipe(gulp.dest('dist/css'));});/*** js 編譯* @return {[type]} [description]* 開發環境調用*/ gulp.task('js', ['cleanJs'], function() {gulp.src(['src/js/*.js', 'src/common/js/*.js']).pipe(plumber({errorHandler: errorHandler})).pipe(addHeader()).pipe(gulp.dest('dist/js'));gulp.src('src/common/plugins/*.js').pipe(gulp.dest("dist/js/plugins")) })/*** img 輸出* @return {[type]} [description]* 開發環境調用*/ gulp.task("imgOutput", ["cleanImg"], function(){gulp.src('src/img/**/*.*').pipe(gulp.dest("dist/img"))}) 復制代碼

簡析上述代碼:

在開發環境中我們需要對我們項目的src下的業務less、js、img和common下的公共less、js、img進行編譯打包,那么我們就需要借助gulp.task()這個方法來建立一個編譯任務。創建完任務以后,我們就需要通過gulp.src()來指向我們需要編譯的文件

最后我們再通過gulp.pipe()來創建一個又一個我們需要的管道,如

gulp.pipe(plumber({errorHandler: errorHandler}))

function errorHandler(e) {// 控制臺發聲,錯誤時beep一下gutil.beep();gutil.log(e); } 復制代碼

編譯的時候控制臺打印錯誤信息。

gulp.pipe(addHeader())

/*** 在文件頭部添加時間戳等信息*/ var addHeader = function() {return header(banner, {pkg: config,moment: moment}); };復制代碼

編譯以后在文件的頭部加上編譯時間

gulp.pipe(gulp.dest('dist/js'))

將編譯后的文件輸出到dist目錄下

生產環境的配置:

var gulp = require("gulp"),less = require("gulp-cssmin"),clean = require("gulp-uglify");header = require("gulp-header")/*** css build* @return {[type]} [description]* 正式環境調用*/ gulp.task("cssmin", ["cleanCss"], function() {gulp.src('src/common/less/all.base.less').pipe(less()).pipe(cssmin()).pipe(rename({suffix: '.min'})).pipe(addHeader()).pipe(gulp.dest("dist/css"));gulp.src('src/less/*.less').pipe(less()).pipe(cssmin()).pipe(addHeader()).pipe(gulp.dest("dist/css"));});/*** js 編譯* @return {[type]} [description]* 正式環境調用*/ gulp.task('jsmin', ['cleanJs'], function() {gulp.src(['src/js/**/*.js', 'src/common/js/**/*.js']).pipe(plumber({errorHandler: errorHandler})).pipe(uglify()).pipe(addHeader()).pipe(gulp.dest('dist/js'));gulp.src('src/common/plugins/**/*.js').pipe(uglify({mangle: true})).pipe(addHeader()).pipe(gulp.dest("dist/js/plugins")) }) 復制代碼

關于生產環境的配置其實跟上述的開發環境配置原理差不多,區別將在于生產環境中我們需要借助gulp-cssmin和gulp-uglify將css和js都進行壓縮,縮小文件的體積。

這里提一下cleancss和cleanjs的意思,其實就是在我們每一次編譯打包的時候將原來已經打包生成css和js都清理調,這樣保證我們每次編譯打包的代碼都是最新的。

gulp.task("cleanCss", function() {return gulp.src('dist/css', {read: false}).pipe(clean()); });gulp.task("cleanJs", function() {return gulp.src('dist/js', {read: false}).pipe(clean()); });gulp.task("cleanImg", function() {return gulp.src('dist/img', {read: false}).pipe(clean()); }); 復制代碼

開發環境監聽

gulp.task("watch", function() {livereload.listen();// 調用gulp-watch插件實現編譯有改動的LESS文件gulp.watch(['src/less/*.less','src/common/less/*.less'], function(file) {gulp.src(file.path).pipe(plumber({errorHandler: errorHandler})).pipe(less()).pipe(addHeader()).pipe(gulp.dest('dist/css'));});gulp.watch(['src/js/**/*.js', 'src/common/js/**/*.js'], function(file) {gulp.src(file.path).pipe(gulp.dest("dist/js"))});// 監聽圖片改動gulp.watch('src/img/**/*.*', function(file){gulp.src(file.path).pipe(gulp.dest("dist/img"))})// 監聽有變化的css,js,ftl文件,自動刷新頁面gulp.watch(['dist/**/*.css', 'dist/**/*.js', ftlPath]).on('change', livereload.changed);}); 復制代碼

在開發項目的時候我們需要借助gulp.watch()來實時的監聽項目中代碼的改動,并且通過gulp-livereload這個插件來實時的刷新我們的頁面,以提高我們的開發效率。

說完gulpfile.js后我們再來分析一下server.js

server.js

const path = require('path'),express = require('express'),proxy = require("express-http-proxy"),compress = require('compression'),app = express(),fs = require('fs'),config = require('./package.json'),projectName = config.name,port = process.env.PORT || '9091'// GZIP壓縮 app.use(compress());// 設置響應頭 app.use(function(req, res, next) {res.header('X-Powered-By', 'Express');res.header('Access-Control-Allow-Origin', '*');next(); })// 當前靜態項目的資源訪問 app.use('/' + projectName, express.static('dist')); app.use('/html', express.static('src/pages'));// 靜態服務器監聽 app.listen(port, '0.0.0.0', function() {console.log('static server running at ' + port) }) 復制代碼

這里我們通過node中express框架來為我們搭建本地服務,這里重點提一下靜態資源項目的訪問

通過app.use()方法傳入兩個參數,其中projectName代表的是我們在package.json中定義項目名稱,如下phip_ehr

{"name": "phip_ehr","version": "1.0.0","description": "","main": "index.js","scripts": {"start": "gulp && gulp watch","build": "NODE_ENV=production gulp build","server": "node server.js"} 復制代碼

第二個參數express.static('dist')意思是將我們的服務代理到編譯打包后的dist文件下如:http://192.168.128.68:9091/phip_ehr/js/**.js

這樣以來我們將可以輕松的獲取到整個項目下的所有靜態了。

二、后端基于freemarker

后端端技術棧:

  • java
  • freemarker ...

這里后端的項目結構我這邊只截取跟我們前端相關的目錄來說明

后端端項目結構:

├── templates 項目模版 │ ├── home ├── layouts 頁面布局├── views 業務代碼(ftl)├── widgets 項目依賴復制代碼

layouts

default.ftl

<!DOCTYPE HTML> <html><head><link rel="dns-prefetch" href="${staticServer}"><meta http-equiv="X-UA-Compatible" content="IE=edge">${widget("headInner",page.bodyAttributes)}<#list page.styles as style><#if (style?index_of('http') > -1) ><link href="${style}?v=${version}" rel="stylesheet" type="text/css" /><#else><link href="${staticServer}/phip_ehr/css/${style}?v=${version}" rel="stylesheet" type="text/css" /></#if></#list></head><body>${widget("header",page.bodyAttributes)}<div id='gc'>${placeholder}</div>${widget("footerJs")}</body> </html> 復制代碼

上述代碼是整個項目頁面的布局結構

${widget("headInner",page.bodyAttributes)}

這個方法意思是引入一些我們前端靜態的公共樣式和一些公共的meta標簽。

headInner.ftl

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta property="wb:webmaster" content="3b0138a4c935e0f6" /> <meta property="qc:admins" content="341606771467510176375" /> <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> <meta http-equiv="Pragma" content="no-cache" /> <meta http-equiv="Expires" content="0" /><link rel="stylesheet" href="${staticServer}/phip_ehr/css/reset.css?v=${version}" type="text/css"/> <link rel="stylesheet" href="${staticServer}/phip_ehr/css/common.css?v=${version}" type="text/css"/> 復制代碼

這里提一下${staticServer}這個當然指的就是我們靜態域名了,需要在后端項目的配置文件config中來聲明,即指向我們前端的靜態服務

**.mursi.attributesMap.staticServer=http://192.168.128.68:9091 **.mursi.attributesMap.imgServer=http://192.168.128.68:9091 復制代碼

引入完我們的公共樣式以后,那接下來我們業務樣式怎么引入呢?

<#list page.styles as style><#if (style?index_of('http') > -1) ><link href="${style}?v=${version}" rel="stylesheet" type="text/css" /><#else><link href="${staticServer}/phip_ehr/css/${style}?v=${version}" rel="stylesheet" type="text/css" /></#if> </#list> 復制代碼

這段代碼就是用來引入我們的業務樣式的,意思是利用后端框架封裝的page這個對象中style屬性,然后對所有頁面的style標簽進行遍歷

然后在我們業務代碼(ftl)中將可以通過addstyle這個方法來引入我們的業務樣式了

${page.addStyle("audit.css")} 復制代碼

${widget("header",page.bodyAttributes)}

這個方法的意思是引入我們頁面中公共的頭部

${placeholder}

這個意思是引入我們頁面主體內容部分

${widget("footerJs")}

這個意思是引入我們頁面中js文件

footerJS.ftl

<script type="text/javascript">$GC = {debug: ${isDev!"false"},isLogined : ${isLogin!"false"},staticServer : '${staticServer}',imageServer : '${imageServer}',kanoServer : '${kanoServer}',version:"${version}",jspath:"${staticServer}" + "/phip_ehr/js"};// $GS { Array } - the init parameters for startup$GS = [$GC.jspath + "/plugins/jquery-1.8.1.min.js",$GC.jspath + "/GH.js?_=${version}",$GC.jspath + '/plugins/validator.js',function(){// load common moduleGL.load([GH.adaptModule("common")]);// load the modules defined in pagevar moduleName = $("#g-cfg").data("module");if(moduleName){var module = GH.modules[moduleName];if(!module) {module = GH.adaptModule(moduleName);}if(module) {GL.load([module]);}}}]; </script><!-- 引入js模塊加載器 --> <script type="text/javascript" src="${staticServer}/phip_ehr/js/GL.js?_=${version}" ></script><script src="http://127.0.0.1:35729/livereload.js"></script>復制代碼

這段代碼中$GC就指的是初始化一些變量,然后$GS中就是引入我們項目中依賴的公共js,如jquery、common.js等。其次是通過GL.js這個模塊加載器來加載我們的業務js

這樣我們就可以在我們的業務ftl中通過data-moduls來引入每個頁面中的業務js了

a.ftl

<div class="g-container gp-user-info J_UserInfo" id="g-cfg" data-module="a" data-fo-appcode="1" data-header-fixed="1" data-page="infirmary"></div> 復制代碼

a.js

GH.run(function() {GH.dispatcher('.J_Home', function() {return {init: function() {this.switchPatient();},/*** * 切換就診人檔案*/switchPatient: function() {console.log(1);}}}) }, [GH.modules['validator'],GH.modules['datepicker']]); 復制代碼

dispatcher就是相當于頁面的分發器,當然每個頁面只能擁有一個獨立的分發器,run()方法就是我們封裝在GH.js的公共調用方法

那么我們項目中引入 一些公用的插件要怎么引入呢?

那么我們就在GH.js里封裝了GH.modules()方法來引入插件,這里就不詳細的說明了。

這里順帶也提一下ftl,什么是ftl?ftl就是類似于我們的html一樣,但是它不同的地方就是它是基于freemarker語法來進行編寫的一種后端模版引擎。我們項目中一些可以同步加載的數據都可以利用freemarker的語法在ftl中直接進行操作

小結:

這種前后端不分離的模式有哪些優缺點呢?

優點:雖然在開發效率上比不上純前后端分離的模式(vue+webpack,react+webpack),但是針對一些對于兼容性要求很高的多頁項目,這種開發模式也是可取的。

缺點:對后端服務依賴太強,往往后端服務一旦出現報錯或者掛掉后,前端的工作就沒有辦法開展下去了,從而加大了前后端的開發成本。


《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的前端基于gulp后端基于freemarker的工作流程总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。