Как упаковать Lambda / Google Cloud Functions без включения всех ненужных зависимостей

Одна вещь, которая мне не нравится в Node, заключается в том, что как только вы добавляете одну require("whatever"), вы получаете тысячи транзитивных зависимостей, которые вызывают require на случай, если код может понадобиться.

var whatever = require('whatever');
if (probablyFalse) {
   whatever.theOnlyFunctionThatIUse(); 
   // ...but `whatever` et al require other libraries which I won't actually use
}

Я хочу создать пакет для развертывания в Google Cloud Functions (и подобных приложениях на Lambda). Мой код импортирует @ google-cloud / datastore, который имеет много транзитивных зависимостей, некоторые из которых имеют двоичные файлы, вычисленный импорт и т. Д. Я не хочу сталкиваться с ограничениями размера пакета или увеличивать время, необходимое для анализа кода Node . Я хочу использовать инструмент упаковки, который встряхивает дерево и компилирует (большую часть) мой код и зависимости в один файл. Я хочу иметь возможность указать, какие библиотеки исключить из index.js, и предоставить только необходимые файлы в node_modules.

Поскольку я компилирую Typescript и использую другие библиотеки в процессе сборки / тестирования / пакета / развертывания, node_modules содержит от 100 до 1000 библиотек, большинство из которых не нужны в производстве.

В идеале я бы хотел построить что-то похожее на:

  • package.json - {"main": "index.js", зависимости: {"@ google-cloud / datastore": "1.4.1"}}
  • index.js - скомпилирован из нескольких файлов TypeScript в моем проекте и большей части кода, который я импортирую из библиотек и транзитивных зависимостей.
  • node_modules - все, но только код, который не включен в index.js, но необходим для запуска приложения.

Я создал простое демонстрационное приложение, чтобы показать, что я пытаюсь сделать (в настоящее время я использую FuseBox):

https://github.com/nalbion/packaged-google-function/blob/master/lib/demo.js

Чтобы исключить @ google-cloud / datastore и его транзитивные зависимости из моего скомпилированного demo.js, я добавил filterFile:

filterFile: file => {
    return !['@google-cloud/datastore'].includes(file.collection.name);
},

Меня смущают строки в выводе:

FuseBox.pkg("@google-cloud/datastore", {}, function(___scope___){
    return ___scope___.entry = "src/index.js";
});

Google Cloud Functions тоже запутались:

TypeError: Cannot read property 'default' of null
    at helloWorld (/user_code/demo.js:10:42)

Для справки, демонстрация работала, пока я не попытался добавить код хранилища данных:

https://github.com/nalbion/packaged-google-function/blob/no-dependencies/lib/demo.js

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

Есть ли в FuseBox аналог для фильтрации пакетов?

Есть ли лучший способ сделать это?

(Edit) Известная проблема с частными репозиториями git:

https://github.com/GoogleCloudPlatform/nodejs-docs-samples/issues/300

Автоматическое развертывание облачных функций Google из Google Cloud Контроль версий


person Nicholas Albion    schedule 05.07.2018    source источник
comment
Могу я спросить вас об облаке Google? Требуется ли какой-либо дополнительный доступ / файлы для работы с ведром?   -  person J A S K I E R    schedule 05.07.2018


Ответы (1)


Вы будете делать слишком много работы без необходимости.

Облачные функции Google автоматически обрабатывают зависимости за вас, устанавливая их на сервере с помощью npm после развертывания (при условии, что зависимости указаны в вашем package.json). Он не загружает содержимое node_modules. Не пытайтесь создать материализованную версию своих зависимостей, если вы действительно не хотите, чтобы GCF автоматически устанавливал их из npm.

person Doug Stevenson    schedule 05.07.2018
comment
Это влияет на время запуска? Когда приходит первый запрос утром, нужно ли GCF загружать из 10 000 репозиториев git, а затем должен ли Node их анализировать? Я предполагаю, что было бы быстрее, если бы был 1 первичный файл, который был потрясен деревом и, следовательно, намного меньше кода, а в node_modules уже было все необходимое. - person Nicholas Albion; 05.07.2018
comment
Документы по этой ссылке говорят, что если вы развертываете через gcloud .... Я пытался развернуть, используя свой собственный JS-скрипт и REST API: cloudfunctions.projects.locations.functions.create / patch. Я не думаю, что GCF установит deps, когда я так делаю. - person Nicholas Albion; 05.07.2018
comment
Установка происходит после развертывания, до того, как будет обработан первый запрос. Фактически, я никогда не слышал, чтобы кто-нибудь говорил, что этот период времени особенно велик. Я сильно подозреваю, что gcloud использует для развертывания те же общедоступные API, что и все остальные. - person Doug Stevenson; 05.07.2018
comment
Уважают ли они package-lock.json? Они упоминают частные модули, но разве мне не нужно предоставлять SSH-ключ для загрузки из частного репозитория BitBucket? "my-module": "bitbucket:nalbion/my-module#develop", - person Nicholas Albion; 05.07.2018
comment
Я не знаю. Похоже, вы собираетесь задать совершенно другой вопрос о SO. - person Doug Stevenson; 05.07.2018
comment
Однако я считаю, что package-lock.json - это концепция npm, поэтому она, вероятно, зависит от версии npm, используемой на стороне облачных функций. - person Doug Stevenson; 05.07.2018
comment
Известная проблема с частными репозиториями git: github.com/GoogleCloudPlatform/nodejs-docs -samples / issues / 300 stackoverflow.com/questions/47643386/ - person Nicholas Albion; 05.07.2018