1. 程式人生 > >Grunt 例項之 構建 seajs 專案

Grunt 例項之 構建 seajs 專案

Seajs 是時下比較熱的一款模組載入框架,除了能實現程式碼模組按需自動載入、增加程式碼的可複用性之外,還能夠培養我們的模組化低耦合開發思維。愛折(zhuang)騰(bi)的人值得一試。

擺脫 seajs 提供的 spm 構建工具 而改用 Grunt 去構建,這個過程是曲折的,艱辛的,沒點折騰的耐心估計不成,在這裡要感謝優秀的導師 海龍,被我抓住講了 1個小時,分享了他在折騰時遇到的問題,讓我走少了很多彎路(海龍哥自己摸這個 Grunt 配 Seajs,摸了 1個星期,我聽完後折騰一天就搞明白了,在站巨人的肩膀 果然就是不一樣)。

如果已經對 Seajs 十分理解的童鞋 可以直接 滾到最後看第二部分內容,而對 Seajs 一知半懂的 最好繼續慢慢往下看,基礎沒打好,爬得再快一樣會掉下來,還不懂自己錯在哪。

What is Seajs

看了不少站點使用seajs,但僅僅僅限於非同步載入js(沒錯,就僅僅是非同步載入一個 js檔案,裡面還是完完全全是普通的js程式碼),而非 Seajs 所推崇的 匿名模組程式碼,這樣也叫熟練使用 Seajs (擇選自不少應聘者簡歷上的技能說明) 也是醉了。

回顧下我愛撫 Seajs 的經過,在這裡,讓我來說說 我所理解的 Seajs。

在粗略看過下大致的使用方法之後,我就隨手搞了個demo試試。

demo 目錄結構如下:

demo_00
|
+ css
| + hellosea.css
|
+ js
| + lib
| | + jquery-1.11.0.min.js
| | + sea.js
| |
| + hellosea
|   + page.js
|   + util.js
|
+ html
+ hellosea.html

html部分:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Grunt seajs demo</title>
<link rel="stylesheet" href="../css/hellosea.css">
</head>
<body>
<div id="box" class="box"></div>
</body>
<script
src="http://www.jackness.org/wp-content/themes/JStyle/images/default/blank.png" _src="../js/lib/sea.js">
</script> <script> // seajs 的簡單配置 seajs.config({ base: "../js/lib/", alias: { "jquery": "jquery-1.11.0.min.js" } }); seajs.use("../js/hellosea/page.js"); </script> </html>

page.js 部分

define(function(require, exports, module) {

var util = require('./util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);

});

開啟 demo,很好果然 萬事起頭難,報錯了

grunt_seajs_img01

除錯了一下,原來是 這句問題

$ = require('jquery');

require 返回 null,恩,趕緊去看看官網怎麼說。 看來是因為 Seajs 本身的約定: ID 和路徑匹配原則

ID 和路徑匹配原則

所謂 ID 和路徑匹配原則 是指,使用 seajs.use 或 require 進行引用的檔案,如果是具名模組(即定義了 ID 的模組),會把 ID 和 seajs.use 的路徑名進行匹配,如果一致,則正確執行模組返回結果。反之,則返回 null。

舉個例子來消化下,就拿 require(‘jquery’) 做例子吧

要讓 require(‘jquery’) 正確返回 有 2種形式:

1 種是 通過 在 jquery裡面定義匿名模組,即

define(function(require,exports,module){
//.. do something
module.exports = jQuery;
}

另一種就是在js檔案裡面定義具名模組。在例子裡面,我們在頁面上是這樣定義的:

<!-- html code  -->
<script>
// seajs 的簡單配置
seajs.config({
  base: "../js/lib/",
  alias: {
    "jquery": "jquery-1.11.0.min.js"
  }
});

</script>

根據 路徑即 id原則,我們需要在 jquery 檔案裡面這樣定義:

define('jquery-1.11.0.min', [], function(require,exports,module){
return $;
});

然後我們看看例子裡的 jquery 是怎麼寫的, 在底部找到相關程式碼

"function"==typeof define&&define("jquery/jquery/1.10.1/jquery",[],function(){return x}))

這裡定義了 jquery檔案的 id 為 “jquery/jquery/1.10.1/jquery”, 但是我們頁面請求的 id 為 “jquery-1.11.0.min”, id 對不上,所以模組匹配不到,返回 null。

基於路徑即id原則,有 2種修改方式:

  • 1. 修改 jquery 原始碼,把 define(“jquery/jquery/1.10.1/jquery”,[],function(){return x})) 改為 define(“jquery-1.11.0.min”,[],function(){return x}))
  • 2. 調整 jquery 目錄路徑,使 jquery/jquery/1.10.1/jquery 具名模組生效

我選擇 第二種方式來修復,調整 jqeruy目錄結構, 順便 把 seajs 也跟著改

調整後的目錄結構為

demo_00
|
+ css
| + hellosea.css
|
+ js
| + lib
| | + jquery
| | | + jquery
| | |   + 1.10.1
| | |     + jquery.js
| | |     
| | + sea
| |   + sea
| |     + 2.2.0
| |       + sea.js
| |       
| + hellosea
|   + page.js
|   + util.js
|   
+ html
  + hellosea.html

至於為什麼要使用 jquery/jquery/1.10.1/jquery.js 這種結構,多了 1層的 jquery,而不直接使用 jquery/1.10.1/jquery.js,其實是因為考慮到擴充套件。拿jquery來舉例,如果有個 基於jquery的日曆控制元件 calendar.js 根據 推薦的結構 就可以這樣放置:

js
+ lib
| + jquery
| | + jquery
| | | + 1.10.1
| | |   + jquery.js
| | |   
| | + calendar   
| |   + 1.0.0
| |     + calendar.js   
| + ...
| 
+ ...

這樣一看就知道 日曆控制元件是基於 jquery 開發出來的了。

回到我們的例子上, 我們看到函式能成功執行固然開心,但是一開啟 頁面請求資訊欄一看,簡直嚇尿了,所有的js 都進行了請求。為了模組化,代價是請求數的暴增,這樣seajs的價值何在,還能好好玩耍嗎,還不如不用?

grunt_seajs_img02

恩,我們 繼續看看 官網,在一篇 為什麼要有約定和構建工具 文章 裡 找到了答案。

不想請求那麼多個檔案, 答案就是把檔案進行合併。 那麼 問題來了。

如何將模組合併在 1個 js 裡面

繼續拿 上面的 demo 來做例子,jquery 屬於 js庫,而seajs屬於頁面載入的必備檔案,當然就不必合併了,那麼剩下的我們就有必要進行合併了,即 page.js、util.js

調整下目錄結構,我們在 js/hellosea/ 下面 建立一個資料夾 【dist】 是用來放合併之後的檔案,即產出目錄;建立一個資料夾 【src】 用來放置我們的開發原始檔:

js
+ lib
| + jquery
| | + jquery
| |   + 1.10.1
| |     + jquery.js
| |
| + sea
|   + sea
|     + 2.2.0
|       + sea.js
| 
+ hellosea
  + dist
  | + page.min.js
  |
  + src
    + page.js
    + util.js

我們首先將 html 上面的 seajs.use 所用的檔案 指向 產出目錄,即:

// seajs 的簡單配置
seajs.config({
  base: "../js/lib/",
  alias: {
    "jquery": "jquery/jquery/1.10.1/jquery.js"
  }
});

seajs.use("../js/hellosea/dist/page.min.js");

我們再看看 page.js、util.js 這2個檔案

page.js

define(function(require, exports, module) {

var util = require('./util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);

});

util.js

define(function(require,exports,module){
var util = {};
var colorRange = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
util.randomColor = function(){
return '#' +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)];
};
module.exports = util;
});

這兩個檔案裡面都是通過匿名函式的方式建立的,根據文章的意思,我們如果想將他們合併在一個檔案裡面,就要在合併檔案裡面將這 2個 檔案中的匿名函式 變為 具名函式, 並且遵守路徑即id原則

我們把 hellosea/js/src/page.js 中的程式碼修改為具名函式:

define('../js/hellosea/src/page', ['./util', 'jquery'], function(require, exports, module) {

var util = require('./util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);

});

第二個引數是 我們把函式中有依賴其他檔案的 檔案 id(路徑)抽出來放到這裡面。Seajs 這樣設定的原因是:這樣 Sea.js 就不需要通過 factory.toString() 和正則匹配的方式來獲取依賴,直接從第二個引數中就可以拿到依賴陣列

同理 我們把 hellosea/js/src/util.js 也修改為具名函式:

define('../js/hellosea/src/util', [], function(require, exports, module) {
var util = {};
var colorRange = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];

util.randomColor = function() {
return '#' +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)] +
colorRange[Math.floor(Math.random() * 16)];
};

module.exports = util;
});

然後 我們把 hellosea/js/src/page.js 這入口檔案裡的程式碼拷貝到 hellosea/js/dist/page.min.js。 根據路徑即 id原則,我們把 id 改一下:

define('../js/hellosea/dist/page.min', ['./util', 'jquery'], function(require, exports, module) {

var util = require('./util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);

});

然後 再把 hellosea/js/src/util.js 的程式碼考到 hellosea/js/dist/page.min.js 的下面。

執行一下程式碼,發現有個地方錯了:

grunt_seajs_img03

原因是 找不到 ../js/hellosea/dist/util.js 這個檔案。

在 ‘../js/hellosea/dist/page.min’ 模組裡面 請求的 ‘./util’ 是不存在的, 因為根據檔案自身路徑 這請求最終是指向 ‘../js/hellosea/dist/util.js’, 而我們需要他指向的是 ‘../js/hellosea/src/util.js’, 也就是 下面 util 模組的 id。

所以我們要把路徑調整到正確的位置:

define('../js/hellosea/dist/page.min', ['../src/util', 'jquery'], function(require, exports, module) {

var util = require('../src/util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);

});

這就是 seajs 的工作、執行原理了。瞭解清楚原理,我們就可以更好地理解構建工具的工作方式。接下來我們說說 seajs的 構建工具。

使用 Grunt 作為 seajs的 構建工具

如真像上面說的,我們的每次修改程式碼、編寫程式碼、除錯程式碼 都需要我們手工一個個檔案地進行合併、調整、壓縮,如此繁瑣的操作估計各個程式大大就算耐性再高都會被玩壞,更別說效率了。所以,代我們完成這樣些操作的 構建工具 應運而生。

seajs 官網 提供了 seajs特供的構建工具 spm

操作雖然簡單,但是需要遵守的規則也更多了,其中包括 檔案路徑。

這檔案路徑 如果是在全新的一個專案裡面搞還好,但是如果是針對舊專案的seajs改造,目錄架構改動之大以至於估計沒開始你就已經選擇放棄了。

所以這裡介紹的是更具自由的 Grunt 來作為 seajs的 構建工具

根據我上面說的 seajs 工作原理,我們其實想讓構建工具完成的是以下的幾個事情

  1. 將入口檔案拷貝到 產出目錄
  2. 建立一個臨時目錄
  3. 將需要合併的js檔案轉為具名函式,並保持獨立地儲存在這個臨時目錄
  4. 將臨時目錄下獨立的具名函式檔案 合併為 1個 js 檔案
  5. 將這個合併的 js 檔案 拷貝到 我們的輸出目錄
  6. 壓縮 這個 合併後的 檔案
  7. 將這個臨時目錄刪除

seajs 提供以下 grunt 的外掛來 構建 專案

  • grunt-cmd-transport(用於將匿名函式轉為 具名函式)
  • grunt-cmd-concat(根據檔案中的 id 自動 拷貝對應目錄檔案的內容到 同一檔案下)

所以 我的 package.js 這樣配置

{
  "name": "helloSeajs",
  "version": "1.0.0",
  "author": "jackness Lau",
  "devDependencies": {
    "grunt": "0.4.1",
    "grunt-cmd-transport": "0.1.1",
    "grunt-cmd-concat": "0.1.0",
    "grunt-contrib-uglify": "0.2.0",
    "grunt-contrib-clean": "0.4.0"
  }
}

下面說說作為核心的 grunt-cmd-transport、grunt-cmd-concat 這 2個外掛的使用配置

grunt-cmd-transport 介紹

這外掛 用於將檔案中定義的匿名函式轉為 具名函式。配置如下:

grunt.initConfig({
transport: {
hellosea: {
options: {
// 是否採用相對地址
relative: true,
// 生成具名函式的id的格式 預設值為 {{family}}/{{name}}/{{version}}/{{filename}}
format: '../js/hellosea/{{filename}}' 
},
files: [{
// 相對路徑地址
'cwd':'js/hellosea/',
// 需要生成具名函式的檔案集合
'src':['dist/hellosea.js','src/util.js'],
// 生成存放的檔案目錄。裡面的目錄結構與 src 裡各個檔名帶有的目錄結構保持一致
'dest':'.build'
}]
}
},
});

grunt-cmd-concat 介紹

這外掛 用於根據檔案中的 id 自動 拷貝對應目錄檔案的內容到 同一檔案下。配置如下:

grunt.initConfig({
concat:{
hellosea: {
options: {
// 相對路徑地址
relative: true
},
files: {
// 合併後的檔案地址
'js/hellosea/dist/hellosea.js': ['.build/dist/hellosea.js']
}
}
}
});

解壓壓縮包之後 我們 先 npm install 一下

npm install

以下是 Gruntfile.js 內容:

module.exports = function(grunt) {
grunt.initConfig({
/**
 * step 1:
 * 將入口檔案拷貝到 產出目錄
 */
copy: {
hellosea:{
files:{
"js/hellosea/dist/hellosea.js":["js/hellosea/src/hellosea.js"]
}
}
},
/**
 * step 2:
 * 建立一個臨時目錄
 * 將需要合併的js檔案轉為具名函式,並保持獨立地儲存在這個臨時目錄
 */ 
transport: {
hellosea: {
options: {
// 是否採用相對地址
relative: true,
// 生成具名函式的id的格式 預設值為 {{family}}/{{name}}/{{version}}/{{filename}}
format: '../js/hellosea/{{filename}}' 
},
files: [{
// 相對路徑地址
'cwd':'js/hellosea/',
// 需要生成具名函式的檔案集合
'src':['dist/hellosea.js','src/util.js'],
// 生成存放的檔案目錄。裡面的目錄結構與 src 裡各個檔名帶有的目錄結構保持一致
'dest':'.build'
}]
}
},
/**
 * step 3:
 * 將臨時目錄下獨立的具名函式檔案 合併為 1個 js 檔案
 * 將這個合併的 js 檔案 拷貝到 我們的輸出目錄
 */
concat: {
hellosea: {
options: {
// 是否採用相對地址
relative: true
},
files: {
// 合併後的檔案地址
'js/hellosea/dist/hellosea.js': ['.build/dist/hellosea.js']
}
}
},
/**
 * step 4:
 * 壓縮 這個 合併後的 檔案
 */
uglify: {
hellosea: {
files: {
'js/hellosea/dist/hellosea.js': ['js/hellosea/dist/hellosea.js'] //對dist/application.js進行壓縮,之後存入dist/application.js檔案
}
}
},
/**
 * step 5:
 * 將這個臨時目錄刪除
 */
clean: {
build: ['.build']
}
});
grunt.loadNpmTasks('grunt-cmd-transport');
grunt.loadNpmTasks('grunt-cmd-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('default', ['copy','transport', 'concat', 'uglify', 'clean']);
grunt.registerTask('build', function(name,step){
switch(step){
case "1":
grunt.task.run('copy:' + name);
break;
case "2":
grunt.task.run('transport:' + name);
break;
case "3":
grunt.task.run('concat:' + name);
break;
case "4":
grunt.task.run('uglify:' + name);
break;
case "5":
grunt.task.run('clean:' + name);
break;
default:
grunt.task.run(['copy:' + name,  'transport:' + name, 'concat:' + name, 'uglify:' + name, 'clean'])
break;
}
});
};

我們執行下任務 看看是否能執行成功

grunt

grunt_seajs_img04

出錯, 提示在執行 transport 時報錯, 找不到 js/hellosea/dist/util.js 檔案。額 但是我們想要的 應該是 js/hellosea/src/util.js 才對, Why?

開啟 js/hellosea/src/hellosea.js 檔案

define(function(require, exports, module) {

var util = require('./util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);
});

恩, 問題應該出在這裡了

var util = require('./util'),

想想我們定義構建工具做了什麼:

  • 1. 複製 hellosea/src/hellosea.js 檔案到 hellosea/dist/hellosea.js
  • 2. 將 hellosea/dist/hellosea.js 轉為具名函式

所以這 hellosea/src/hellosea.js 同樣用於 hellosea/dist/hellosea.js

所以 require(‘./util’) 變成了相對於 hellosea/dist/hellosea.js 這個檔案目錄來執行的了,當然找不到了。

因此,我們要對 js/hellosea/src/hellosea.js 這樣修改:

js/hellosea/src/hellosea.js 檔案

define(function(require, exports, module) {

var util = require('../src/util'),
$ = require('jquery');
setInterval(function() {
$('#box').css('background-color',util.randomColor());
}, 1500);
});

好是好,但是,問題又來了,線上有問題的話 怎麼除錯

根據地址進行 發行版 與開發版 的切換

下面是 Seajs 的建議方案:

// seajs 的簡單配置
seajs.config({
  base: "../js/lib/",
  alias: {
    "jquery": "jquery/jquery/1.10.1/jquery.js"
  }
});
if(location.href.indexOf("dev=1") != -1){
seajs.use("../js/hellosea/src/hellosea");
} else {
seajs.use("../js/hellosea/dist/hellosea");
}

在確定沒問題的情況下,上線時候可以將開發版部分程式碼去掉

// seajs 的簡單配置
seajs.config({
  base: "../js/lib/",
  alias: {
    "jquery": "jquery/jquery/1.10.1/jquery.js"
  }
});

seajs.use("../js/hellosea/dist/hellosea");

恩,好像已經講完可以投入使用的感覺,我又有個問題了,如果我想將非本專案的一個 通用 js 也合併在一起呢,情況會不會一樣?

對非本專案的 js 進行 seajs 構建

同樣,在上面 demo的 基礎上 增加一個 通用頭部的呼叫。 目錄結構如下

demo
+ css
|
+ html
|
+ js
  + lib
  | + jquery
  | | + jquery
  | |   + 1.10.1
  | |     + jquery.js
  | |
  | + sea
  |   + sea
  |     + 2.2.0
  |       + sea.js
  | 
  + hellosea
  | + dist
  | | + hellosea.js
  | |
  | + src
  |   + hellosea.js
  |   + util.js
  |  
  + common
    + head.js

相關推薦

Grunt 例項 構建 seajs 專案

Seajs 是時下比較熱的一款模組載入框架,除了能實現程式碼模組按需自動載入、增加程式碼的可複用性之外,還能夠培養我們的模組化低耦合開發思維。愛折(zhuang)騰(bi)的人值得一試。 擺脫 seajs 提供的 spm 構建工具 而改用 Grunt 去構建,這個過程是

springboot學習構建簡單專案搭建

概述   相信對於Java開發者而言,spring和springMvc兩個框架一定不陌生,這兩個框架需要我們手動配置的地方非常多,各種的xml檔案,properties檔案,構建一個專案還是挺複雜的,在這種情況下,springboot應運而生,他能夠快速的構建spring專案,而且讓專案正常執行起來的配置檔案

Docker入門構建Springboot專案釋出在映象環境

在之前,簡單的講了一下docker環境的搭建,這裡就說一下docker的專案部署,如springboot專案如何執行在docker環境中 這裡其實主要就是在原有下載映象的基礎上進行重新構建。

Jenkins入門教程--構建軟體專案

Jenkins可以用於執行典型的構建伺服器工作,例如執行連續/官方/每晚構建,執行測試或執行一些重複的批處理任務。這在Jenkins被稱為“自由式軟體專案”。 設定專案 轉到Jenkins首頁,選擇“New Job”,然後選擇“Build

構建seajs業務模組grunt VS spm build

在最開始,我並不知道grunt可以構建CMD模組.(以下spm指代spm build) 當時正困惑於如何用spm方便的構建業務模組,後來看到@twinstony (感謝@twinstony的分享)使用grunt-cmd-xxx外掛構建了CMD模組,跟著demo自己做了測試,的確可以構建,但是有一個問題:

grunt 例項構建(四)

相關外掛的引用: grunt-usemin  對頁面的操作  grunt-contrib-cssmin  壓縮css  load-grunt-tasks 瘦身gruntfile   grun

IDEA構建一個Web基礎專案

IDEA之構建一個Web基礎專案 前言   昨天構建Web基礎專案,發現編輯器不知道怎麼用了,用SpringBoot習慣了,因此做一個記錄。 正文   首先點選 ->File -> new Project -> mave

Gradle重新認識Gradle(專案結構、命令列、task、構建Java專案、包裝器)

前言:之前一直接觸使用Gradle完成Android專案的自動化構建,所謂重新認識Gradle是因為最近看了《Gradle IN Action》一書,對gradle進行了一次全面的重新的認識。所以決定以系列部落格,來完成自己對Gradle學習之路的一個總結。關於

構建Android專案RxAndroid+Retrofit網路請求

注意 Retrofit 2.0+和Retrofit 2.0之前的版本語法上有差別,本文基於Retrofit2.1.0 什麼是Retrofit? retrofit是一款針對Android網路請求的開源框架,它與okhttp一樣出自Square公司。Rotrofit2.0的

Vue.js構建專案初始步驟(二)

接上回: 報錯解決: This dependency was not found: * common/stylus/index.styl in ./src/main.js 解決

Maven權威指南(續)多模組專案構建及POM優化

  在《Maven權威指南》部分I中,第6、7章介紹了多模組專案及多模組企業級專案的構建思想。對於多模組的情況,無論是簡單的或是企業級的,對於POM來說,重點就是分析處理好父POM與子POM之間的關係,包括依賴管理(DependencyManagement)、外掛管理(Plu

Jenkins入門教程自動構建部署專案常見錯誤及解決方案(十)jenkins中構建maven專案一直打包失敗

此篇文章總結六筆者在使用jenkins過程中的一些坑和常見錯誤總結和解決方案,在這裡分享給大家,希望大家少走彎路。常見錯誤:1、在 Jenkins 中,使用 maven 打包報 package xxx does not exist 問題的解決方法錯誤資訊:解決方案:需要把ma

Jenkins構建Android專案持續整合系統配置篇

使用者設定 jenkins有自有的使用者資料庫,為了安全考慮,可以啟用使用者註冊,使用許可權控制登入。 切記,授權策略要先選擇“登入使用者可以做任何事”,因為現在還沒有任何使用者,不能指定管理員,設定之後儲存退出。 填寫註冊資訊。 然後使

初學構建專案倉庫管理系統主頁面的實現(二)

       上一篇部落格我講了資料庫的建立以及管理員表的實現和管理員登入頁面的實現,這一篇我來說說倉庫管理系統的主頁面的實現。主要是用eclipse中的外掛windowbuilder來實現。其下載地址為:http://www.eclipse.org/windowbuild

從零開始學習Gradle三---多專案構建

   隨著資訊化的快速發展,IT專案變得越來越複雜,通常都是由多個子系統共同協作完成。對於這種多系統、多專案的情況,很多構建工具都已經提供了不錯的支援,像maven、ant。Gradle除了借鑑了ant或者maven的繼承的方式定義子專案,也提供了一種更為方便的集中配置的方式,大大減少了構建帶來的複雜度。

webpack+vue+vueRouter模組化構建完整專案例項詳細步驟-入門篇

新建專案 開始(確認已經安裝node環境和npm包管理工具) 1、新建專案檔名為start_vuedemo 2、npm init -y 初始化專案,我的win7系統,工程在d盤的vue_test_project資料夾下的名為start_vuedemo的工程資料夾 如圖所示: 在該工程下自動生成一個pac

Shiro原始碼研究構建Subject例項

接上一篇部落格Shiro原始碼研究之處理一次完整的請求,其中的第二小節中的這樣一行程式碼final Subject subject = createSubject(request, response);直接略過了。這篇文章就專門來對這段程式碼後面所發生的事

1. webpack+vue+vueRouter模組化構建完整專案例項詳細步驟-入門篇

新建專案開始(確認已經安裝node環境和npm包管理工具)1、新建專案檔名為start_vuedemo2、npm init -y 初始化專案,我的win7系統,工程在d盤的vue_test_project資料夾下的名為start_vuedemo的工程資料夾如圖所示:在該工程下自動生成一個package.jso

springboot構建web專案的叢集部署

最近搞了個springboot構建的bbs專案,專案整體是從github上面clone的,到本地做了一些環境移植,最後部署到linux環境下,部署2個節點,算是一個叢集。期間踩坑無數,這裡記錄一下,以備後用,免蹈覆轍。 1.springboot構建的web專案,例子裡面都是

java網絡編程學習——構建基於多線程的網絡通信模型1

傳遞 println util adl 多個 start oid stream 數值   該例展示了多用戶/服務器通信模型,包含三個文件:Server.java ServerThread.java 和Client.java類。其中ServerThread類支持多線程,為