Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(webpack): compile JS with webpack - EUBFR-7 #4

Merged
merged 13 commits into from
Sep 11, 2017
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,25 @@ clone:

pipeline:
install:
image: node:latest
image: yhuard/node:latest
pull: true
commands:
- yarn install --frozen-lockfile

test:
image: node:latest
test-lint:
image: yhuard/node:latest
group: test
commands:
- yarn test
- yarn test:lint

test-integration:
image: yhuard/node:latest
group: test
commands:
- yarn test:integration

test-unit:
image: yhuard/node:latest
group: test
commands:
- yarn test:unit
19 changes: 12 additions & 7 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
---
root: true
extends:
- 'airbnb-base'
- 'prettier'
- airbnb-base
- prettier
- plugin:jest/recommended
plugins:
- 'prettier'
- jest
- prettier
rules:
'prettier/prettier':
- 'error'
prettier/prettier:
- error
-
'trailingComma': 'es5'
'singleQuote': true
trailingComma: es5
singleQuote: true
env:
node: true
jest/globals: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.serverless
.webpack
node_modules
*.log
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
singleQuote: true
trailingComma: es5
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Requirements

- Node.js current (8.x)
- yarn >= 0.27.5
- yarn >= 1.0.1

We recommend you to use [Node Version Manager](https://github.com/creationix/nvm) with our local `.nvmrc`:

Expand Down
62 changes: 62 additions & 0 deletions docker/node/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
FROM buildpack-deps:jessie

RUN groupadd --gid 1000 node \
&& useradd --uid 1000 --gid node --shell /bin/bash --create-home node

# gpg keys listed at https://github.com/nodejs/node#release-team
RUN set -ex \
&& for key in \
9554F04D7259F04124DE6B476D5A82AC7E37093B \
94AE36675C464D64BAFA68DD7434390BDBE9B9C5 \
FD3A5288F042B6850C66B31F09FE44734EB7990E \
71DCFD284A79C3B38668286BC97EC7A07EDE3FC1 \
DD8F2338BAE7501E3DD5AC78C273792F7D83545D \
B9AE9905FFD7803F25714661B63B535A4C206CA9 \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
56730D5401028683275BD23C23EFEFE93C4CFFFE \
; do \
gpg --keyserver pgp.mit.edu --recv-keys "$key" || \
gpg --keyserver keyserver.pgp.com --recv-keys "$key" || \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \
done

ENV NPM_CONFIG_LOGLEVEL info
ENV NODE_VERSION 8.4.0

RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \
&& case "${dpkgArch##*-}" in \
amd64) ARCH='x64';; \
ppc64el) ARCH='ppc64le';; \
s390x) ARCH='s390x';; \
arm64) ARCH='arm64';; \
armhf) ARCH='armv7l';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz" \
&& curl -SLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " node-v$NODE_VERSION-linux-$ARCH.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "node-v$NODE_VERSION-linux-$ARCH.tar.xz" -C /usr/local --strip-components=1 \
&& rm "node-v$NODE_VERSION-linux-$ARCH.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs

ENV YARN_VERSION 1.0.1

RUN set -ex \
&& for key in \
6A010C5166006599AA17F08146C2130DFD2497F5 \
; do \
gpg --keyserver pgp.mit.edu --recv-keys "$key" || \
gpg --keyserver keyserver.pgp.com --recv-keys "$key" || \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" ; \
done \
&& curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
&& curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \
&& gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
&& mkdir -p /opt/yarn \
&& tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/yarn --strip-components=1 \
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarnpkg \
&& rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz

CMD [ "node" ]
7 changes: 1 addition & 6 deletions lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,5 @@
"lerna": "2.1.2",
"version": "0.0.1",
"npmClient": "yarn",
"commands": {
"bootstrap": {
"hoist": "**"
}
},
"packages": ["services/*"]
"useWorkspaces": true
}
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@
"deploy": "lerna exec -- serverless deploy -v",
"lint": "eslint .",
"offline": "lerna run --parallel offline",
"postinstall": "npm run bootstrap",
"precommit": "lint-staged",
"test": "npm run lint"
"test:integration": "lerna run --parallel test:integration",
"test:unit": "lerna run --parallel test:unit",
"test:lint": "npm run lint",
"test": "npm-run-all -p test:* -cn"
},
"lint-staged": {
"*.js": ["prettier-eslint --write", "git add"]
"*.{js,json}": ["prettier --write", "git add"]
},
"devDependencies": {
"eslint": "4.6.1",
"eslint-config-airbnb-base": "12.0.0",
"eslint-config-prettier": "2.4.0",
"eslint-plugin-import": "2.7.0",
"eslint-plugin-jest": "21.0.0",
"eslint-plugin-prettier": "2.2.0",
"husky": "0.14.3",
"lerna": "2.1.2",
"lint-staged": "4.1.3",
"prettier-eslint-cli": "4.3.0",
"serverless": "1.21.1",
"serverless-offline": "3.15.3"
}
"npm-run-all": "4.1.1",
"prettier": "1.6.1"
},
"workspaces": ["services/*"]
}
4 changes: 4 additions & 0 deletions services/example01/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"plugins": ["transform-runtime"],
"presets": ["es2015", "stage-3"]
}
35 changes: 35 additions & 0 deletions services/example01/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"private": true,
"name": "example01",
"version": "0.0.1",
"scripts": {
"deploy-function":
"AWS_ACCESS_KEY_ID=foobar AWS_SECRET_ACCESS_KEY=foobar SLS_DEBUG=* serverless deploy function -f hello",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are ok temporarily to test quickly, though it's risky as it's easy to commit secrets. I'd suggest adding a line in the readme about configuring a profile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely for testing purpose and we should indeed manage secrets carefully. Since we don't have real code there and we don't use the actual api, it's not harmful, it just serves as an example

"invoke":
"AWS_ACCESS_KEY_ID=foobar AWS_SECRET_ACCESS_KEY=foobar SLS_DEBUG=* serverless invoke -f hello -l",
"logs":
"AWS_ACCESS_KEY_ID=foobar AWS_SECRET_ACCESS_KEY=foobar SLS_DEBUG=* serverless logs -f hello -t",
"remove":
"AWS_ACCESS_KEY_ID=foobar AWS_SECRET_ACCESS_KEY=foobar SLS_DEBUG=* serverless remove",
"test:integration":
"serverless offline start --exec \"jest --testPathPattern=integration\"",
"test:unit": "jest --testPathPattern=unit",
"offline": "serverless offline start"
},
"devDependencies": {
"babel-core": "6.26.0",
"babel-loader": "7.1.2",
"babel-plugin-transform-runtime": "6.23.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-stage-3": "6.24.1",
"jest": "21.0.1",
"serverless": "1.21.1",
"serverless-offline": "3.15.3",
"serverless-webpack": "2.2.2",
"webpack": "3.5.6",
"webpack-node-externals": "1.6.0"
},
"dependencies": {
"babel-runtime": "6.26.0"
}
}
33 changes: 33 additions & 0 deletions services/example01/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
service: example01

plugins:
- serverless-webpack
- serverless-offline

custom:
serverless-offline:
port: 4000
# Enable auto-packing of external modules
webpackIncludeModules: true

provider:
name: aws
runtime: nodejs6.10

functions:
hello-custom:
handler: src/handler.hello
events: # All events associated with this function
- http:
path: hello/{name}
method: get
request:
parameters:
paths:
name: true
hello-world:
handler: src/handler.hello
events: # All events associated with this function
- http:
path: hello
method: get
19 changes: 19 additions & 0 deletions services/example01/src/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable import/prefer-default-export, no-console */
import getMessage from './message';

export const hello = (event, context, callback) => {
// Contains incoming request data (e.g., query params, headers and more)
// console.log(event);

const { name } = event.pathParameters || { name: 'World' };

const response = {
statusCode: 200,
headers: {
'x-custom-header': 'My Header Value',
},
body: JSON.stringify({ message: getMessage(name) }),
};

callback(null, response);
};
1 change: 1 addition & 0 deletions services/example01/src/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default name => `Hello ${name}!`;
23 changes: 23 additions & 0 deletions services/example01/test/integration/hello.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const http = require('http');

function request(url) {
return new Promise(resolve => {
http.get(url, response => {
let data = '';
response.on('data', _data => {
data += _data;
});
response.on('end', () => resolve(data));
});
});
}

it('works with promises', () => {
expect.assertions(1);

const name = 'test';

return request(`http://localhost:4000/hello/${name}`).then(data =>
expect(JSON.parse(data)).toEqual({ message: `Hello ${name}!` })
);
});
5 changes: 5 additions & 0 deletions services/example01/test/unit/message.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import getMessage from '../../src/message';

test(`getMessage('World') to return 'Hello World!'`, () => {
expect(getMessage('World')).toBe('Hello World!');
});
25 changes: 25 additions & 0 deletions services/example01/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable import/no-extraneous-dependencies */
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const path = require('path');

module.exports = {
entry: slsw.lib.entries,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the documentation for the serverless-webpack but I didn't manage to understand what would be the workflow if there is an additional library which is to be developed separately from the main handler? For example, 1 file in lib contains an export of a single function which is imported in the handler, would the lib file be ok with the babel run-time transpiration if the handler is not called?

Copy link
Contributor Author

@yhuard yhuard Sep 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Serverless has been updated during the weekend, I don't know which documentation you read but:

  • AFAIK the code is not transpiled during runtime, it is transpiled before being deployed
  • you can import myFunction from 'helper.js' and if there's no call to myFunction, the code won't be imported (tree-shaking)

But maybe I've missed your point

target: 'node',
externals: [nodeExternals()],
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel-loader'],
include: __dirname,
exclude: /node_modules/,
},
],
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
};
15 changes: 0 additions & 15 deletions services/test01/handler.js

This file was deleted.

12 changes: 0 additions & 12 deletions services/test01/package.json

This file was deleted.

Loading