简体   繁体   中英

Cannot deploy nest.js project to Google Firebase Functions

NestJs uses ES6, ES7 and ES8, but Firebase Functions is stuck at Node v.6.11.

I tried to write a webpack config file w/ babel to transpile both my files and the node_modules to node v6.11 but I'm not able to complete the deploy due to a syntax error caused by an async function in the @nestjs/common/interceptors/file-fields.interceptor.js file.

⚠  functions[api]: Deployment error.
Function load error: Code in file dist/index.js can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: /user_code/node_modules/@nestjs/common/interceptors/file-fields.interceptor.js:10
        async intercept(context, call$) {
              ^^^^^^^^^

SyntaxError: Unexpected identifier
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:549:28)
    at Object.Module._extensions..js (module.js:586:10)
    at Module.load (module.js:494:32)
    at tryModuleLoad (module.js:453:12)
    at Function.Module._load (module.js:445:3)
    at Module.require (module.js:504:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/user_code/node_modules/@nestjs/common/interceptors/index.js:6:10)

Here's my webpack.config.js file:

'use strict';
const nodeExternals = require('webpack-node-externals');
module.exports = {
    entry: './src/server.ts',
    output: {
        filename: 'index.js',
        libraryTarget: 'this'
    },
    target: 'node',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: [
                    { 
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env',
                                    {
                                        "targets": {
                                        "node": "6.11.1"
                                        }
                                    },
                                    '@babel/stage-0'
                                ]
                            ],
                            plugins: [require('@babel/plugin-transform-async-to-generator')]
                        }
                    }, 
                    {
                        loader: 'ts-loader',
                        options: {
                            transpileOnly: true
                        }
                    }
                ]
            },
            {
                test: /\.js$/,
                use: [
                    { 
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                [
                                    '@babel/preset-env',
                                    {
                                        "targets": {
                                        "node": "6.11.1"
                                        }
                                    },
                                    '@babel/stage-0'
                                ]
                            ],
                            plugins: [require('@babel/plugin-transform-async-to-generator')]
                        }
                    }
                ]
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.tsx', '.js' ]
    },
    externals: [nodeExternals()]
};

My tsconfig.json:

{
  "compilerOptions": {
    "lib": ["es6", "es2015.promise"],
    "module": "commonjs",
    "noImplicitAny": false,
    "outDir": "",
    "sourceMap": true,
    "removeComments": true,
    "noLib": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowJs": true,
    "target": "es6",
    "typeRoots": [
      "node_modules/@types"
    ]
  },
  "include": [
    "src/**/*.ts",
    "spec/**/*.ts"
  ],
  "exclude": [
    "**/*.spec.ts"
  ]
}

What's wrong?

Exactly 3 days ago (after Google Cloud's Next conf) Google just announced the new Node 8 runtime and Firebase Cloud Functions 2.0.0 and Firebase tools to 4.0.0.

Here's what you need to do to get on the Node 8 train:

  1. Upgrade your firebase-functions version to 2.0.0
  2. Upgrade firebase-tools to 4.0.0
  3. Add "engines": { “node": “8” } to your /functions/package.json

More deets here: https://firebase.google.com/docs/functions/manage-functions#set_nodejs_version

Node 6 won't run any code using the async keyword as it doesn't support async functions from ES2017.

I'd recommend trying to use TypeScript for the transpilation of your code, using es6 as a target in your tsconfig.json . It should transpile async functions. Please keep in mind that you might have to load specific polyfills depending on your needs. And you're probably aware of this detail but NestJS specifies Node 8.9+, as documented here :

We follow the Node.js release schedule which recently moved to 8.x as an active LTS version. Therefore, Nest 5 supports >= 8.9.0 as the lowest version now. This shift gaves us sustainable performance boosts thanks to the es2017 target of the TypeScript compilation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM