Serverless packaging issue - serverless-framework

I am using NodeJS 10 to create number of lambdas. Many functions has shared code that included into each function, so overall structure looks like:
project/
function1/
api.js
serverless.yml
function2/
api.js
serverless.yml
function3/
api.js
serverless.yml
shared/
http/
index.js
node_modules/
intercom/
index.js
node_modules/
Each serverless.yml contains function declaration like:
functions:
test-database-connection:
package:
include:
- ../shared/http/**
- ../shared/intercom/**
- ./node_modules/**
- ./api.js
handler: api.connectivityDatabase
events:
- http:
path: /api/test/database
method: post
During development it works, also working offline well, but after packaging it becomes unusable because package changes relative paths to shared folder like:
package.zip/
shared/
http/
...
intercom/
...
api.js
Is it possible to keep same structure in package as during development? Or any other way to fix module paths that will work locally and on AWS both?

If you're using npm, I recommend creating a package.json file in shared
Then you can simply require it in the package.json files in function1 with a relative path:
"name": "function1",
"dependencies": {
"shared": "file:../shared",
...
}
Then you can remove the package logic from the serverless.yml file, and just let the package manager handle things. The Serverless Framework will resolve those packages when packaging your application for deployment.

Related

Can't get Vite to build app and js file into the same dist

I'm having trouble configuring vite.config.js so that I can have both my Vue app and a service worker file live in the dist folder. My service worker was working with webpack previously but I've just upgraded to Vite and I'm having trouble configuring the build. My goal is to have my dist folder look like:
dist
|- index.html
|- sw.js
|- assets
|- app.[hash].js
I tried various different configurations but none of them have worked:
An approach that is recommended by Workbox. It seems like this doesn't work because of what is mentioned in this comment.
After reading that comment I tried to separate the logic out into a separate file (vite-sw.config.js) and running vite build -c vite-sw.config.js. This successfully generated the file I wanted but I couldn't figure out how to get that file mixed in with the original build. Is there a way to combine vite build and vite build -c vite-sw.config.js so that they both output to the same dist directory without overriding each other?
I found this alternative approach which successfully created the folder structure I wanted in dist but I was unable to adjust the format of the service worker file so I got Cannot use import statement outside a module (at sw.js:1:1) in the browser. Is there some way to use this method and somehow configure the format of the service worker file?
Any other ideas? I've been pretty stuck on this for a while. Thanks!
Try changing your configuration like this:
export default defineConfig({
build: {
rollupOptions: {
output:
{
format: 'es',
strict: false,
entryFileNames: "[name].js",
dir: 'dist/'
}
}
},
.
.
.
});

NPM Workspaces monorepo - share local package's distribution folder as root instead of the entire source files

Using NPM Workspaces, I'm sharing one package (components) with others (webapp1 and webapp2). Something like this:
root
apps
webapp1
webapp2
packages
components
Everything is working well, but everything inside components, include source code in the src folder is being shared. Since components' compiled output folder is dist, I'd like to only share that folder. This is how it looks in the root node_modules:
The problem is that when I need to import in webapp1 or webapp2, my import path has to include the dist folder. Here's the intellisense that I get from VS Code:
And this is how I import in webapp1 and webapp2:
import Center from '#mycompany/components/dist/Center'
While everything works, how can I set up my NPM Workspaces so that only the contents of the dist folder is shared in its root?
I've tried NPM's files and .npmignore inside the components folder to ignore everything except for the dist folder, but that doesn't seem to work. The main property in package.json for components is also set to point to dist/index.js:
"main": "dist/index.js"
Interestingly, if I want to import dist/index.js file, I can do it without dist:
import foo from '#mycompany/components'
...however, importing anything other than dist/index.js requires dist to be included in the path.
You should treat the packages folder as a collection of dist folders in your use case.
In this scenario, you would move your packages/components/src folder somewhere else in your project and then build to packages/components instead of packages/components/dist
root
apps
webapp1
webapp2
packages
components
src
components
I have a similar setup in this tooling monorepo I created
An alternative to #nicksaroba's approach, if you don't want to restructure your project layout, you can just setup an alias:
// apps/webapp/webpack.config.js
module.exports = {
// ...
resolve: {
alias: {
"components": "#mycompany/components/dist/"
}
},
// ...
};

Change default directory in Snowpack Vue app

I want to use Snowpack for my Vue 3 app. Currently, I've initialized the Vue 3 app using the following command:
npx create-snowpack-app my-app --template #snowpack/app-template-vue
By default, Snowpack creates a directory structure like this:
public/
src/
App.vue
index.js
package.json
README.md
snowpack.config.js
I need to restructure things slightly. The reason why is I'm moving an existing app to Snowpack. My challenge is I need to move to a structure like this:
public/
pages/
App.vue
index.js
package.json
README.md
snowpack.config.js
In short: 1) rename src to pages and 2) move index.js up to the same level as package.json. When I make this change, Snowpack throws a warning that says "mounted directory does not exist". It prints out the files it's looking for, which, Snowpack is clearly still looking in the src directory. My thinking was to review the snowpack.config.js file.
I looked at the mount property in the snowpack.config.js file. I changed mount.src.url to /pages. However, that didn't work. I also tried changing the property to just /, which also didn't work.
What do I need to change to tell Snowpack to look in the current directory instead of the src directory for the index.js file?
That directory layout is possible with a mount config that specifies . as the mount point:
// snowpack.config.js
module.exports = {
mount: {
'.': {url: '/dist'}
},
}
Then the root index could import the SFC from <projectRoot>/pages/:
// <projectRoot>/index.js
import App from './pages/App.vue'
...

How can I create two separate bundles with vue-cli 3?

I want to build two separate vue apps that will be served on two different routes in an express application: a ‘public’ vue app and an ‘admin’ vue app. These two apps have their own router and store but they share a lot of custom components.
How can I edit the default webpack template to make it output two separate bundles based of my two different entry points (‘public’ and ‘admin’)?
The goal would be to end up with a setup more or less like this:
my-app/
+- ...
+- dist/
| +- admin/ Admin bundle and files
| +- public/ Public bundle and files
+- src/
| +- components/ Shared components
| +- admin/ Entry point, router, store... for the admin app
| +- public/ Entry point, router, store... for the public app
+- ...
Must by available 2 dev servers http://localhost:8080/admin and http://localhost:8080/public
Each project must be in own folder in dist, and own public
What i have today:
created file vue.config.js in root directory
With:
module.exports = {
// tweak internal webpack configuration.
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
chainWebpack: config => {
// If you wish to remove the standard entry point
config.entryPoints.delete('app')
// then add your own
config.entry('admin')
.add('./src/admin/index.js')
.end()
.entry('public')
.add('./src/public/index.js')
.end()
}
}
Assuming you need completely separate builds, with some shared scripts guided by your entries, you can add separate build commands.
In your package.json "scripts" section:
"scripts": {
"build:admin": "vue-cli-service build --dest dist/admin src/admin/index.js,
"build:public": "vue-cli-service build --dest dist/public src/public/index.js
}
For admin builds, you may run:
npm run build:admin
and for public builds:
npm run build:public
For more information, view the build target docs.
I am also very interested by this matter.
Maybe we can solve this issue with subpages :
https://cli.vuejs.org/config/#pages :
"Build the app in multi-page mode. Each "page" should have a corresponding JavaScript entry file. The value should be an object where the key is the name of the entry, and the value is either:"
module.exports = {
pages: {
index: {
// entry for the *public* page
entry: 'src/index/main.js',
// the source template
template: 'public/index.html',
// output as dist/index.html
filename: 'index.html'
},
// an admin subpage
// when using the entry-only string format,
// template is inferred to be `public/subpage.html`
// and falls back to `public/index.html` if not found.
// Output filename is inferred to be `admin.html`.
admin: 'src/admin/main.js'
}
}
Building on the other answers here, I've found it's possible to specify the build output directory in vue.config.js rather than having to do that in the command line. So then combining that with the use of the VUE_CLI_SERVICE_CONFIG_PATH environment variable makes things a lot simpler - no need for it to copy/delete config files each time you build.
You do have to specify the full paths to the Vue config files though. This works even on Windows, but only from a Linux-type terminal (e.g. I tested it from Git Bash installed by Git for Windows and it worked fine, but doesn't work from the normal Windows Command Prompt, as I couldn't find any way of setting the environment variable in the npm script which worked when run from there)
https://gist.github.com/EdwardMillen/0c417747cd8ce64b8ba550bdfa582cf5
It is also possible to have multiple vue.config.js configs and switch them over using the VUE_CLI_SERVICE_CONFIG_PATH environment variable.
For example, we can have a default vue.config.js and an additional vue.public.config.js and run the build like this:
# Build using vue.config.public.js
# Note: using real path here, it didn't work with relative path
CONF=`realpath vue.config.public.js`
VUE_CLI_SERVICE_CONFIG_PATH=$CONF npm run build
# Build using default vue.config.js
npm run build
Where npm run build is defined in package.json as vue-cli-service build:
"scripts": {
"build": "vue-cli-service build"
}
Note: I didn't find any mention on VUE_CLI_SERVICE_CONFIG_PATH in the documentation, found it looking at the source code.

How to set up a private shared library of React components with Webpack

I have a number of React components that I use in multiple Webpack projects, and I want to share them via NPM. So naturally I:
put those components into a (private) GitHub repo
Added that repo to a main project's package.json
So that I could develop on the component library simultaneously, I used npm link to symlink it into my main project.
However, Webpack can't resolve react from my library component files, because there's no node_modules in the library project folder or any of its parents.
I've seen 3rd party React components that were built as a bundle with react in the externals of the Webpack config, but I don't want to build a separate bundle or do anything complicated, I just want to require the raw source for my library components. Does anyone know how to do that?
I wish I could find a more elegant solution, but adding this to my webpack.config.js worked:
resolve: {
fallback: path.resolve(__dirname, 'node_modules')
},
resolveLoader: { root: path.join(__dirname, "node_modules") },
However, I ultimately decided it would be easier just to share the components between projects in a git submodule.