Рубрики
Без рубрики

Угловой / узел: Создание инструмента командной строки для генерации проектов Часть 2 – Угловая и ваша файловая система.

Узнайте, как использовать Angularjs для программирования на стороне сервера через этот учебник.

Автор оригинала: Kyle J. Roux.

Примечание: Это часть 2 мультиугольного блога о моем стремлении к использованию угловой для программирования на стороне сервера, предыдущие сообщения:

  • Часть 1 Угловой/узел: Создание инструмента командной строки для генерации проектов

    • Примечание : Код из части 1 понадобится несколько обновлений, которые будут совместимы с кодом из этого поста, но все в его Github Repo это тока и должна работать вместе с кодом ниже. Так что, если вы столкнулись с проблемами с чем-либо в этом посте, будьте уверены, что вы установили Node-NG локально через NPM (который вытащит последний код из GitHub), запустив:
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 => здесь