Serverless-webpack: Skip webpack on a per function basis

Created on 19 Oct 2017  路  23Comments  路  Source: serverless-heaven/serverless-webpack

This is a Feature Proposal

Description

I have a use case where in the same project I need to mix javascript and python lambda functions. The use case is I have a custom cloudformation resource written in python which I want to deploy before I use it in the resources section.

I think it would be useful to be able to skip this plugin on a perfunction basis.

For example

functions:
  pthon_func:
    runtime: python2.7
    webpack: false
feature

Most helpful comment

I'm trying to use legacy python codebase in a typescript application and I've been banging my head against the wall with this issue.

I found hacky workaround for my usecase using webpack config that I wanted to share. It even works with serverless-python-requirements.

Here's the relevant parts from serverless.yml:

plugins:
  - serverless-webpack
  - serverless-python-requirements # optional

# I needed this to get serverless-python-requirements working:
package:
  artifact: .serverless/<service name>.zip

functions:
  python:
    handler: python.handler
    runtime: python3.7
  node:
    handler: node.handler
    runtime: nodejs8.10

With webpack I needed to exclude python scripts from webpack entry first so they don't cause errors:

// webpack.config.js

const path = require('path');
const slsw = require('serverless-webpack');

const entries = {};

Object.keys(slsw.lib.entries).forEach(
  key => {
    if (!slsw.lib.entries[key].match(/\.py$/)) {
      entries[key] = ['./source-map-install.js', slsw.lib.entries[key]]
    }
  }
);

module.exports = {
  entry: entries,
  target: 'node',
  ...
};

Then I installed copy-webpack-plugin and used it to copy my python source files as is to the webpack output folder.

// webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  ...
  plugins: [
    new CopyPlugin([
      './*.py'
    ])
  ],
}

All 23 comments

MS recently started with Java support for Azure. So it seems that more and more providers support other languages than JS.

So the least instrusive approach to add the feature would be just to check if function.runtime || provider.runtime results in anything that matches /nodejs/. That will at least catch all AWS cases if we put it into a condition like provider.name === 'aws'.

Imo this should be sufficient for a first approach. As soon as there is any more in common (like the runtime property) for other providers, we can think of supporting them too.

@johnf What do you think? Can you try to change the PR to this minimal approach, and use the condition NOT in the index, but in the compile/deploy steps where the entries array is reverse-mapped to functions again. Additionally you should rebase to the cuirrent master as there is the extensisbility PR already merges that changes the internal lifecycles to be extensible for plugin authors who want to plug into the serverloess-webpack plugin.

@HyperBrain Have made some changes to #256

@johnf Thanks 馃憤 . I'll have a look later.

@johnf Sorry. I completely forgot about this.

I'll do the 4.1.0 release today. This will become part of 4.1.1 as it would block the 4.1.0 right now.

@HyperBrain any updates here? I am looking forward to get this functionality. Thanks

@XBeg9 It seems we need some additional tests and maybe corrections in the pending PR. Accoring to this comment https://github.com/serverless-heaven/serverless-webpack/pull/256#issuecomment-359255918 the provided solution does not seem to be complete.

@HyperBrain I will try to help.

May I ask what is the latest on this issue? I too am looking forward to getting this functionality into the serverless framework

Just found this issue and wanted to share my current use case as it is slightly different. I would love to user webpack only on a subset of functions. I currently porting some legacy functions into the serverless repo where all other functions don't need webpack. I would like to avoid to bundle those as well.

Hi @Stereobit . You should use webpack (and sls-webpack), regardless, if your functions need to be transpiled. the reason for that is, that the plugin does packaging much better than serverless, i.e. it only packages dependencies that are really needed.
Whole bundling is not necessary and you should set custom: webpack: includeModules: true. Then all external node modules won't be bundled (as long as you use node-externals.

If you use the standard serverless packaging it will bundle _ALL_ modules you have installed which bloats the packages.

Are there any updates on this? I am also trying to mix nodejs and python functions in one serverless project.

Any updates on this? Is there any possibility for this?

I'm trying to use legacy python codebase in a typescript application and I've been banging my head against the wall with this issue.

I found hacky workaround for my usecase using webpack config that I wanted to share. It even works with serverless-python-requirements.

Here's the relevant parts from serverless.yml:

plugins:
  - serverless-webpack
  - serverless-python-requirements # optional

# I needed this to get serverless-python-requirements working:
package:
  artifact: .serverless/<service name>.zip

functions:
  python:
    handler: python.handler
    runtime: python3.7
  node:
    handler: node.handler
    runtime: nodejs8.10

With webpack I needed to exclude python scripts from webpack entry first so they don't cause errors:

// webpack.config.js

const path = require('path');
const slsw = require('serverless-webpack');

const entries = {};

Object.keys(slsw.lib.entries).forEach(
  key => {
    if (!slsw.lib.entries[key].match(/\.py$/)) {
      entries[key] = ['./source-map-install.js', slsw.lib.entries[key]]
    }
  }
);

module.exports = {
  entry: entries,
  target: 'node',
  ...
};

Then I installed copy-webpack-plugin and used it to copy my python source files as is to the webpack output folder.

// webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
  ...
  plugins: [
    new CopyPlugin([
      './*.py'
    ])
  ],
}

Any updates on this?

Thanks for sharing the workaround, @hyrsky! While it did not work for me (still getting some errors), I'd like to point out using different runtimes in same service is very much valid use case also outside migration/legacy codebases: For example, there are a lot of analysis/math libraries for Python so it makes sense use Python runtime for those while using TypeScript for others.

I also tried the workaround but it did not work. Webpack doesn't seem to fire before I get a handler not found error:

No matching handler found for 'myPythonModule.myPythonFile'

I uploaded the project where I'm using the workaround here: https://github.com/hyrsky/pankkilinkki.

It still works for me. I hope this helps!

@hyrsky Thanks, that helped a lot. I had missed the explicit setting of package: artifact: ...

Hi, anyone had this working with serverless offline? all works when deployed but offline it doesnt seem to invoke the python handler and then for some reason triggers a rebuild of webpack which fails and destroys the .webpack folder so none of the functions then work after you have attempted to invoke a python one eeeeeeeeeeeeeeeeeeeeeeeeeeeek

I've added some options to control which functions will and will not be built using Webpack.

Please review when you have some time.

Thanks!

Any updates here? it's almost 4 years and it's a shame that we cannot avoid Webpack running on certain functions

Available since 5.3.3, thanks to https://github.com/serverless-heaven/serverless-webpack/pull/579 only node runtime are checked.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

heri16 picture heri16  路  4Comments

serverlesspolska picture serverlesspolska  路  4Comments

jmparsons picture jmparsons  路  5Comments

deftomat picture deftomat  路  5Comments

timoangerer picture timoangerer  路  3Comments