Как собрать / скомпилировать облачные функции firebase с помощью webpack

Я использую webpack для создания своих облачных функций (несколько причин для этого, например, псевдонимы путей, машинописный текст и некоторые другие конфигурации)

У меня есть свой index.ts файл, а также src папка, содержащая отдельные файлы для каждой функции.

Мой index.ts файл затем экспортирует их вот так

import admin from 'firebase-admin';

admin.initializeApp();

export const func1 = require('./src/func1').default;
export const func2 = require('./src/func2').default;

Проблема с webpack по сравнению с чем-то вроде tsc заключается в том, что он требует весь код из требуемых файлов и объединяет его в индексный файл, что для облачных функций не идеально из-за производительности холодного запуска.

Каким будет правильный способ разбить эти файлы на отдельные и обеспечить хорошую производительность при холодном запуске (т.е. требуется только код для вызываемой функции).

Конфигурация моего веб-пакета для firebase выглядит так

const config = {
  entry: {
    index: path.resolve(__dirname, './index.ts')
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, './dist'),
    libraryTarget: 'commonjs'
  },
  mode: 'production',
  optimization: {
    nodeEnv: 'production',
    splitChunks: {
      chunks: 'all'
    },
    minimize: true,
    minimizer: [
      new ESBuildMinifyPlugin({
        target: 'es2020',
        minifyWhitespace: true,
        minifyIdentifiers: true,
        minifySyntax: true
      })
    ]
  },
  resolve: {
    alias: {
      $tools: path.resolve(__dirname, '../../tools'),
      $types: path.resolve(__dirname, '../../types')
    },
    extensions: ['.tsx', '.ts', '.js', '.mjs', '.json']
  },
  externals: ['firebase-functions', 'firebase-admin'],
  target: 'node',
  module: {
    rules: [
      {
        test: /\.(m?js|ts)$/u,
        exclude: /(node_modules)$/u,
        use: {
          loader: 'esbuild-loader',
          options: {
            loader: 'ts',
            target: 'es2020',
            tsconfigRaw: require('./tsconfig.json')
          }
        }
      }
    ]
  },
  plugins: [new CleanWebpackPlugin(), new ESBuildPlugin()]
};

Какая у вас конфигурация веб-пакета?   —  person Ilja    schedule 29.01.2021

@guillaumeblaquiere добавил это в вопрос   —  person Ilja    schedule 30.01.2021

См. также:  Ошибка подключения к локальному эмулятору функций Firebase из приложения Flutter
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 2
  1. Ilja

    Принцип веб-пакета состоит в том, чтобы преобразовать и оптимизировать JS, минимизировать его и упаковать в один файл (например, для оптимизации загрузки браузера, здесь не тема).

    В вашем случае у вас всего 1 точка входа. Webpack проследит за всеми зависимостями и упакует их в один файл.

    Решение здесь состоит в том, чтобы иметь 2 отдельные / независимые точки входа, и, таким образом, у вас будет 2 выходных файла. Но иногда это бывает скучно, потому что вы хотите совместить какую-то часть кода / инициализации. Это всегда вопрос компромисса

    Мне подходит разделение на разные записи, так как у меня есть некоторые функции, которые полагаются на значительный объем связанных с ними данных json, а другие нет. Я попытался создать отдельную запись для каждой отдельной функции, однако мой файл index.ts по-прежнему включает их все из-за этого, поэтому, по сути, установка нескольких записей просто создает больше файлов в данный момент. person Ilja; 30.01.2021

    Да, у вас не должно быть файла, который ссылается на функцию (ваш индекс), потому что он будет агрегировать данные. Зачем вам этот index.js? Для локального тестирования? person Ilja; 30.01.2021

    Вот как облачные функции firebase ожидают, что пользователи будут их экспортировать. Должен быть индексный файл, который экспортирует / требует другие ваши функции. При строительстве с использованием tsc требуется оставаться там. Теперь я думаю, что мне, возможно, придется проигнорировать этот индексный файл и просто оставить его как js one person Ilja; 31.01.2021

    Плохо, я забыл ваш контекст Firebase Functions … Да, это ограничение firebase. Вы можете попробовать использовать Google Cloud Functions напрямую вместо Firebase, но это создаст неоднородную среду разработки. person Ilja; 31.01.2021

  2. Ilja

    Вот решение, которое я смог приготовить.

    Во-первых, сделайте каждую функцию отдельной записью в webpack, вы можете сделать это вручную или с помощью чего-то вроде этого

    const fs = require('fs');
    const path = require('path');
    
    // Get all functions and store their names in an array, based on filename, use .js instead of .ts if thats your case
    const functions = fs.readdirSync('./src').map(file => file.split('.ts')[0]);
    
    // Add all functions to entries object
    const entries = {};
    functions.forEach(file => {
      entries[file] = path.resolve(__dirname, `src/${file}.ts`);
    });
    
    // Finally add your index file to entries object (if it is not already in src folder together with functions)
    entries.index = path.resolve(__dirname, './index.ts');
    
    // Use this in your webpack congig
    const config = {
     entry: entries,
     // ...
    }
    

    В результате получится что-то вроде этого

    dist/
      func1.js
      func2.js
      index.js
    

    Затем в вашем индексном файле используйте non_webpack_require < / a>, таким образом webpack сохраняет их как require() в скомпилированном коде. Экспортируйте все свои функции, помните, что каждый файл будет в корне скомпилированной папки.

    import admin from 'firebase-admin';
    
    admin.initializeApp();
    
    export const func1 = __non_webpack_require__('./func1');
    export const func2 = __non_webpack_require__('./func2');
    
    

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: