簡體   English   中英

如何使用 webpack 構建/編譯 firebase 雲函數

[英]How to build / compile firebase cloud functions with webpack

我正在使用 webpack 來構建我的雲函數(有幾個原因,如路徑別名、typescript 和其他一些配置)

我有我的index.ts文件以及包含每個 function 的單獨文件的src文件夾。

我的index.ts文件然后像這樣導出它們

import admin from 'firebase-admin';

admin.initializeApp();

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

tsc之類的東西相比,webpack 的問題在於它需要所需文件中的所有代碼並將其捆綁在索引文件中,由於冷啟動性能,這對於雲函數來說並不理想。

將這些文件拆分成單獨的文件並確保良好的冷啟動性能的正確方法是什么(即只需要調用 function 的代碼)。

我的 webpack 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()]
};

這是我能夠烹制的解決方案。

首先,讓每個 function 在 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 ,這樣 webpack 在編譯代碼中將它們保持為require() 導出所有函數,請記住每個文件都位於已編譯文件夾的根目錄中。

import admin from 'firebase-admin';

admin.initializeApp();

export const func1 = __non_webpack_require__('./func1');
export const func2 = __non_webpack_require__('./func2');

webpack的原理是對JS進行改造優化,將其最小化打包成一個文件(以瀏覽器下載優化為例,不在此列)。

在您的情況下,您只有 1 個入口點。 Webpack 會跟隨所有的依賴包到同一個文件中。

這里的解決方案是有 2 個單獨/獨立的入口點,這樣你將有 2 個 output 文件。 但有時這樣做很無聊,因為您想共享代碼/初始化的某些部分。 這總是一個權衡的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM