Nrwl Nx build for production missing node modules bundle - express

I have a Nrwl Nx repo with different apps (angular, nodejs with express) and shared libs inside.
The repo was created with the nx cli and I want to build for production one of the express apps.
nx build:production myexpressapp
The bundle I get is very nice and runs if I run it (with pm2) from where it was built (dist folder).
However, if I get it to production, the node modules are missing and the app does not start.
If I copy the node_modules folder above the one with the built dist it works as well.
But I would very much like either of:
Getting a big bundle with all the required modules inside of it?
Getting another 'vendors' bundle along my main one where all the needed modules are?
I tried using "vendorChunk":true in my production build options but nothing changes.
Any thoughts?

Looking at angular.json (or workspace.json), if your builder is #nrwl/node:build, under options, set externalDependencies to none, like so:
{
"projects": {
"api": {
"architect": {
"build": {
"builder": "#nrwl/node:build",
"options": {
"externalDependencies": "none"
...
You may experience errors like:
ERROR in ...
Module not found: Error: Can't resolve 'some-modules' in ...
Just keep installing what its complaining about, until it stops.
Reference: Nrwl Nx Node Builder

Related

Npm workspaces: Different "main" property for development and publishing?

I've created an npm workspace with two packages "foo" and "bar".
Furthermore, I'm using typescript so both packages contain a src/index.ts.
During development, I want to have the "main" property of both packages to be src/index.ts.
But after building and publishing the packages the "main" entry has to point to the built dist/index.js.
How can I accomplish that or is my assumption wrong, that I can point to the typescript file during development?
But then I would have to rebuild the packages during development all the time.
I hope that's not necessary.
Thank you for your help in advance
UPDATE
To be more precise, I need to have "main" point to the Typescript file src/index.ts because otherwise, I can't reference "foo" inside of "foo" itself:
// foo/src/index.ts
import { something } from 'foo';
This error is thrown:
[vite:resolve] Failed to resolve entry for package "foo". The package may have incorrect main/module/exports specified in its package.json.
The above import only works, If "main" points to src/index.ts.
Otherwise I would have to use relative paths to the imported file of the same project, for example
// foo/src/index.ts
import { something } from './someotherfile.ts';
I found out, that vite needs the plugin vite-tsconfig-paths to find my main tsconfig.json to properly resolve the project:
// vite.config.ts
import tsconfigPaths from "vite-tsconfig-paths";
plugins: [
tsconfigPaths({
root: "../../",
}),
],

How can I reduce the webpack bundle size for a Vue.js / Nuxt.js project incorporating AWS SDK?

Summary:
I have created projects, with Vue.js and Nuxt.js, where I have installed aws-amplify (which automatically installs aws-sdk) in order that I can implement authentication with AWS Cognito.
In both cases, this works very nicely, but the problems come when I build production versions.
In both cases, I end up with massive bundle sizes which (thanks to webpack-bundle-analyzer) I can immediately see are caused by the aws-sdk which appears to contain code to implement every AWS service, under the sun, despite the fact that I am only importing AWS Cognito's: "Auth" (import { Auth } from 'aws-amplify')
I have tried creating a custom AWS SDK for JavaScript, which only includes the service: AWS.CognitoIdentity, but despite incorporating that (presumably incorrectly), I still end up with the same bundle size (and aws-sdk files) when I build the projects.
As I say, this is happening in both Nuxt and Vue project, but in order to simplify this, I for now just want to find the solution to a very basic sample project created with Vue.
I think I must be doing something dumb, but I can't work out what that is.
Any help would be greatly appreciated! :-)
Steps to reproduce:
Create a basic Vue.js project with defaults. Run: vue create vue-aws-sdk-inv
[Note: Steps 2 - 4, are not crucial to reproduce issue, but install webpack-bundle-analyzer which provides useful extra info.]
In the new project, install webpack-bundle-analyzer. Run: npm install --save-dev webpack-bundle-analyzer
Create root file: vue.config.js
Add the following code to vue.config.js:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
}
};
As a benchmark, build the project. Run: npm run build
At this stage, the project will build (with no console warnings) and webpack-bundle-analyzer will launch (in the browser) showing the file: chunk-vendors..js, at the top of the tree, containing a bunch of other .js files, all of acceptable size.
Install AWS Amplify (and by default aws-sdk). Run: npm i aws-amplify
Open src/components/HelloWorld.vue and add the following under the tag: import { Auth } from "aws-amplify";
Build the project. Run: npm run build
At this stage, the project will build WITH console warnings regarding the following files being too large:
File Size Gzipped
dist/js/chunk-vendors.013ac3f0.js 3055.78 KiB 550.49 KiB
dist/js/app.fa2a21c4.js 4.67 KiB 1.67 KiB
dist/css/app.53019c4c.css 0.33 KiB 0.23 KiB
If installed, webpack-bundle-analyzer should launch (in the browser) showing an inflated: chunk-vendors..js, due to a hefty: aws-sdk.
aws-sdk will include api: .json files and lib: .js files for every AWS service I can think of!
The attempt to rectify:
Navigate to: https://sdk.amazonaws.com/builder/js/
Clear all services.
Select just: AWS.CognitoIdentity
Download "Minified" aws-sdk-.js
Download "Default" aws-sdk-.min.js
[Note: the following are the steps I am guessing I'm getting wrong?...]
In the project, search the node_modules directory for aws-sdk.js and aws-sdk.min.js.
They were found in /node_modules/aws-sdk/dist
Replace both files with the downloaded files (renaming to aws-sdk.js and aws-sdk.min.js respectively.)
Build the project. Run: npm run build
Project will build with same console warnings and same massive aws-sdk, as before, containing all the same .js and .json files for a bunch of services that are not actually imported in the application.
Final pieces of analysis:
Remove aws-sdk.js and aws-sdk.min.js from project's: /node_modules/aws-sdk/dist
Build the project. Run: npm run build
Project is built without even referencing these files.
Rename /node_modules/aws-sdk to /node_modules/TEMP_aws-sdk and attempt to build the project.
Build fails, and this proves (I think) that I was at least trying to add the custom versions, of aws-sdk.js and aws-sdk.min.js, somewhere in the correct directory!
Source Code:
vue.config.js:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
}
};
src/components/HelloWorld.vue:
import { Auth } from "aws-amplify";
As said before, any help would be greatly appreciated! :-)
It looks like import { Auth } from "aws-amplify"; doesn't currently allow for tree shaking according to this issue.
Reading through several related issues, it appears that:
import Auth from '#aws-amplify/auth';
is the best you can currently do. I suspect that over time, the AWS team will figure out a way to better separate the internals.
For readers looking for a way to reduce bundle sizes for the aws-sdk package, see this section of the docs.
In my case:
import S3 from 'aws-sdk/clients/s3';
import AWS from 'aws-sdk/global';
cut the bundle size down by quite a lot. That gets it down to ~57k gz to use S3.
Also, for anyone using nuxt you can just run nuxt build -a to get the build analyzer.

Running Vuetify on Vert.x (w/ES4X)

I'm wondering if it's possible to run Vuetify (out-of-the-box) with Vert.x. I've played around a bit and I don't see a straightforward way but perhaps I'm missing something.
Sources:
https://vuetifyjs.com/en/getting-started/quick-start
https://reactiverse.io/es4x/start/install
Steps:
Create an out-of-the-box Vuetify:
npm install #vue/cli -g
vue create my-app
cd my-app
vue add vuetify
Test that it works by running it in Node
npm run start
When I view http://localhost:8080 (using node) it looks good. So I
create a compiled version in a dist folder
npm run build
Now I would like to try and get it working in Vert.x So I add ES4X, which is supposed to allow ES 5+ js code
npm install -g es4x-pm
es4x init
npm install #vertx/unit --save-dev
npm install #vertx/core --save-prod
npm install #vertx/web --save-prod
npm install
Create an index.js file so vert.x server for the index.html
vertx.createHttpServer().requestHandler(function (req){
req.response().sendFile("dist/index.html");
}).listen(8080);
Run Vert.x
npm start
When I view http://localhost:8080 it does not show as expected. It looks like a blank page. When I view the source code of the page in a browser, it shows the contents of the index.html file. So I know it's loading it, just not interpreting it. When I view the console I see a log entry saying Syntax error: Expected expression, got '<'
Note - I would like to avoid going the 'CDN install' route shown on the Vuetify quick-start link. My project is fairly complex and I just wanted to test how Vuetify by itself worked with Vert.x before tying in all the other dependencies
You've added a bare request handler, think of it as using just core nodejs modules. In order to serve multiple files and resources you should use vertx-web (which you already installed). In this case your code should be:
import { Router, StaticHandler } from '#vertx/web';
// router acts like express if you're familiar with it
const app = Router.router(vertx);
// for any HTTP GET request this will be your
// first handler "dist" is your static files root dir
app.get().handler(StaticHandler.create("dist"));
// add more handlers as needed...
vertx.createHttpServer()
.requestHandler(app)
.listen(8080);
So now all your static files should be served correctly...
Not sure I'm grokking this question.
Vuetify is runs in the browser, Es4x runs on the server.
You just need way to serve the static 'dist' folder, as described above.
ps: I'm assuming you're not doing server-side rendering, in which case, I'm not sure if es4x will work (it might).

process.env.NODE_ENV is not working with webpack3 [duplicate]

I've got an existing code base in which Vue.js has performance problems. I also see this notice in the browser console:
so I guess an easy fix could be to put Vue into production mode.
In the suggested link I try to follow the instructions for webpack. We're on Webpack version 2.7 (current stable version is 4.20). In the instructions it says that in Webpack 3 and earlier, you’ll need to use DefinePlugin:
var webpack = require('webpack')
module.exports = {
// ...
plugins: [
// ...
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
}
So in my package.json I've got a build script defined:
To build for production I run yarn run build and it runs a build.js file (paste here) which in turn calls webpack.base.conf.js (paste here) and webpack.prod.conf.js (paste here).
As you can see in the paste I use the DefinePlugin as suggested by the docs.
I also found a file called vue-loader.conf.js (paste here) and to be sure I also added the DefinePlugin in there as well.
I can run yarn run build which ends without errors, but when serve the site over Apache and open the browser it still shows the notification that we're in development mode.
To be sure it actually uses the files created by webpack I completely removed the folder /public/webpack/ and checked that the webinterface didn't load correctly without the missing files and then built again to see if it loaded correctly after the command finished. So it does actually use the files built by this webpack process. But Vue is actually not created in production mode.
What am I doing wrong here?
The problem may be in your 'webpack.base.conf.js' as i suspected, thank you for sharing it, upon searching i've found an issue resolving your 'production not being detected' problem on github here
The solution requires that you change 'vue$': 'vue/dist/vue' to 'vue$': vue/dist/vue.min in production.
You will find the original answer as:
#ozee31 This alias 'vue$': 'vue/dist/vue' cause the problem, use vue/dist/vue.min in production environment.

Elm "cannot find module"

I'm fairly new in Elm. It's interesting to see a functional language which allows you to develop front-end stuff. Now even if I am following the steps described here nicely, I still have problems with modules.
The code is
module Main where
import Html exposing ( Html )
import Signal
main : Signal Html.Html
main = Html.text "This should work."
|> Signal.constant
I have used elm-reactor -a='localhost' to be able to view my output. But I am getting an error, that module 'HTML' cannot be found:
I cannot find find module 'Html'.
Module 'Main' is trying to import it.
Potential problems could be:
* Misspelled the module name
* Need to add a source directory or new dependency to elm-package.json
(note the double "find" hehe)
The fix suggestion didn't help me. Or it could be that I'm not understanding the use of the .json file correctly.
elm-package.json:
{
"version": "1.0.0",
"summary": "testing elm",
"license": "BSD3",
"source-directories": [
".",
"./bin/"
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "3.0.0 <= v < 4.0.0"
},
"elm-version": "0.16.0 <= v < 0.17.0"
}
Here is a screenshot of my file tree.
Maybe it behaves differently than how Haskell is threatening the modules.
How can I solve this - eh simple? - problem.
Or is my elm-package.json just configured incorrectly?
Update for Elm 0.17
In 0.17, the Html package has been moved to elm-lang/html. Run the following command from the terminal to install it:
elm package install elm-lang/html
You should also remove the evancz/elm-html package from elm-package.json because it no longer exists as of 0.17.
For more information about the upgrading from 0.16 to 0.17, please see the 0.17 announcement.
Original Answer for Elm 0.16
Your elm-package.json configuration is missing the evancz/elm-html package, which exposes Html. You can use elm's package manager to install dependencies rather than editing elm-package.json directly.
From the terminal, type the following:
elm package install evancz/elm-html
You will also be prompted to install a few other missing dependencies required by evancz/elm-html. Running this command will update your elm-package.json file as well as pull down the missing packages from the internet and install them in the standard elm-stuff/packages directory.
More info on the elm-package tool can be found here.
You can browse elm packages online at package.elm-lang.org. The sidebar has a Popular Packages section which contains the evancz/elm-html package mentioned here.