I am working on a node application using serverless architecture. We are using serverless-webpack plugin to build the application. Here is the webpack.config.js
module.exports = {
mode: isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
externals: [nodeExternals()],
devtool: 'inline-cheap-module-source-map',
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx']
},
output: {
libraryTarget: 'commonjs2',
path: path.join(__dirname, '.webpack'),
filename: '[name].js'
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin()],
},
target: 'node',
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'ts-loader',
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true
}
},
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader',
}
]
},
// plugins: [new ForkTsCheckerWebpackPlugin()]
};
and here is the serverless.yml file :
service: app
provider:
name: aws
region: ${env:AWS_REGION}
stage: ${env:STAGE}
logRetentionInDays: 90
role: ${env:ROLE}
versionFunctions: false
runtime: nodejs12.x
package:
individually: true
plugins:
- serverless-webpack
- serverless-offline
custom:
webpack:
webpackConfig: './webpack-gql.config.js'
packager: 'npm'
includeModules: true
functions:
######## GraphQl ###########
graphql:
role: ${env:ROLE}
runtime: nodejs12.x
timeout: 30
handler: aws/lambda/common/api/graphql.graphqlHandler
events:
- http:
path: graphql
method: post
- http:
path: graphql
method: get
When I am running sls deploy --config serverless.yml to deploy the application , everything is working and the lambda is getting deployed successfully.
Only thing is , during the process of deployment , it is using the package-lock.json and installing the used packages again :
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: graphql-compose#^7.19.3, linewrap#^0.2.1, d64#^1.0.0, graphql-scalars#^1.2.6, graphql-tools#^6.0.12
Serverless: Packaging service...
My question is how to stop rerunning the npm install again during deployment instead it should use the existing node_moudles while packing the external modules.
Can anybody help me on this. ?
Related
I am trying to use typescript with serverless applications and I ran in some issues like the serverless-typescript package had its last update a year ago. I also tryed to use it with serverless webback but i am running in some issues regarding the use of ORMS because webpack cannot load the modals properly (it can when i import the files but not a runtime). Does someone have any advice of how to devolop serverless applications with typescript or should I keep using just javascript?
Basically it doesn't matter either it is serverless application or not. What matters is your webpack config. Try using serverless-webpack plugin with proper webpack config for typescript compilation
serverless.yml webpack part example:
plugins:
- serverless-webpack
custom:
webpack:
webpackConfig: ./webpack.config.js
webpack.config.js example:
const path = require('path')
const slsw = require('serverless-webpack')
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: slsw.lib.entries,
target: 'node',
resolve: {
extensions: ['.mjs', '.ts', '.js', '.json', '.tsx']
},
output: {
libraryTarget: 'commonjs2',
path: path.join(__dirname, '.webpack'),
filename: '[name].js'
},
module: {
rules: [
{
oneOf: [
{
test: /\.(ts|js)$/,
exclude: [/node_modules/],
loader: 'ts-loader',
options: {
transpileOnly: true
}
}
]
}
]
}
}
You can adapt it to your needs, I've just shared a little piece of my config
When I deploy a serverless function to AWS I get "Cannot find module '../knexfile'". That import path works when im working using serverless-offline. However, when I deploy to AWS all the packages get included at the root level so the import path is not correct. When I change it to 'knexfile' instead of '../knexfile' it works when deployed but not when ran locally. What can I do for the path to be what it needs to be automatically?
I would like for the path to get automatically resolved when deployed to AWS or tested locally.
I used the serverless-webpack npm package to solve the problem. This ended up being my webpack.config.js file:
const path = require('path')
const slsw = require('serverless-webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = {
entry: slsw.lib.entries,
target: 'node',
mode: slsw.lib.webpack.isLocal ? 'development': 'production',
optimization: {
// We no not want to minimize our code.
minimize: false
},
performance: {
// Turn off size warnings for entry points
hints: false
},
devtool: 'nosources-source-map',
externals: [nodeExternals(),
{
'sqlite3': 'sqlite3',
'mariasql': 'mariasql',
'mssql': 'mssql',
'mysql': 'mysql',
'mysql2': 'mysql2',
'mssql/package.json': 'mssql/package.json',
'mssql/lib/base': 'mssql/lib/base',
'oracle': 'oracle',
'strong-oracle': 'strong-oracle',
'oracledb': 'oracledb',
'pg-native': 'pg-native',
'pg-query-stream': 'pg-query-stream',
'tedious': 'tedious'
}],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
],
}
]
},
output: {
libraryTarget: 'commonjs2',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
sourceMapFilename: '[file].map'
}
}
I have a project which is building successfully on Jenkins but when I try to build using AWS Codebuild it gives a plugin error. The project is basically a NodeJS and ReactJS project. We do not want to move to Jenkins as we are serverless and installing jenkins requires one EC2 instance. We do not want to maintain any server. I have tried below environments for AWS codebuild:
aws/codebuild/ubuntu-base:14.04
aws/codebuild/nodejs:6.3.1
aws/codebuild/nodejs:7.0.0
aws/codebuild/nodejs:4.4.7
The first four commands of my buildspec.yml is executed only when I use aws/codebuild/ubuntu-base:14.04 codebuild environment. Otherwise only last three commands are part of my buildspec.yml
Below is my buildspec.yml
version: 0.1
phases:
build:
commands:
- sudo apt-get update
- curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
- sudo apt-get install -y nodejs
- sudo apt-get install -y build-essential
- npm install
- npm run dev
- aws s3 cp --recursive dist/ s3://$AWS_BUCKET_NAME/ --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers
Below is my error logs in AWS codebuild during npm run
ERROR in
Child html-webpack-plugin for "index.html":
+ 3 hidden modules
Also, I get following warning during npm install in Codebuild but I do not get the this warning in Jenkins
npm WARN deprecated babel-plugin-react-hot#1.0.4: This plugin is no longer maintained. Please use babel-plugin-react-transform with react-transform-hot-reload instead.
Below is my webpack.config.js
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var FlowStatusWebpackPlugin = require('flow-status-webpack-plugin');
module.exports = {
entry: [
'./src/app/index.js'
],
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
module: {
loaders: [
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.js$/,
exclude: /(node_modules|test)/,
loaders: ["babel-loader"]
},
{
test: /\.(css|scss)$/,
loaders: ['style', 'css', 'sass-loader']
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader',
options: {
limit: 100000,
name: 'assets/[hash].[ext]'
}
},
{
test: /\.styl$/,
loader: 'style-loader!css-loader!postcss-loader!stylus-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + '/src/app/index.html',
filename: 'index.html',
inject: 'body'
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
new webpack.DefinePlugin({
"process.env": {
'NODE_ENV': JSON.stringify('dev')
}
}),
new FlowStatusWebpackPlugin({
failOnError: true
})
],
devtool: 'source-map',
node: {
tls: "empty",
fs: "empty"
},
resolve: {
root: path.resolve(__dirname),
alias: {
'~': 'src',
},
extensions: ['', '.js', '.jsx']
},
};
new HtmlWebpackPlugin({
template: __dirname + '/src/app/index.html',
filename: 'index.js',
inject: 'body'
})
filename option is supposed to be a javascript file? i.e: filename: index.js
After bundling I have following errors:
Module not found: Error: Can't resolve 'crypto' in //filePath
It can't resolve five modules: crypto, fs, path, vm and constants - from any file which requires them
I thought it could be because of nvm which I use, but I switched to system nodejs via nvm use system command and webpack still throws these errors.
I also thought it could be target property, so I changed it to node, but it didn't help too (anyway I need electron-renderer, not node).
Important note: I've just migrated from webpack 1. It all works well before I migrated. But these are the only errors I have. Moreover, webpack seems to work fine, it even watches files when I pass --watch option.
Here is my webpack.config.js:
const config = {
target: 'electron-renderer',
context: __dirname,
entry: { app: './app.js', vendor: [/*vendors*/]},
cache: true,
devtool: 'source-map',
watch: false
resolve: {
extensions: ['.js', '.json', '.jsx'],
modules: ["node_modules"]
},
module: {
rules: [
{test: /\.html/, loader: 'html-loader'},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader?sourceMap", "less-loader?sourceMap"]
})
},
{
test: /\.css/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader?sourceMap"
})
},
{test: /\.(jpg|png|gif|jpeg|svg|otf|ttf|eot|woff)$/, loader: 'url-loader?limit=10000'}
]
},
plugins: [
new ExtractTextPlugin('styles.[contenthash].css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['commons', 'vendor', 'manifest'],
minChuncks: Infinity
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
hash: false,
inject: 'head',
cashe: true,
showErrors: true
})
],
output: {
publicPath: './',
path: path.join(__dirname, 'dist'),
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js'
}
};
module.exports = config;
The problem was in worker-loader, which is not in my webpack.config.js (I used it directly when importing file). See this issue for details (not fixed yet).
I am using webpack+react+redux on a web application. And I am using webpack-dev-server to launch dev web server. When I access my application on a browser, it gives below error messages on the console:
Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster.
You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify to ensure you have the correct code for your production build.
Below is my webpack.config.js file. I didn't specify production mode, why webpack gives me such warning message? And how can I get rid of it?
const webpack = require('webpack');
const path = require('path');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const WebpackShellPlugin = require('webpack-shell-plugin');
var CompressionPlugin = require("compression-webpack-plugin");
const PATHS = {
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
app: path.join(__dirname, 'src'),
build: path.join(__dirname, './dist')
};
module.exports = {
entry: {
app: './app/index.jsx',
android: './app/utils/platform_android.js',
ios: './app/utils/platform_ios.js',
web: './app/utils/platform_web.js',
vendor: [
'axios',
'react',
'react-dom',
'react-redux',
'react-router',
'react-router-redux',
'redux',
'redux-thunk',
'react-alert',
'sha1',
'moment',
'nuka-carousel',
'react-cookie',
'material-ui',
'react-spinkit',
'react-tap-event-plugin',
'react-tappable',
],
},
output: {
path: PATHS.build,
filename: '[name].bundle.js',
},
watch: true,
devtool: 'source-map',
relativeUrls: true,
resolve: {
extensions: ['', '.js', '.jsx', '.css', '.less'],
modulesDirectories: ['node_modules'],
alias: {
normalize_css: __dirname + '/node_modules/normalize.css/normalize.css',
}
},
module: {
preLoaders: [
{
test: /\.js$/,
loader: "source-map-loader"
},
// {
// test: /\.js$/,
// exclude: /node_modules/,
// loader: 'jshint-loader'
// }
],
loaders: [
{
test: /\.html$/,
loader: 'file?name=[name].[ext]',
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets=es2015',
},
{
test: /\.less$/,
loader: "style!css!less",
},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /\.png$/, loader: "url-loader?limit=100000"},
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader?presets=es2015']
},
{
test: /\.svg$/,
loader: 'svg-sprite',
include: /public\/icons/
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
}),
new NpmInstallPlugin({
save: true // --save
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */["vendor"], /* filename= */"[name].bundle.js", Infinity),
],
devServer: {
colors: true,
contentBase: __dirname,
historyApiFallback: true,
hot: true,
inline: true,
port: 9093,
progress: true,
stats: {
cached: false
}
}
}
EDIT1:
I removed this line:
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
Then updated the NODE_ENV to development as below:
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("development")
}
})
Then I still got the same warning.
warning.js:14You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) to ensure you have the correct code for your production build.
I don't know how to say it more clear than webpack does...
You are not in a production build mode, but using a minified version of React. Use a non-minified one, so replace
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
with
react: path.join(__dirname, 'node_modules/react/dist/react.js'),
or whatever place where you have your react not minified.
And this is not an error - it is a warning, so you can still work with this one.
Just another thing by the way: path.join adds proper slashes for each operating system. What you do here is
path.join(__dirname, 'node_modules/react/dist/react.min.js')
when you should go with
path.join(__dirname, 'node_modules', 'react', 'dist', 'react.min.js')
This is how the path should be properly used
The warning you get now is because you are letting Webpack minify your build, but you are still setting NODE_ENV to development.
If you use UglifyJsPlugin you should always set NODE_ENV to production. If you're not building for production, remove UglifyJsPlugin to not get any warnings.
Webpack, React and Redux try to give you some best practice hints here. In development mode (NODE_ENV not set to production), they all give more warnings and have lower performance. When you minify them they assume you're running a production build. For production builds, they really expect NODE_ENV to be set correctly.
So in short:
Production builds: set NODE_ENV to production and use UglifyJsPlugin.
Dev builds: set NODE_ENV to development and don't use any minification plugins.
I fixed it by removing below configuration from webpack.config.js for development build. It seems that this plugin will compress the js code which is not suitable for development mode.
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
})