I'm facing with a rather annoying and frustrating anomaly with Serverless + Webpack generating empty files in the .serverless/<package>.zip.
Config
serverless.yml
...
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
...
webpack.config.js
const slsw = require("serverless-webpack")
const nodeExternals = require("webpack-node-externals")
// const CopyPlugin = require("copy-webpack-plugin")
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
},
// node: false,
// devtool: 'inline-cheap-module-source-map',
// Run babel on all .js files and skip those in node_modules
module: {
rules: [
{
test: /\.js$/,
include: __dirname,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
[
'#babel/preset-env',
{
targets: { node: '12' },
useBuiltIns: 'usage',
corejs: 3,
},
],
],
},
},
],
},
],
},
plugins: [
// TODO
// new CopyPlugin([
// 'path/to/specific/file',
// 'recursive/directory/**',
// ]),
],
};
Additional Data
Serverless-Webpack Version: "serverless-webpack": "^5.3.5",
Webpack version: "webpack": "4.44.2",
Serverless Framework Version: 1.83.2
Operating System: MacOS
I have tried other version combinations too: Serverless 2.20, webpack 5.17.0, copy-webpack-plugin 7.0.0
Why empty files in ZIP?? 🤯
Update:
I have just tried to run sls package in one of the example projects with same result, empty files in ZIP.
Thanks.
I downgraded nodejs from 15.7.0 to 15.4.0 and it's working fine now.
Solution: downgrade Node JS from version 15 to 13. (Did not try 14.)
Use nvm to manage different versions of the node.
The issue was happening for me with node version v15.8.0. Resolved by downgrading system version to v14.15.5 using nvm.
Reference - https://forum.serverless.com/t/empty-files-in-uploaded-zip/13777
I am unable to build certain PrimeVue UI components with webpack.
I have tried several components, and all the basic ones work fine, but as soon as I try and use a component that requires a sub-component, webpack fails to build. I experienced this so far with the Breadcrumb and PanelMenu components.
The error is:
ERROR in ./node_modules/primevue/components/panelmenu/PanelMenu.vue?vue&type=script&lang=js& (./node_modules/vue-loader/lib??vue-loader-options!./node_modules/primevue/components/panelmenu/PanelMenu.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve './PanelMenuSub' in '/my-application-directory/node_modules/primevue/components/panelmenu'
# ./node_modules/primevue/components/panelmenu/PanelMenu.vue?vue&type=script&lang=js& (./node_modules/vue-loader/lib??vue-loader-options!./node_modules/primevue/components/panelmenu/PanelMenu.vue?vue&type=script&lang=js&) 27:0-42 86:24-36
# ./node_modules/primevue/components/panelmenu/PanelMenu.vue?vue&type=script&lang=js&
# ./node_modules/primevue/components/panelmenu/PanelMenu.vue
# ./node_modules/primevue/panelmenu.js
# ./interface/html5/vue-components/Menu.js
# ./interface/html5/vue-components/App.js
# ./interface/html5/vue-main.js
My webpack config is as follows:
const path = require('path');
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
mode: 'development',
entry: 'vue-main.js',
output: {
filename: 'vue-main.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.vue$/,
use: 'vue-loader'
},
// the below will apply to both plain `.js` files AND `<script>` blocks in `.vue` files
// the below will apply to both plain `.css` files AND `<style>` blocks in `.vue` files
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
plugins: [
new VueLoaderPlugin()
]
};
The component is used exactly as described in the documentation.
What could be causing this? The same is happening with the Breadcrumb component, except it can't find the BreadcrumbItem component. I checked the node_modules directory and the files are there.
Is this a webpack config file problem, a PrimeVue bug, or a user (me) error?
is that your full config without babel? I would try to resolve properly.
https://webpack.js.org/configuration/resolve/
resolve: {
alias: {
'#': res('src'),
'vue$': 'vue/dist/vue.esm.js'
},
modules: [res('node_modules')],
extensions: ['.js', '.vue', '.json']
},
resolveLoader: {
modules: [res('node_modules')]
}
My testing-app is compiling fine, except that I get this warning:
" Critical dependency: the request of a dependency is an expression"
(base) marco#pc01:~/webMatters/vueMatters/PeerJS-VueJS-Test$ npm run serve
> testproject#0.1.0 serve /home/marco/webMatters/vueMatters/PeerJS-VueJS-Test
> vue-cli-service serve
INFO Starting development server...
98% after emitting CopyPlugin
WARNING Compiled with 1 warnings
7:22:25 PM
warning in ./node_modules/peerjs/dist/peerjs.min.js
Critical dependency: the request of a dependency is an expression
App running at:
- Local: http://localhost:8080
- Network: http://ggc.world/
Note that the development build is not optimized.
To create a production build, run npm run build.
I read around that it might depend of webpack, but didn't find how to put it right.
This is webpack.config.js :
{
"mode": "development",
"output": {
"path": __dirname+'/static',
"filename": "[name].[chunkhash:8].js"
},
"module": {
"rules": [
{
"test": /\.vue$/,
"exclude": /node_modules/,
"use": "vue-loader"
},
{
"test": /\.pem$/,
"use": "file-loader"
}
]
},
node: {
__dirname: false,
__filename: false
},
resolve: {
extension: ['*', '.pem'],
},
devServer: {
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
https: true,
compress: true,
public: 'ggc.world:8080'
}
}
Any ideas about how to solve it?
The following code works for me. Edit vue.config.js and add webpack config:
configureWebpack: {
module: {
exprContextCritical: false
}
}
const webpack = require('webpack');
module.exports = {
// ... your webpack configuration ...
plugins: [
new webpack.ContextReplacementPlugin(
/\/package-name\//,
(data) => {
delete data.dependencies[0].critical;
return data;
},
),
]
}
try this one
For people coming here using CRA and having trouble with PeerJS, install react-app-rewired and use the following override config and it should work.
/* config-overrides.js */
const webpack = require('./node_modules/webpack')
module.exports = function override (config, env) {
if (!config.plugins) {
config.plugins = []
}
config.plugins.push(
new webpack.ContextReplacementPlugin(
/\/peerjs\//,
(data) => {
delete data.dependencies[0].critical
return data
}
)
)
return config
}
It seems it is an error between the library bundler (parcel) and CRA bundler (webpack), and I couldn't find any official fix on the way.
I'm developing a full-stack application using Vue-CLI 3. The backend is written in TypeScript and so requires compilation etc. Currently I'm just using ts-node to run the backend app directly which works, but it would be much cleaner if I could also webpack the backend app to give a single server.js rather than multiple sprawling typescript files all over the place.
The problem is that the way I'd do this normally is have a single webpack.base.js and then include that in different webpack config files. I can't really do that because a lot of the webpack configuration is hidden away in vue-cli-service
Ended up pretty much having a base webpack config and extending client and server webpack configuration.
My app root webpack.config.js looks like this:
const { config: client } = require('./src/client/webpack.config');
const { config: server } = require('./src/server/webpack.config');
/**
* Webpack Build File
*
* This webpack configuration is used for only building the client and server
* bundles. It imports both of these from their respective directories, but
* allows for overrides if required.
*
* Other dev tools such as watching, hot module reloading etc. has been split
* out into other config files
*
* #param {object} env Webpack `env` object
*/
module.exports = ({ mode = 'development' } = {}) => ([
{
...client({ mode }, process.env),
},
{
...server({ mode }, process.env),
},
]);
My src/client/webpack.config.js looks like this:
const { resolve: _resolve, sep } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackRootElementPlugin = require('html-webpack-root-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const { DefinePlugin } = require('webpack');
const paths = {
src: {
rootDir: _resolve(__dirname) + sep,
app: _resolve(__dirname, 'app') + sep,
},
dist: {
rootDir: _resolve(__dirname, '..', '..', 'dist'),
app: _resolve(__dirname, '..', '..', 'dist', 'public'),
},
};
/**
* Client webpack build configuration.
*
* This webpack config produces a bundle for the client-side application only.
*
* #param {object} webpackEnv Webpack env object (basically any/all options passed in via the CLI)
* #param {object} processEnv Process env object (environment variables from process.env)
*/
const config = ({ mode = 'none' }, { APP_NAME = '', BASE_URL = '/' } = {}) => ({
name: 'client',
target: 'web',
mode,
entry: {
app: paths.src.app + 'main.ts',
},
output: {
path: paths.dist.app,
},
optimization: {
runtimeChunk: 'single',
},
resolve: {
extensions: ['.ts', '.js', '.vue'],
plugins: [
new TSConfigPathsPlugin({
configFile: paths.src.rootDir + 'tsconfig.json',
}),
],
},
context: paths.src.rootDir,
module: {
rules: [
{
test: /\.tsx?$/,
include: paths.src.rootDir,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
happyPackMode: true,
},
},
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.s?[ac]ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
loader: 'file-loader',
options: {
name: 'assets/[name].[hash].[ext]',
esModule: false,
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
favicon: paths.src.app + 'assets/logo.png',
title: APP_NAME,
}),
new HtmlWebpackRootElementPlugin('app'),
new VueLoaderPlugin(),
new DefinePlugin({
'process.env.BASE_URL': JSON.stringify(BASE_URL),
}),
],
});
module.exports = {
config,
paths,
};
and my src/server/webpack.config.js looks like this:
const { resolve: _resolve, sep } = require('path');
const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
const { IgnorePlugin } = require('webpack');
const paths = {
src: _resolve(__dirname) + sep,
dist: _resolve(__dirname, '..', '..', 'dist'),
};
/**
* NestJs uses a custom wrapper around require() that allows it to show a
* warning when some extra package needs to be installed. This causes problems
* with webpack, so we're blacklisting packages we're not using with the
* IgnorePlugin below.
*
* To de-blacklist a package, just remove it from this array.
*/
const nestBlacklist = [
'^cache-manager$',
'^#nestjs/microservices$',
// packages below are required from microservices
'^amqp-connection-manager$',
'^amqplib$',
'^grpc$',
'^mqtt$',
'^nats$',
'^redis$',
];
/**
* Server webpack build configuration.
*
* This webpack config produces a bundle for the server-side application only.
*
* #param {object} webpackEnv Webpack env object (basically any/all options passed in via the CLI)
* #param {object} processEnv Process env object (environment variables from process.env)
*/
const config = ({ mode = 'none' }) => ({
name: 'server',
mode,
target: 'node',
entry: paths.src + 'main.ts',
externals: [nodeExternals()],
output: {
path: paths.dist,
filename: 'server.js',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [
new TSConfigPathsPlugin({
configFile: './tsconfig.build.json',
}),
],
},
context: paths.src,
optimization: {
minimize: false,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.ts$/,
include: paths.src,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
happyPackMode: true,
},
},
],
},
],
},
plugins: [
new IgnorePlugin({
contextRegExp: /#nestjs/,
resourceRegExp: new RegExp(nestBlacklist.join('|')),
}),
],
node: {
__dirname: false,
},
});
module.exports = {
config,
paths,
};
This allows me to have distinct server and client side compilation configuration, but in such a way that's re-usable in other configurations. So, for webpack dev server - I have webpack.dev.config.js which contains the following:
const client = require('./src/client/webpack.config');
const server = require('./src/server/webpack.config');
const { HotModuleReplacementPlugin } = require('webpack');
const {
SERVER_PORT = 3000,
} = process.env;
/**
* Watch settings are the same between client and server, so we're keeping them
* here for consistency
*/
const watchConfig = {
watch: true,
watchOptions: {
ignored: /node_modules/,
},
};
/**
* Development Webpack Build File
*
* This webpack configuration extends `webpack.config.js` and builds on it to
* provide hot module replacement, watch moide and a dev server for the
* client-side code
*
* Other dev tools such as watching, hot module reloading etc. has been split
* out into other config files
*
* #param {object} env Webpack `env` object
*/
module.exports = ({ mode = 'development' } = {}) => ([
{
...client.config({ mode }, process.env),
...watchConfig,
devServer: {
contentBase: client.paths.dist.app,
historyApiFallback: {
rewrites: [
{ from: /./, to: '/index.html' },
],
},
port: 8000,
host: '0.0.0.0',
hot: true,
hotOnly: true,
proxy: {
'/api': `http://localhost:${SERVER_PORT}/`,
},
},
},
{
...server.config({ mode }, process.env),
...watchConfig,
plugins: [
...server.config({ mode }, process.env).plugins,
new HotModuleReplacementPlugin(),
],
},
]);
This config provides a setup that produces a server.js which then serves up a directory (in this case '/public'`) as it's static files dir.