Автор оригинала: Kyle J. Roux.
Примечание: Это часть 2 мультиугольного блога о моем стремлении к использованию угловой для программирования на стороне сервера, предыдущие сообщения:
Часть 1 Угловой/узел: Создание инструмента командной строки для генерации проектов
- Примечание : Код из части 1 понадобится несколько обновлений, которые будут совместимы с кодом из этого поста, но все в его Github Repo это тока и должна работать вместе с кодом ниже. Так что, если вы столкнулись с проблемами с чем-либо в этом посте, будьте уверены, что вы установили
Node-NG
локально черезNPM
(который вытащит последний код из GitHub), запустив:
- Примечание : Код из части 1 понадобится несколько обновлений, которые будут совместимы с кодом из этого поста, но все в его Github Repo это тока и должна работать вместе с кодом ниже. Так что, если вы столкнулись с проблемами с чем-либо в этом посте, будьте уверены, что вы установили
npm install node-ng
Время взглянуть на то, что нам нужно от узла
Одним из первых инструментов, которые мы будем строить на нашем поисках программы командной строки для создания проектных скелетов для нас, будет угловым модулем, который обернут узел ФС
модуль. ФС
Модуль обеспечивает низкоуровневый доступ к файловой системе, поэтому мы будем обернуть его как угловой модуль (что мы будем делать в любое время, мы столкнемся к внешнему коду, нам нужно интегрировать в наш проект).
Обратите внимание, что отсюда мы будем использовать CoffeeScript.
Кроме того, мы должны иметь в виду, что угловой был спроектирован с самого начала в качестве Frontend Framework.
Это помогает объяснить (или оправдать, в зависимости от того, как вы можете почувствовать об этом), многие из вариантов, сделанных командой, которая создала его, и теперь (так как угловой – все еще активно развивается в настоящее время), а также проливает свет на то, почему некоторые Особенности содержались, в то время как другие не были.
Вот почему у нас есть angular.module.directive
Функция, позволяющая нам манипулировать DOM и ассоциировать его с нашим JavaScript, что делает все наши веселые веб-страницы, которые угловые позволяет, т. Е. Перетаскивание, анимацию и т. Д. Это также почему уравновешенная петля ориентирована на изменение DOM, И делает много копирования и замены узлов DOM на основе того, как вы размещаете свои различные директивы в вашем HTML, поэтому это довольно мощная система.
К счастью, существует больше угловой, чем просто узлы DOM и дистанционная петля, в противном случае, в противном случае это может быть не очень использоваться за пределами браузера. Угловой имеет много функций, которые придут к удобной стороне сервера: DI, услуги и т. Д.
Теперь я начну создавать нашу командную строку, штуку по частям, внедряя каждую функцию, установленную в виде углового модуля, установленного через NPM. Сегодня мы будем работать с функциями обработки файлов узла.
Во-первых, нам нужно наше приложение, и снова, пожалуйста, обратите внимание, мы используем CoffeeScript, так как он позволяет более чистым способом написать JavaScript. Если вы не знакомы, я настоятельно рекомендую понять несколько минут, чтобы прочитать его.
Наша обертка модуля FS
Первое, что мы делаем, это создать наш угловой модуль объекта, используя angular.module
функция.
node-fs.coffee
'use strict` app = angular.module 'node.fs.app', []
Угловые обещания в узле
Теперь нам нужен быстрый способ обернуть функции из узла, в форму, используемой угловой, а также угловой $ Q
на основе обещаний. Для начального объекта обертки я просто введу узел ФС
Модуль в угловую службу для нас использовать позже. Тогда, для обещаний, я буду использовать похищать
Функция, которую я объяснил частично из этой серии. Эта функция принимает единственную функцию безблокировки в качестве единственного аргумента и возвращает новую функцию, с которой угловые могут работать с.
# first we need our service to call node functions from app.service 'nodeFs',[-> require 'fs' ] # next we will create a factory that will wrap our functions app.factory 'ngIfy',['nodeFs',(nodeFs)-> (name)-> promisify nodeFs[name] ] # now we need to wrap a few of the basic fs functions for $q app.factory 'ngStat',['ngIfy',(ngIfy)-> ngIfy 'stat' ] app.factory 'ngReaddir',['ngIfy',(ngIfy)-> ngIfy 'readdir' ] # and we also need some private functions, that implement some of the # functionality we need, I am going to be showing that the # functions are private by starting their names with a single _ app.factory '_isDir',[-> (res)-> res.blksize == res.size ] app.factory '_isFile',[-> (res)-> res.blksize !== res.size ] # now we use those implementation functions to implement the # syncronys and asyncronys versions of isFile and isDir app.factory 'isDir',['_isDir','ngStat',[(_isDir,ngStat)-> (name)-> ngStat(name).then (res)-> actualResult = _isDir res ] app.factory 'isDirSync',['_isDir','nodeFs',(_isDir,nodeFs)-> (name)-> _isDir nodeFs.statSync(name) ] app.factory 'isFile',['_isFile','ngStat',(_isFile,ngStat)-> (name)-> ngStat(name).then (res)-> actualResult = _isFile res ] app.factory 'isFileSync',['_isFile','nodeFs',(_isFile,nodeFs)-> (name)-> _isFile nodeFs.statSync(name) ]
Чтение и запись на файловую систему
Теперь, когда мы почти закончили, у нас есть только еще несколько вещей, которые нам нужно здесь.
Следующий выпуск, который мы будем решать, будем читать и запись к файлам, на данный момент мы избегаем удаления файлов, потому что это не одно из наших требований, но вы можете попробовать себя как упражнение после того, как мы закончили. Кроме того, мы не собираемся делать блокировку версий этих функций, потому что чтение и запись в файлы могут действительно занять много времени, поэтому не нужно блокировать наш прогресс, пока мы это делаем.
app.factory 'readFile',['$q','nodeFs',($q,nodeFs)-> def = $q.defer() (filename)-> nodeFs.readFile filename,(err,res)-> if err def.reject err else def.resolve res return def.promise ] app.factory 'writeFile',['$q','nodeFs',($q,nodeFs)-> def = $q.defer() (filename,data)-> nodeFs.writeFile filename,data,(err,res)-> if err def.reject err else def.resolve true return def.promise ]
Листинг файлов
И, наконец, наше последнее требование от ФС
Модуль узла будет отображаться содержимое каталогов. Который также будет довольно проще. Нам просто нужно использовать NGREADDIR
Фабрика мы определили ранее.
app.factory 'listDir',['ngReaddir',(ngReaddir)-> (name)-> ngReaddir name ]
Тестирование
Наконец, мы можем написать несколько небольших тестов, чтобы быть уверены, что работают как планируется.
module.exports = ()-> require '../dist/node-fs.js' fmtstr = require '../fstr.coffee' isDir = ng_load 'isDir',['node.fs.app'] isDirSync = ng_load 'isDirSync' isFile = ng_load 'isFile' isFileSync = ng_load 'isFileSync' listDir = ng_load 'listDir' readFile = ng_load 'readFile' writeFile = ng_load 'writeFile' $q = ng_load '$q' # test data firstTestItem = './dist/node-fs.js' secondTestItem = './dist' thirdTestItem = './src' fourthTestItem = './src/node-fs.coffee' testItems = [] for i in [firstTestItem,secondTestItem,thirdTestItem,fourthTestItem] testItems.push i # blocking tests console.log 'Starting blocking tests\n' console.log '\ntesting isDirSync\n' testItem = (func,itm)-> func itm testDirItem = (itm)-> result = testItem isDirSync,itm "is #{itm} a directory? ---> [#{result}]" for itm in testItems console.log fmtstr(testDirItem(itm),"--",60) console.log "\ntesting isFileSync\n" testFileItem = (itm)-> result = testItem isFileSync,itm "is #{itm} a file? ---> [#{result}]" for itm in testItems console.log fmtstr(testFileItem(itm),"--",60) doDirTests = -> testDirItem2 = (itm)-> testItem(isDir,itm).then (res)-> "\nWe are testing if #{itm} is a dir, is it? ---> [#{res}]\n" for itm in testItems testDirItem2(itm).then (res)-> console.log fmtstr(res, '--',80) ,(err)-> console.log "ERROR@!:",err doFileTests = -> testFileItem2 = (itm)-> testItem(isFile,itm).then (res)-> "\nWe are testing if #{itm} is a file, is it? ---> [#{res}]\n" for itm in testItems testFileItem2(itm).then (res)-> console.log fmtstr("#{res}", '--',80) ,(err)-> console.log "ERROR@!:",err console.log "counting #{testItems.indexOf(itm)}" doListDirTests = -> listDir('./dist').then (res)-> count = 0 count++ for r in res console.log "Should have 1 file, had: #{count}" listDir('./src').then (res)-> count = 0 count++ for r in res console.log "Should have 1 file, had: #{count}" doReadWriteTests = -> tstTxt = "this is a test file" tstName = "tst.txt" writeFile(tstName,tstTxt).then (res)-> readFile(tstName).then (res)-> console.log "Data from #{tstName}\n#{res}\n\nData from variable\n#{tstTxt}" console.log '\nstarting non-blocking tests\n' do doDirTests do doFileTests do doListDirTests do doReadWriteTests
Функция FMTSTR
Возможно, вы заметили, что я использую функцию FMTSTR
, который я потянув из fstr.coffee
Отказ Это просто абстракция строки форматирования Что я чувствовал, было настолько не связано с целями этого проекта, что нужно было в собственном файле. Во всяком случае, вот содержание fstr.coffee
:
makePadd = (char,num)-> res = [] for x in [1..num] res.push char res.join "" fmtstr = (s,splitchar,size,padchar)-> splitchar = splitchar or '--' size = size or 40 padchar = padchar or ' ' #console.log s parts = String(s).split(splitchar) padlen = size - (parts[0].length + parts[1].length) padd = makePadd padchar,padlen "#{parts[0]}#{padd}#{parts[1]}" module.exports = fmtstr
Финальные ноты
У нас есть все, что нам нужно от узлов ФС
Модуль на данный момент! Давайте посмотрим на разные вещи, которые нам удалось выполнить в этой статье:
Проверка, если файл dir или нет
Чтение файлов
Письменные файлы
и листинг каталогов
И все эти функции интегрированы в угловой рабочий процесс
Спасибо, что пришли на это путешествие со мной, мы добились прогресса, но все еще имеют долгий путь.
Это была часть 2 постоянной саги, где я пытаюсь использовать угловой серверид.
Присоединяйтесь к мне в следующий раз, когда мы будем работать над рендерингом шаблонов из строк и файлов, частично, используя модуль, который мы закодировали сегодня, node.fs.app.app.
Опять же, весь код из этого блога можно найти на Github => здесь