Я пытаюсь написать общую конечную точку javascript для служебных методов, которые будут совместно использоваться клиентом и сервером.

Я прочитал вокруг, но я изо всех сил пытаюсь понять понятия.

Я думал о том, чтобы отправить его как строку и использовать eval? Я не уверен, что лучшая практика для этого.

Пока у меня есть:

Клиентская служба, для которой нужны скрипты.

angular.module('passionForgeApp').service('Utils', function ()
{
    //TODO Load these from the server side utlity module.
}

Экспорт утилиты узла

'use strict';

var Utility = function(){};

Utility.isASCII = function (str) {
    return /^[\x00-\x7F]*$/.test(str);
};

Utility.isAlphaNumeric = function(str) {
    var code, i, len;
    for (i = 0, len = str.length; i < len; i++) {
        code = str.charCodeAt(i);
        if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
            return false;
        }
    }
    return true;
};

module.exports = Utility;

Конечная точка Node Express
Это где я потерян.

//TODO Bad path.
var utility = require('./../../components/utility');

// Gets a list of Commonjss
exports.utility = function(req, res) {


    //send utility????
    //Stuck here, sends {} to browser.

    res.json(utility);

};

ИЗМЕНИТЬ

По запросу выложен скрипт browserify.

Это загружается браузером, который я вижу в журналах сети.

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var Utility = function(){};

Utility.isASCII = function (str) {
    return /^[\x00-\xFF]*$/.test(str);
};

Utility.isAlphaNumeric = function(str) {
    var code, i, len;
    for (i = 0, len = str.length; i < len; i++) {
        code = str.charCodeAt(i);
        if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
            return false;
        }
    }
    return true;
};

module.exports = Utility;

},{}]},{},[1]);

Моя проблема в том, что я не знаю, как его использовать.

В моем контроллере я пытался, console.log(Utility); Затем я попытался потребовать («Утилита»).

Ничего, не определено. : - /

Изменить

Полная реализация объединения общего кода на стороне сервера на стороне клиента

1
Oliver Dixon 18 Дек 2015 в 22:44

3 ответа

Лучший ответ

Если это ваша структура папок

/ root
    / client
        - client.js
    / server
        - server.js
    / shared
        - utility.js

На вашем сервере (node.js) вам «нужны» такие файлы

var server = require('server.js');
var utility = require('utility.js');

В вашем браузере вам нужны такие файлы

<script src="client.js" type="text/javascript">

Node.js имеет другую систему модулей, чем браузер. Основными из них являются RequireJS и CommonJS (узел require()), и они несовместимы друг с другом.

Browserify - это утилита, которая преобразует модуль CommonJS или RequireJS в совместимый с браузером (в противном случае это не так). Другими словами, он «связывает» все файлы, которые когда-либо требуются () файлом (рекурсивно), и объединяет их все в один файл, используемый браузером.

Итак, если вы хотите иметь возможность использовать один и тот же файл в node.js и браузере, начните с его кодирования (стиль node.js) с помощью require () s, если хотите.

// File utility.js
var a = require('lodash')
var b = require('myotherlib')
module.exports.a = function(a){ } //etc.

Вы можете использовать его в узле

var utility = require('utility.js');

Затем вы используете утилиту browserify.

browserify utility.js -o utility-bundled.js

Затем вы можете использовать его в своем браузере!

<script src="utility-bundled.js" type="text/javascript"/>
<script src="angular.js" type="text/javascript"/>
<script src="controllers.js" type="text/javascript"/>
<script src="app.js" type="text/javascript">

Browserify "browserifies" модули для использования в браузере, потому что в противном случае они не.

- РЕДАКТИРОВАТЬ 1

Это сделает вашу служебную библиотеку «глобальной». Хотя, если вы хотите иметь возможность «импортировать» его с помощью следующего синтаксиса:

angular.module('passionForgeApp').service('Utils', function ()
{
    //TODO Load these from the server side utlity module.
}

Вы можете настроить ocLazyLoad. Это очень хорошая библиотека для определения ленивых внешних файлов.

«Ленивая загрузка», это означает, что она будет загружать библиотеку только тогда, когда вы явно запросите ее.

Если вы используете этот подход, вы можете удалить

<script src="utility-bundled.js" type="text/javascript"/>

Из вашего index.html. И вы должны настроить ocLazyLoad

angular.module('app', ['oc.lazyLoad']).config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
  $ocLazyLoadProvider.config({
    modules : [{
        name : 'Utility',
        files : ['utility-bundled.js']
    }]
  });
}]);

Затем вы можете использовать его в модулях, которые в нем нуждаются, в режиме ленивой загрузки.

angular.module('MyController', ['$ocLazyLoad', function(ocLazyLoad){
    ocLazyLoad.load('Utility');
}]
1
Ludovic C 18 Дек 2015 в 21:22

ИМО это не должно быть так сложно. Если вы используете browserify или пакет для своего интерфейса, вы можете сделать это. Сначала это может быть сложно, но оно того стоит.

структура проекта

/client
    main.js
    /components
        /utility
            utility.module.js

/server
    controller.js

/utilities <- put your code that is shared between server/client here
    Utility.js

< Сильный > клиент / компоненты / утилиты / utility.module.js

module.exports = angular
                    .module("app.utility")
                    .factory("Utility", require(__dirname + "/../../utilities/Utility.js");

< Сильный > утилиты / Utility.js

module.exports = {
    toASCII: function() { //do stuff in angular and express }
};

client / main.js (здесь вам нужны все ваши компоненты, это точка входа в браузер)

require("angular")
    .module("app" [
        "app.utility"
    ]);

    require( <% path to utility.module.js %>);

server / controller.js (вы можете использовать свой модуль, как и следовало ожидать)

var util = require( <% path to Utility.js %>);
util.toASCII(); //do something        
4
Daniel Lizik 18 Дек 2015 в 20:56

Еще один способ сделать это - записать свой служебный модуль в узел и использовать browserify, чтобы сделать его работоспособным на узле или в браузере.

Browserify добавит код в начало вашего файла, чтобы проверить, есть ли объект module.exports или объект окна. Затем он убедится, что когда код выполняет операторы require и module.exports работают.

С помощью просмотра кода вы можете использовать функции утилиты в браузере, включив их в теги html-скрипта.

Это должно быть безопаснее, чем использование eval ().

Обновить

Я сделал пример. Я добавил требование к подчеркиванию и моменту только для того, чтобы показать работу утверждений. Вы не нуждаетесь в них все же.

Сделайте файл с именем myUtility.js и добавьте это

var _ = require('underscore');
var moment = require('moment');

function now (format) {
    var time;
    var dFormat = 'YYYY-MM-DD hh:mm:ss a';
    format = format || dFormat;

    try {
        time = 'TIME:\t' + moment().format(format);
    }catch (err) {
        time = 'TIME:\t' + moment().format(dFormat);
    }finally{
        return time;
    }

}

function isAlphaNumeric(str) {
    var code, i, len;
    return _.every(str, function (letter, i) {
        code = str.charCodeAt(i);
        console.log('code: ' + code);
        if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
            return false;
        }
    });
}

var myutil = {
    now: now,
    isAlphaNumeric: isAlphaNumeric,
};

module.exports = myutil;

Запустите эти команды:

npm install browserify
npm install underscore
npm install moment
browserify myUtility.js --s myutil -o myutil.js

Приведенная выше команда browserify создает файл myutil.js. Добавьте это в ваш index.html

<script src="/path/to/myutil.js"></script>

Добавьте это в свой контроллер, войдите на свою страницу и проверьте вывод консоли:

console.log(myutil)
var isAlphaNumeric = myutil.isAlphaNumeric;
console.log('try cat: ' + isAlphaNumeric('cat'));
console.log('try 123cat123: ' + isAlphaNumeric('123cat123'));
console.log('try ca?t: ' + isAlphaNumeric('ca?t'));

Вывод показывает, что вы используете свою функцию сейчас в браузере с экспортом модуля и требуете операторов в файле.

Также коды ascii нуждаются в корректировке. Я считаю, что вы хотите проверить, находится ли буква в любом из диапазонов с || вместо того &&.

TIME:   2015-12-18 05:13:00 pm
code: 99
try cat: false
code: 49
try 123cat123: false
code: 99
try ca?t: false

Когда я просмотрел вашу функцию и добавил ее в index.html, я получил неправильные ответы в консоли. Изменение символьной логики исправило это так, что если код не входит ни в одну из групп, он не возвращает true:

if (
    (code > 47 && code < 58) || // numeric (0-9)   false to true
    (code > 64 && code < 91) || // upper alpha (A-Z) false to true
    (code > 96 && code < 123)   // lower alpha (a-z)
) { 
    return true;
}
1
curtwphillips 19 Дек 2015 в 00:19