How to use more than 1 set of rules in extends in eslint yaml file? - node.js

If I have
env:
commonjs: true
es6: true
node: true
extends:
- plugin:mocha/recommended
...
I get no error, i.e. linting passes with
eslint .
but if I try and add in eslint:recommended in addition to the mocha one, i.e.
env:
commonjs: true
es6: true
node: true
extends:
- eslint:recommended
- plugin:mocha/recommended
...
I get loads of errors as the mocha one isn't applied
71:3 error 'it' is not defined no-undef <-- from the mocha tests
How can I have both recommendations in a yaml file?

This is nothing to do with using a YAML file, and the Mocha plugin is being applied in both cases. The first linting passes because, without eslint:recommended, the rule no-undef is not enabled. For example, given the following basic setup:
temp/
node_modules/
.eslintrc.yml
package.json
package-lock.json
test.js
Where test.js contains:
describe("something",function () {
it("should pass linting", function () {});
});
and .eslintrc.yml contains:
extends:
- plugin:mocha/recommended
then linting passes. But if I just add that one rule:
extends:
- plugin:mocha/recommended
rules:
no-undef: error
then linting fails with:
path/to/temp/test.js
1:1 error 'describe' is not defined no-undef
2:3 error 'it' is not defined no-undef
✖ 2 problems (2 errors, 0 warnings)
Per the configuration docs, you need to set the environment for the globals to be defined; for example, the following configuration is back to passing:
env:
mocha: true
extends:
- plugin:mocha/recommended
rules:
no-undef: error
Now you can enable the full suite of recommended rules and still pass linting:
env:
mocha: true
extends:
- eslint:recommended
- plugin:mocha/recommended

Related

How to include static files into the lambda package with AWS SAM esbuild?

I have a NodeJS AWS Lambda function which generates an e-mail based on a html template file (emailTemplate.html). I started building my lambdas with esbuild via SAM. Now I wonder how I can configure SAM/esbuild to include this file into my lambda package.
This is the SAM template configuration for the lambda:
EmailNotificationFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./lambdas-node/email-notifications/
Handler: daily-summary.handler
Timeout: 120
MemorySize: 512
Runtime: nodejs16.x
Metadata:
BuildMethod: esbuild
BuildProperties:
Sourcemap: true
EntryPoints:
- daily-summary.ts
In my application code, I read the file from the local file system:
fs.readFileSync("./emailTemplate.html", "utf-8")
The html file is small so I'd like to stick to this minimalistic approach. I can always fetch the file from S3 or package it in a layer but I prefer not to go there.
Ok, so basically ESBuild's file loader is the way to go. ESBuild will replace the import with a reference to the file and copy over the file to the result bundle. (That's exactly what I wanted.)
This behaviour seems rather specific to ESBuild and will not work with the regular tsc compiler. So I replaced my build step to typechecking with tsc and transpiling with esbuild (see below)
I added an import to the html file to my code. This will ESBuild trigger to do something with this file.
import emailTemplateHtmlUrl from "./emailTemplate.html";
To keep the typechecker happy, I added also a types.d.ts file (mind the d.ts extension)
declare module '*.html' {
const value: string;
export default value
}
And then I added the Loader to my SAM template so that ESBuild will copy over html files and reference them in the import:
EmailNotificationFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./lambdas-node/email-notifications/
Handler: daily-summary.handler
Timeout: 120
MemorySize: 512
Runtime: nodejs16.x
Metadata:
BuildMethod: esbuild
BuildProperties:
Sourcemap: true
Loader:
- .html=file
EntryPoints:
- daily-summary.ts
And finally, my new test command looks now like this:
tsc --noEmit
npx esbuild daily-summary.ts --outdir=. --loader:.html=file --platform=node
--bundle
mocha *.spec.js

Does an extended ESLint configuration overwrite the base configuration's plugins?

Say you have a base ESLint config like this:
# .eslintrc.base.yml
extends:
- "eslint:recommended"
- "plugin:#typescript-eslint/recommended"
parser: "#typescript-eslint/parser"
plugins:
- "#typescript-eslint"
If I then have a child config that extends from the base above:
# .eslintrc.yml
extends:
- "../../.eslintrc.base.yml"
plugins:
- "next"
Will this child config merge the plugins, producing something like this?
plugins:
- "#typescript-eslint"
- "next"
Or will it overwrite the base config's plugins, like this?
plugins:
- "next"

Rules do not work in my gitlab-ci, why include file is ignored?

part of my gitlab-ci.yaml looks like that
include:
# Base templates
- '/templates.yml'
envsubst:
image: ${K8S_DEPLOY_IMAGE}
stage: tests
rules:
- <<: *if-commit
when: on_success
tags:
- k8s
script:
- envsubst --version
in this case *if-commit rule is:
.if-commit: &if-commit
if: '$CI_COMMIT_BRANCH'
this rule exists in my templates.yaml file and "include" contains this file in gitlab-ci as you see
gitlab says "yaml invalid", but if rule (which templates.yaml contains) will be in gitlab-ci, everything goes well and yaml is valid
so, include for some reasons does not work and "include" ignores my rules

Found errors in your .gitlab-ci.yml: unknown keys in `extends`

My code for the pipeline is:
include:
- template: Terraform/Base.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
stages:
- init
- validate
- build
- deploy
init:
extends: .init
validate:
extends: .validate
build:
extends: .build
deploy:
extends: .deploy
dependencies:
- build
The error message I'm getting is:
Found errors in your .gitlab-ci.yml:
init: unknown keys in extends (.init)
You can also test your .gitlab-ci.yml in CI Lint
Is the code you shared for your .gitlab-ci.yml only a snippet?
Where do you define your .init, .validate, .build, and .deploy job templates?
The pipeline template Terraform/Base.gitlab-ci.yml that you inherit from only has the following jobs defined that you can extend:
.terraform:fmt
.terraform:validate
.terraform:build
.terraform:deploy
.terraform:destroy
You can make use of https://gitlab.com/<group>/<project>/-/ci/lint to validate the syntax of your .gitlab-ci.yml file.

How to setup serverless.yml and webpack.config for a multiple-runtime AWS Lambda service

I want to deploy AWS Lambda functions with Node8.10 and Ruby2.5 runtimes from one serverless.yml file.
I set up the following folder structure, with /node and /ruby holding my respective handlers.
-/nodeRubyLambdas
-/node
-handler.js
-package.json, package-lock.json, /node_modules
-/ruby
-rubyRijndaelEncryption.rb
-Gemfile, Gemfile.lock, /vendor
-serverless.yml
-webpack.config.js
-package.json for serverless-webpack
Here is my serverless.yml
service: nodeRubyLambdas
plugins:
- serverless-webpack
- serverless-offline
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
provider:
name: aws
stage: dev
region: us-west-2
iamRoleStatements:
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource: "*"
package:
individually: true
functions:
nodeMain:
handler: node/handler.main
runtime: nodejs8.10
events:
- http:
path: main
method: get
package:
individually: true
rubyEncryption:
handler: ruby/rubyRijndaelEncryption.lambda_handler
runtime: ruby2.5
environment:
RIJNDAEL_PASSWORD: 'a string'
package:
individually: true
My webpack configuration: (This is the base example, I just added the bit to ignore ruby files when I got my first error.)
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
module.exports = {
entry: slsw.lib.entries,
target: "node",
// Generate sourcemaps for proper error messages
devtool: 'source-map',
// Since 'aws-sdk' is not compatible with webpack,
// we exclude all node dependencies
externals: [nodeExternals()],
mode: slsw.lib.webpack.isLocal ? "development" : "production",
optimization: {
// We do not want to minimize our code.
minimize: false
},
performance: {
// Turn off size warnings for entry points
hints: false
},
// Run babel on all .js files and skip those in node_modules
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
include: __dirname,
exclude: [/node_modules/, /\.rb$/]
}
]
}
};
Fail #0:
[Webpack Compilation error] Module parse failed
Fail #1:
Basically, webpack assumes all functions are .js and tries to package them as such. Based off this suggestion, I forced my entry point in webpack config to be my handler.js
module.exports = {
entry: "./node/handler.js",
target: "node",
...
This packages ONLY the Node Lambda. An empty placeholder for the Ruby Lambda is created on AWS.
Fail #2:
I commented out webpack from serverless.yml and added include and exclude statements in the functions package options.
functions:
nodeMain:
package:
individually: true
include:
- node/**
- handler.js
exclude:
- ruby/**
- rubyLambda/**
rubyEncryption:
package:
individually: true
include:
- vendor/**
- rubyRijndaelEncryption.rb
exclude:
- Gemfile
- Gemfile.lock
- node/**
This gets an [ENOENT: no such file or directory] for node/node_modules/#babel/core/node_modules/.bin/parser. This file is not there but I don't understand why it is looking for it, since webpack is not being called.
Sort of success?:
I was able to get the Lambdas to deploy if I commented out webpack and used
serverless deploy function -f <function name here>
to deploy the Ruby Lambda and then uncommented webpack and used the same thing to deploy the Node Lambda.
I'm convinced that there's a better way to get them to deploy; Have I missed something in my setup? Is there another option I haven't tried?
P.S. I did see this pull request https://github.com/serverless-heaven/serverless-webpack/pull/256, but it seems to be abandoned since 2017.
serverless-webpack is not designed for non-JS runtimes. It hijacks serverless packaging and deploys ONLY the webpack output.
Here are your options:
Don't use serverless-webpack and simply use serverless' built-in packaging.
You can use webpack directly (not serverless-webpack), and change your build process to compile using webpack first and then let serverless deploy the output folder.
P.S. The package.individually property is a root-level property in your serverless.yml. It shouldn't be in provider or in your function definitions.
For those who may be looking for options for multiple-runtimes other than serverless-webpack, I ended up switching to this plugin: https://www.npmjs.com/package/serverless-plugin-include-dependencies.
It works with my runtimes (Ruby and Node) and lets you use package.individually with package.include/exclude at the root and function level if the plugin misses something.

Resources