Статьи

Настройка интерфейсных приложений

Обычно внешние приложения имеют особую конфигурацию, в зависимости от среды. Это могут быть маркеры доступа, URL-адреса API, настройки приложений и т. Д. В течение довольно длительного периода времени я решал эту проблему, выставляя window.envпеременную, заполняемую либо рендерингом сервера, либо плагинами как html-build…, либо просто ссылаясь напрямую <script src="config/my.env.js">, где my.env.jsнеобходимо было обновить до фактического развертывание.

Тратить много времени на бэкэнд и работать с Node.js / CommonJS. Мне понравилась простота configпаттерна и я хотел использовать этот паттерн во внешнем интерфейсе. Это действительно простой и не зависящий от структуры подход.

Конфиг шаблон

Шаблон конфигурации — это то, что я часто использую для приложений Node.js. Это просто папка с index.jsфайлом, содержащая такой код:

var env = process.env.NODE_ENV || 'development';

module.exports = require('./' + env + '.config.js');

Папка содержит такие файлы, development.config.js, staging.config.js, и production.config.jsт.д.

Файлы конфигурации, просто экспортируйте объект с конфигурацией,

var config = {
  connection: 'mongodb://localhost:27017/notifierdb',
  accessToken: '1234',

  hook: {
      url: 'http://localhost:5000/api/notify/',
      token: 'fake-hook-token'
  },

  logentries: {
      token: null
  },

  transport: {
      // ...
  }

  // ...
};

module.exports = config;

Модуль, фактически необходимый для конфигурации, будет requireв configпапке, например:

var request = require('request');
var config = require('../config');

function fetchActions(user, callback) {
  var apiUrl = config.api.url;
  var token = config.api.token;

  request({url: apiUrl + '/actions/' + user, headers: {token: token}, callback);
}

module.exports = fetchActions;

Browserify

Browserify — это препроцессор (или назовем его транспилятором) для javascript. Он охватывает стиль модульности CommonJS и предоставляет популярные npmмодули на сайте клиента. Это просто потрясающий проект (большое спасибо за него), который имеет большой смысл для меня.

С Browserify вы можете писать браузерный javascript так же, как вы делаете это на бэкенде с Node.js. Он реализует require()вызов и объединяет приложение, состоящее из разных модулей, в один, исполняемый в браузере.

Обычно browserifyзапускается не вручную, а с помощью инструментов сборки JS as gruntили gulp.

Я собираюсь принять configшаблон Node.js для внешнего интерфейса с browserify.

Подготовьте конфигурацию

По аналогии с нодовыми приложениями, давайте создадим configпапку внутри нашей jsпапки.

структура конфигурации

index.js Файл точно такой же, как упомянуто выше, файлы конфигурации содержат зависящие от приложения настройки.

В примере с приложением Angular.js, здесь serviceиспользуется поставщик данных,

var config = require('../config');

function drivers ($http) {
  var apiUrl = config.api.url;

  return {
      fetch: function () {
          var url = apiUrl + '/api/drivers';

          return $http.get(url);
      }
  };
}

module.exports = drivers;

Если вы просто попробуете это, это будет работать как очарование … но только для developmentокружающей среды.

Настройка NODE_ENV

Проблема, однако, browserifyне имеет понятия, что помещать в process.env.NODE_ENVпеременную, поскольку она undefineddevelopmentконфигурация всегда выбрана.

К счастью, browserifyархитектура поддерживает так называемые transformsпромежуточные компоненты, способные настраивать поведение браузера. Один из Handly преобразования функции является envify от Хью Кеннеди .

То, что envifyпозволяет сделать, это в основном замена process.env.NODE_ENVопределенной стоимости, например.

if (process.env.NODE_ENV === "development") {
  console.log('development only')
}

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

if ("production" === "development") {
  console.log('development only')
}

Это именно то, что нам нужно, чтобы config/index.jsправильно работать.

Поскольку я использую grunt, я покажу, как интегрировать envifyв рабочий процесс (подход для gulpбудет аналогичным),

var envify = require('envify/custom');

module.exports = function (grunt) {
  grunt.initConfig({
      browserify: {
          dev: {
              files: {
                  'source/build/app.js': ['source/js/app.js']
              },
              options: {
                  browserifyOptions: {
                      debug: true
                  },
                  transform: [envify({
                      NODE_ENV: 'development'
                  })]
              },
          },
          stage: {
              files: {
                  'source/build/app.js': ['source/js/app.js']
              },
              options: {
                  transform: [envify({
                      NODE_ENV: 'staging'
                  })]
              }
          },
          prod: {
              files: {
                  'source/build/app.js': ['source/js/app.js']
              },
              options: {
                  transform: [envify({
                      NODE_ENV: 'production'
                  })]
              }
          }
      },
  // ...
}

Теперь, после запуска grunt build:devили grunt build:prod, он будет заполнять правильное NODE_ENVзначение, а остальная часть переданного приложения будет работать как положено.