Absolute Imports with Lambda Functions

tl;dr: netlify-lambda build fails to recognize absolute imports in my project. Is there anything I can do to make netlify functions respect absolute imports?

Repo: GitHub - dyelax/netlify-functions-abs-import: Testing absolute imports with Netlify Lambda Functions

I’m using lambda functions in a react project that uses an absolute import scheme, with src/ as the root (see jsonconfig.json). I’m trying to do server-side rendering, so I need to import the <App /> component in the function:

src/lambda-functions/default.js

import App from '../App.js'
import React from 'react';
import ReactDOMServer from 'react-dom/server';

exports.handler = async (event, context) => {
  const app = ReactDOMServer.renderToString(<App />);

  return {
    statusCode: 200,
    body: app,
  };
};

Absolute imports aren’t working inside the function, so I need to use a relative import for App. This is not ideal, but fine. The bigger issue is that App (and the rest of the project) use absolute imports (e.g. from 'utils.js' instead of from ./utils.js below:

src/App.js

import { testFunc } from 'utils.js';

const App = props => {testFunc()}

export default App;

When I run netlify-lambda build src/lambda-functions, I get the following error:
ModuleNotFoundError: Module not found: Error: Can't resolve 'utils.js' in '<repo-root>/src'.

If I switch to relative imports (e.g. from ./utils.js), it builds fine. But this isn’t feasible as the real app I’m trying to use functions with is large and has absolute imports everywhere.

Is there anything I can do to make netlify functions respect absolute imports?

–-
Full error log:

$ netlify-lambda build src/lambda-functions

netlify-lambda: Building functions
ModuleNotFoundError: Module not found: Error: Can't resolve 'utils.js' in '/Users/coop/programming/tests/netlify-functions-abs-import/src'
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/webpack/lib/Compilation.js:925:10
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/webpack/lib/NormalModuleFactory.js:401:22
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/webpack/lib/NormalModuleFactory.js:130:21
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/webpack/lib/NormalModuleFactory.js:224:22
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/neo-async/async.js:2830:7
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/neo-async/async.js:6877:13
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/webpack/lib/NormalModuleFactory.js:214:25
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/Resolver.js:213:14
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/coop/programming/tests/netlify-functions-abs-import/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js:44:7
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/coop/programming/tests/netlify-functions-abs-import/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/Users/coop/programming/tests/netlify-functions-abs-import/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:67:43
resolve 'utils.js' in '/Users/coop/programming/tests/netlify-functions-abs-import/src'
  Parsed request is a module
  using description file: /Users/coop/programming/tests/netlify-functions-abs-import/package.json (relative path: ./src)
    resolve as module
      /Users/coop/programming/tests/netlify-functions-abs-import/src/node_modules doesn't exist or is not a directory
      /Users/coop/programming/tests/node_modules doesn't exist or is not a directory
      /Users/coop/programming/node_modules doesn't exist or is not a directory
      /Users/coop/programming/node_modules doesn't exist or is not a directory
      /Users/coop/node_modules doesn't exist or is not a directory
      /Users/node_modules doesn't exist or is not a directory
      /node_modules doesn't exist or is not a directory
      looking for modules in /Users/coop/programming/tests/netlify-functions-abs-import/node_modules
        using description file: /Users/coop/programming/tests/netlify-functions-abs-import/package.json (relative path: ./node_modules)
          using description file: /Users/coop/programming/tests/netlify-functions-abs-import/package.json (relative path: ./node_modules/utils.js)
            no extension
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js doesn't exist
            .wasm
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js.wasm doesn't exist
            .mjs
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js.mjs doesn't exist
            .js
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js.js doesn't exist
            .json
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js.json doesn't exist
            .ts
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js.ts doesn't exist
            as directory
              /Users/coop/programming/tests/netlify-functions-abs-import/node_modules/utils.js doesn't exist

Hi @dyelax,

Absolute imports isn’t the default way of doing imports so you would need to configure that. Typically, it’s done in webpack so you could probably create your own webpack config and use it with netlify-lambda as described here: GitHub - netlify/netlify-lambda: Helps building and serving lambda functions locally and in CI environments. Let me know if that helps.

Thanks! This was resolved by adding the following in webpack.config.js and changing my lambda-build script in packages.json to netlify-lambda build src/lambda-functions --config ./webpack.config.js

const path = require('path');

module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  }
};
1 Like