使用Grunt遇到的問題?
- 必須要安裝
NodeJS
- 必須安裝
grunt-cli
- 需要編寫復雜的
Gruntfile.js
規則 - 每個項目中必須存在nodejs的
grunt
模塊 - 不方便管理每一個包含grunt的項目
- 無法快速開始一個項目
解決思路
- 直接把
NodeJS
跟grunt-cli
包含進去? - 弄個有UI的界面來管理?
- 用程序簡化gruntfile的規則?
- 將所有項目中需要的grunt模塊包含到一起?
- 默認內置一些常用功能模塊?
解決方案 -- nodewebkit
- 集成了
nodejs
,省去NodeJS安裝 - 集成
webkit
內核,方便編寫界面 - 適合前端人員開發
- 一次開發,兼容三大平台window/mac/linux
遇到問題
一.如何讓NodeJS運行Grunt?
-
利用NodeJS的spawn運行cmd命令
//切換運行環境到項目中 process.chdir("項目地址"); //執行grunt require("child_process").spawn("grunt");
這種方案最簡單,但需要依賴
NodeJS
跟grunt-cli
-
將grunt-cli的模塊直接引進代碼中,利用nodejs調用
var gruntpath = "grunt.js的路徑"; var grunt = require(gruntpath); grunt.cli();
直接運行,提示找不到gruntfile.js,修改grunt文件夾中的
task.js
,大概在430行左右var old_path = process.cwd();//獲取當前工作目錄 process.chdir('項目文件目錄');//修改到項目目錄 var gruntfile = allInit ? null : grunt.option('gruntfile') || grunt.file.findup('Gruntfile.{js,coffee}', {nocase: true});//查找gruntfile文件 process.chdir(old_path);//修改回程序目錄 此處省略n行代碼~~~ (grunt.option('npm') || []).forEach(task.loadNpmTasks);//加載npm的模塊 process.chdir('項目文件目錄');//切換到項目目錄
先切換到項目文件目錄查找
gruntfile.js
文件,然后切換回程序目錄查找node模塊,運行完grunt后,程序自動退出了,囧,需要修改grunt下的exit.js
process.exit(0);//這句需要注釋掉
二.如何在子進程中運行Grunt?
-
利用NodeJS的child_process.fork
var child = require("child_process").fork("child.js"); child.onmessage = function(data){ console.log(data); } child.on("exit",function(exitCode){ console.log(exitCode); });
--運行后提示:unzip the package xx/child.js,上網各種谷歌之后得出作者結論:
child_process.fork is broken
--囧,就是這個方法是不能用了?繼續谷歌之后得知
child_process.fork是無法運行js文件,它是直接運行執行命令
nw 文件夾
,所以修改一下,在child
文件夾中也放一個package.json
文件,執行后,果然成功了。--然后又留下一個大問題,無法使用fork的通信接口,囧,最后只好用
tcp
來實現進程通信。--當我想打包成app測試的時候,發現,壓根就不會運行子進程
child
因為child_process.fork是運行
nw
命令,所以,打包后是沒有nw命令 -
利用NodeJS的webworker來執行
npm install node-webworker
之后引用
worker.js
var Worker = require("worker.js"); var workker = new Worker("child.js"); worker.onmessage = function(data){ console.log(data); } worker.postmessage({msg:'hello'});
運行后,發現child.js中的任何信息都無法傳遞回給父進程,最后發現在
worker.impl.buffer
中保存了相關信息。var timeId = setInterval(function(){ var msg = worker.impl.buffer; if(!msg)return false; console.log(msg); worker.imple.buffer = ""; },1000);
雖然很挫,但還是實現了功能了,打包測試,發現一切OK。發送到其它電腦測試,提示:
spawn node not found,就是需要執行的命令找不到
奇怪,我沒調用
spawn
,哪來找不到?打開worker.js的源碼查看,囧,發現:child_process.spawn("node xxx.js");
囧,原來它是執行了
node
的命令來實現子進程,坑爹了。 -
利用HTML5的webworker
var worker = new Worker("child.js"); worker.onmessage = function(data){}; worker.postmessage("hello");
測試后,發現成功運行,消息也正常接收,可...
webworker
不支持運行nodejs
代碼,就是grunt無法跑起來。
三.目前可用方案
-
采用非子進程方式
- 無法同時跑多個grunt任務
- grunt沒有提供結束的方法
- 需要手動清除grunt的watch任務以及很多變量值,比較麻煩
- 出錯很可能會直接結束程序
-
獨立將child內容打包成可執行文件,采用child_process.spawn執行
- 需要打開兩個可執行文件,兩個加起來至少也有80M
- 開發時,需要用fork,打包時候用spawn
-
安裝NodeJS,采用webworker方式
- 電腦必須安裝了NodeJs
- 目前較好的方案
- 未來nodewebkit支持子進程方式,可以比較方便修改過來