serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack
MIT License
1.72k stars 417 forks source link

Cannot read property 'path' of undefined #434

Open yankeeinlondon opened 6 years ago

yankeeinlondon commented 6 years ago

I have several handler functions in the /lib/handlers directory and my serverless.yml file correctly points to them. After adding serverless-webpack I am able to do a full deploy or a function deploy. In both cases I get the error:

Cannot read property 'path' of undefined

When turning on debugging I can see the following steps are completed before the error is throw:

Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command create
Serverless: Load command install
Serverless: Load command package
Serverless: Load command deploy
Serverless: Load command deploy:function
Serverless: Load command deploy:list
Serverless: Load command deploy:list:functions
Serverless: Load command invoke
Serverless: Load command invoke:local
Serverless: Load command info
Serverless: Load command logs
Serverless: Load command login
Serverless: Load command logout
Serverless: Load command metrics
Serverless: Load command print
Serverless: Load command remove
Serverless: Load command rollback
Serverless: Load command rollback:function
Serverless: Load command slstats
Serverless: Load command plugin
Serverless: Load command plugin
Serverless: Load command plugin:install
Serverless: Load command plugin
Serverless: Load command plugin:uninstall
Serverless: Load command plugin
Serverless: Load command plugin:list
Serverless: Load command plugin
Serverless: Load command plugin:search
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command rollback
Serverless: Load command rollback:function
Serverless: Load command webpack
Serverless: Load command invoke
Serverless: Load command invoke:stepf
Serverless: Invoke deploy:function
Serverless: Invoke webpack:validate

Further, the webpack.config.js file in the packages root folder (along with serverless.yml) is:

const nodeExternals = require("webpack-node-externals");
const slsw = require("serverless-webpack");

module.exports = async () => {
  return {
    entry: slsw.lib.entries,
    target: "node",
    externals: [nodeExternals()],
    mode: slsw.lib.webpack.isLocal ? "development" : "production"
  };
};

This is pretty much boilerplate from the docs. Further my config in the serverless.yml is:

service: vue-components-services
plugins:
  - serverless-webpack
  - serverless-pseudo-parameters
  - serverless-step-functions
package:
  individually: true
  excludeDevDependencies: false
  browser: false
  includeModules: true
custom:
  stage: '${opt:stage, self:provider.stage}'
  region: '${opt:region, self:provider.region}'
  webpack:
    webpackConfig: webpack.config.js
    includeModules: true
    packager: yarn

Note I have alternated npm and yarn as the packager but both produce the same results. I am using the following versions:

sls: 1.30.0 node: 8.11.3 os: macOS 10.13.6 cloud: AWS serverless-webpack: 5.2.0 webpack: 4.16.5 webpack-node-externals: 1.7.2

Finally, here is the stack-trace of the error:

TypeError: Cannot read property 'path' of undefined
    at webpackConfig._.map.entryFunc (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/lib/validate.js:214:56)
    at arrayMap (/Users/ken/mine/oss/vue-components-services/node_modules/lodash/lodash.js:639:23)
    at Function.map (/Users/ken/mine/oss/vue-components-services/node_modules/lodash/lodash.js:9554:14)
    at processConfig (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/lib/validate.js:208:32)
    at ServerlessWebpack.validate (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/lib/validate.js:228:14)
From previous event:
    at Object.webpack:validate:validate [as hook] (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/index.js:157:10)
    at BbPromise.reduce (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:390:55)
From previous event:
    at PluginManager.invoke (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:390:22)
      at PluginManager.spawn (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:408:17)
    at ServerlessWebpack.BbPromise.bind.then (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/index.js:108:51)
From previous event:
    at Object.before:deploy:function:packageFunction [as hook] (/Users/ken/mine/oss/vue-components-services/node_modules/serverless-webpack/index.js:108:10)
    at BbPromise.reduce (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:390:55)
From previous event:
    at PluginManager.invoke (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:390:22)
    at PluginManager.run (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/classes/PluginManager.js:421:17)
    at variables.populateService.then.then (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/Serverless.js:157:33)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)
From previous event:
    at Serverless.run (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/lib/Serverless.js:144:8)
    at serverless.init.then (/Users/ken/mine/oss/vue-components-services/node_modules/serverless/bin/serverless:43:50)
    at <anonymous>
yankeeinlondon commented 6 years ago

This is the specific line in serverless-webpack which it is failing on:

 config.output.path = path.join(config.output.path, compileName);
yankeeinlondon commented 6 years ago

Based on this error I thought maybe I needed to explicitly state an output directory so I included the following:

output: {
  libraryTarget: "commonjs",
  path: path.resolve(__dirname, ".webpack"),
  filename: "[name].js"
}

Which is again straight out of the docs. As you may be able to tell, I'm no expert on webpack but I'm trying to follow the docs as closely as possible.

yankeeinlondon commented 6 years ago

Finally as a desperate step, I introduced ts-loader as the source files are actually TS. That changed the webpack.config.js to:

const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");

module.exports = async () => {
  return {
    entry: slsw.lib.entries,
    resolve: {
      extensions: [".js", ".json", ".ts", ".tsx"]
    },
    output: {
      libraryTarget: "commonjs",
      path: path.resolve(__dirname, ".webpack"),
      filename: "[name].js"
    },
    target: "node",
    externals: [nodeExternals()],
    mode: slsw.lib.webpack.isLocal ? "development" : "production",
    module: {
      rules: [
        {
          test: /\.ts(x?)$/,
          use: [
            {
              loader: "ts-loader"
            }
          ]
        }
      ]
    }
  };
};

Still same error.

HyperBrain commented 6 years ago

Hi @ksnyde , can you check if you specified the handler property of your functions correctly? If they are located in a subfolder, you should specify them as subdir/myhandler.handlerfunc without any leading ./.

hassankhan commented 5 years ago

Hi @ksnyde, is this still an issue for you? I have a similar setup (TypeScript + Webpack) and I don't seem to have the same issue...

ariel-frischer commented 3 years ago

I am getting this same issue with TS, Node, and Serverless Webpack. Not only is config.output.path undefined but the whole config is an empty object {}. Something with the webpackConfig path in the serverless.yml is changing when I add some TS plugin (I've tested with both serverless-plugin-typescript and @kingdarboja/serverless-plugin-typescript). It says it cannot find webpackConfig path looking in the .build folder when TS plugin is enabled, If I change the relative path to outside the .build folder I will get this path undefined error. If I remove TS plugin and use the normal webpack path I will also get an empty config with the path undefined error. I'm using TsconfigPathsPlugin as well as awesome-typescript-loader in my webpack config I don't know if that is causing the issue. I've posted more of my details in the serverless forums here: https://forum.serverless.com/t/serverless-plugins-just-keep-giving-new-errors/14168

ariel-frischer commented 3 years ago

Update: Finally got passed this error, basically my config in webpack was an async function that returned a config object. I changed it into just a regular config object and it started parsing correctly!

alexbondify commented 3 years ago

resolved by changing from module.exports to exports