Firebase Cloud Functions 无法识别已转译的 ES5:firebase 未定义

Transpiled ES5 not recognized by Firebase Cloud Functions: firebase is undefined

稍微介绍一下,目前(在我写这篇文章时)Firebase 函数不支持更新版本的节点中的异步和等待等功能。我试图通过将我的代码转换为他们当前支持的节点版本来克服这个问题。

我正在使用 webpack 3 来捆绑我的 react.js 网络应用程序。我设置了两个单独的配置 - 一个用于开发,另一个用于生产。我使用第三个配置作为生产管道上的第二个任务执行,以获取 cloudfunctions.js 并将其吐出到部署目录 functions/index.js 使用 babel 来转换代码,

我没有在 .babelrc 中描述转译要求,而是使用 webpack 将这些细节添加到规则模块内部的选项配置对象中。

我已成功转译代码,但 Firebase 一直抱怨 'firebase' 未定义。我已将此错误的触发范围缩小到导入代码的第一行。

非常感谢任何可以为我指明正确方向的建议。

import functions from ''firebase-functions';

事实上,我已经尝试过 Commonjs(使用 require)并在 ES6 上进行了其他尝试 import/exports。

Package.json:

{
  "scripts": {
  "start":"node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack/dev.config.js",
"build": "cross-env NODE_ENV=production node ./node_modules/webpack/bin/webpack.js --config webpack/prod.config.js"
  },
  "dependencies": {
    "@babel/polyfill": "^7.0.0-beta.40",
    "firebase-admin": "^5.5.1",
    "firebase-functions": "^0.7.3",
  },
  "devDependencies": {
    "@babel/cli": "^7.0.0-beta.40",
    "@babel/core": "^7.0.0-beta.40",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
    "@babel/preset-env": "^7.0.0-beta.40",
    "babel-loader": "^8.0.0-beta.0",
    "babel-preset-react": "^6.24.1",
    "cross-env": "^5.1.3",
    "generate-json-webpack-plugin": "^0.2.2",
    "uglifyjs-webpack-plugin": "^1.1.8",
    "webpack": "^3.10.0",
    "webpack-merge": "^4.1.1"
  }
}

functions.config.js (webpack)

const
    path               = require('path'),
    pkg                = require('../package'),
    GenerateJsonPlugin = require('generate-json-webpack-plugin'),
    UglifyJSPlugin     = require('uglifyjs-webpack-plugin'),
    webpack            = require('webpack');

const externals = [
    'firebase-admin',
    'firebase-functions'
]

const genPackage = () => ({
    name         : 'functions',
    private      : true,
    main         : 'index.js',
    license      : 'MIT',
    dependencies : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: pkg.dependencies[name] || pkg.devDependencies[name] }), {} )
})

module.exports = {
    entry  : [
        '@babel/polyfill',
        path.join(__dirname, '../cloudfunctions.js')
    ],
    output : {
        path     : path.join(__dirname, '../functions/'),
        filename : 'index.js'
},
    module : {
        rules: [
            {
                test    : /\.js$/,
                loader  : 'babel-loader',
                options : 
                    {
                        presets : [
                            [ 
                                '@babel/env',
                                { 
                                    option : { 
                                        targets : { 
                                            node : '6.11.5'
                                        }
                                    }
                                }
                            ]                 
                        ],
                        plugins: [
                            '@babel/plugin-proposal-object-rest-spread'
                        ]   
                    }
                ,
                exclude : /node_modules/
            }
        ]
    },
    externals : externals.reduce( (acc, name) => Object.assign({}, acc, { [name]: true }), {} ),
    plugins   : [
        new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) }),
        new UglifyJSPlugin(),
        new GenerateJsonPlugin('package.json', genPackage())
    ]
}

环境

预期行为

  1. 转译成功。
  2. 成功部署到 firebase

实际行为

转译成功。 在点击 firebase deploy --only functions 命令后继续收到此日志并显示相同的错误:

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...

Error: Error occurred while parsing your function triggers.

ReferenceError: firebase is not defined
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:9040:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.module.exports (C:\Users\Andrew Redican\Compass\functions\index.js:8967:17)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:3687:18)
at __webpack_require__ (C:\Users\Andrew Redican\Compass\functions\index.js:20:30)
at C:\Users\Andrew Redican\Compass\functions\index.js:63:18
at Object.<anonymous> (C:\Users\Andrew Redican\Compass\functions\index.js:66:10)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)

cloundFunctions.js [输入]

let functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

functions/index.js [输出]

  1. 根据我是否包含 Uglify 插件,输出将缩小或正常。
  2. Webpack 也接受@babel/polyfill,所以帮助功能被添加到这个文件中。

我没有包含 outfile,因为 unmifinify 版本有 9049 行代码,而 minified 不清晰。

我试过了

  1. 用过 Babel 6 再用 Babel 7 还是没结果。
  2. 环境配置https://firebase.google.com/docs/functions/config-en
  3. 我试过提供直接硬编码的访问对象。

我显然遗漏了一些东西,但我已经检查了这个 article/repo 好几次了。

其他注意事项

我正在尝试尽可能远离 typescript 和处理 promises 的回调地狱。我也在尝试不直接依赖 npm 来直接 运行 命令,而是利用 webpack。

我能够让 webpack 使用 babel 将代码转换为 functions/index.js。我找到问题了。

使用 webpack 时,请确保将 output.libraryTarget 指定为 'umd'。

下面是 webpack 配置文件:

const
    path               = require('path'),
    pkg                = require('../package'),
    GenerateJsonPlugin = require('generate-json-webpack-plugin');

const
    externals = [
        'firebase-admin',
        'firebase-functions'
    ], 
    genPackage = () => ({
        name    : 'functions',
        private : true,
        dependencies: externals.reduce(
            (acc, name) =>
                Object.assign({}, acc, {
                [name]:
                    pkg.dependencies[name] ||
                    pkg.devDependencies[name]
                }),
            {}
        )
    });

module.exports = {
    entry : [
      'babel-polyfill',
      './cloudfunctions.js'
    ],
    output: {
        path          : path.resolve(__dirname,'../functions'),
        filename      : 'index.js',
        libraryTarget : 'umd'
    },
    module : {
        rules : [
            {
                exclude : /node_modules/,
                loader  : 'babel-loader',
                query   : { 
                    presets : [ 'babel-preset-env' ] 
                }
            }
        ]
    },
    resolve: {
        extensions: ['.js']
    },
    node: {
        fs  : 'empty',
        net : 'empty',
        tls : 'empty'
    },
    externals: externals.reduce(
        (acc, name) => Object.assign({}, acc, { [name]: true }),{}
    ),
    plugins: [
        new GenerateJsonPlugin('package.json', genPackage())
    ]
};

干杯!