0
votes

I am building a simple Hello World function for AWS Lambda/APIGateway and want to incorporate ESLint and Typescript functionality. Normally when I am using Typescript and ESlint, I need the eslint-plugin-import package and need to specify the extensions in my .eslintrc file like so:

  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  }

However, with this monorepo, I am still getting the Unable to resolve path to module 'aws-lambda' error even after those are setup. Here is my repo setup:

apis/
    users/
        dist/ <-- My complied JS code
        node_modules/
        src/
            functions/ <-- My Typescript Lambda functions
        test/ <-- My Jest tests
        .eslintrc <-- My ESLint config
        package.json
        template.yaml <-- My SAM template
        tsconfig.json <-- My Typescript config
        webpack.config.js <-- My WebPack config

Here is my .eslintrc config:

{
  "root": true,
  "env": {
    "es2020": true,
    "mongo": true,
    "node": true,
    "jest": true
  },
  "parser": "@typescript-eslint/parser",
  "extends": [
    "airbnb",
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended" // This will display prettier errors as ESLint errors. Make sure this is always the last configuration.
  ],
  "ignorePatterns": ["dist/", "coverage/", "test/"],
  "parserOptions": {
    "ecmaVersion": 2018,
    "sourceType": "module",
    "ecmaFeatures": {
      "impliedStrict": true
    }
  },
  "rules": {
    "import/extensions": [
      "error",
      "ignorePackages",
      {
        "js": "never",
        "jsx": "never",
        "ts": "never",
        "tsx": "never"
      }
    ],
    "max-len": [
      "error",
      {
        "code": 100,
        "ignoreComments": true,
        "ignoreStrings": true,
        "ignoreTemplateLiterals": true
      }
    ],
    "quotes": ["error", "single", { "allowTemplateLiterals": true }],
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "vars": "all",
        "args": "none"
      }
    ]
  },
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    }
  }
}

Here is my tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "esnext",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist"
  },
  "include": ["src/**/*"],
  "exclude": ["**/*.test.*"]
}

and finally my webpack config:

/* eslint-disable */
const path = require('path');
const { readFileSync } = require('fs');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const { yamlParse } = require('yaml-cfn');
/* eslint-enable */

const conf = {
  prodMode: process.env.NODE_ENV === 'production',
  templatePath: './template.yaml',
};

const cfn = yamlParse(readFileSync(conf.templatePath));
const entries = Object.values(cfn.Resources)

  // Find nodejs functions
  .filter((resource) => resource.Type === 'AWS::Serverless::Function')
  .filter(
    (resource) =>
      (resource.Properties.Runtime && resource.Properties.Runtime.startsWith('nodejs')) ||
      (!resource.Properties.Runtime && cfn.Globals.Function.Runtime)
  )
  .map((resource) => ({
    // Isolate handler src filename
    handlerFile: resource.Properties.Handler.split('.')[0],
    // Build handler dst path
    CodeUriDir: resource.Properties.CodeUri.split('/').splice(1).join('/'),
  }))
  .reduce(
    (resources, resource) =>
      Object.assign(
        resources,
        // Generate {outputPath: inputPath} object
        { [`${resource.CodeUriDir}/${resource.handlerFile}`]: `./src/${resource.CodeUriDir}.ts` }
      ),
    {}
  );

module.exports = {
  entry: entries,
  target: 'node',
  mode: conf.prodMode ? 'production' : 'development',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
    libraryTarget: 'commonjs2',
  },
  devtool: 'source-map',
  plugins: conf.prodMode
    ? [
        new UglifyJsPlugin({
          parallel: true,
          extractComments: true,
          sourceMap: true,
        }),
      ]
    : [],
};
1

1 Answers

0
votes

Try using eslint-import-resolver-typescript instead of the node resolver. It was designed to make eslint-plugin-import understand typescript

https://www.npmjs.com/package/eslint-import-resolver-typescript