ng build --prod --aot --preserve-symlinks give Module not found for lazy load module from extenal link package - angular2-routing

I am new to AOT build and angular2 deployments.
I am using Angular 2 with Node # 6.11.0, NPM # 4.6.1 and #Angular/CLI # 1.4.2
I have two projects where one is the host application (UI-Host) and the other is the actual application(UI-Core). I link and package the UI code and link it inside the host application i.e.
cd frontEnd/UI-Core
call npm i
call npm link .\src
and in host application:
cd UI-Host
call npm i
call npm link UI-Core
call npm run build:prod
package.json -> scripts has got the following entry:
"build:prod": "ng build --prod --aot --preserve-symlinks"
I am using a lazy loaded module in the UI which is running fine with ng build and throwing the error as shown in the attachment with --aot prod build.
I am not able to figure out what is wrong with my setup. Please find below the code i am using.
frontend/UI-Core:
----------------
ui-core.routing.ts
--------------------------
const routes: Routes = [
{
path: 'workflows',
canActivate: [AuthGuard],
loadChildren: './components/imported/admin/admin.module#AdminModule'
},
{ path: 'login', component: LogonPageComponent },
{ path: '', pathMatch: 'full', redirectTo: 'login' }
];
export const CoreRouting = RouterModule.forChild(routes);
index.ts
--------
#NgModule({
imports: [
CoreRouting
]
})
export class UICoreModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: UICoreModule,
providers: [
AuthService,
AuthGuard
]
};
}
}
Host application ( frontend/UI-Host)
----------------
app.module.ts
-------------
#NgModule({
imports: [
CUSTOM_IMPORTS
]
})
export class AppModule { }
custom\custom.app.ts
----------------------
import { UICoreModule } from 'ui-core';
export const CUSTOM_IMPORTS: any[] = [
UICoreModule.forRoot()

You may try for this:
Here we did aot false , which will not check all the depecies during production. use following.
ng build --prod --aot=false.

Related

Missing required argument `file|environment' - PM2

I am trying to launch my nextjs app through PM2. I have configured PM2 in ecosystem.config.js file and starting my nextjs app as pm2 start my-app. That's work perfectly fine.
Now I also want PM2 to pull from my github repo then run a custom script that I provided undeer post-deploy key. After setting up my github repo through ssh, I tried to run PM2 as pm2 deploy but that gives me following error
error: missing required argument 'file|environment'
ecosystem.config.js
module.exports = {
apps: [
{
name: 'next-app',
script: 'npm run start',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}
],
deploy: {
production: {
user: 'ubuntu',
host: ["123.12.12.123"],
key: '~/.ssh/id_ed25519.pub',
ssh_options: 'ForwardAgent=yes',
ref: 'origin/branch-12',
repo: 'git#github.com:my-username/my-repo.git',
path: '/var/www/my-project/',
'pre-deploy': "git fetch --all && git reset --hard origin/branch-12",
'post-deploy': 'sh nextjs-pm2-deploy.sh'
}
}
};

How to transpile node_modules with Turborepo and SWC

next-transpile-modules works great for Next projects, but how do I transpile modules for a raw SWC build??? I stumped 😭
Repo: https://github.com/deltaepsilon/script-kitty
I started from a Turborepo base and exported two packages, ui and command-k into a Turborepo Next app named web. Everything worked great once I added ui and command-k to the next.config.js file like so:
const withTM = require('next-transpile-modules')(['command-k', 'ui']);
module.exports = withTM({
reactStrictMode: true,
});
Now I've got a new app named external that's going to be a standalone build of the command-k package. This will get published to npm.
I'm using swc-loader to transpile it with the following config:
const path = require('path');
// See https://github.com/iykekings/react-swc-loader-template
const config = {
mode: 'development',
entry: './index.tsx',
module: {
rules: [
{
test: /\.(ts|tsx)$/,
loader: 'swc-loader',
include: [
path.resolve(__dirname),
path.resolve(__dirname, '../../packages/command-k'),
path.resolve(__dirname, '../../packages/ui'),
],
exclude: /node_modules/,
},
],
},
};
module.exports = config;
I keep getting the following error when building with yarn dev:
ERROR in ../../packages/command-k/index.tsx 2:0-50
Module not found: Error: Can't resolve './command-k' in '/kitty/packages/command-k'
resolve './command-k' in '/kitty/packages/command-k'
using description file: /kitty/packages/command-k/package.json (relative path: .)
// /packages/command-k/index.tsx
import * as React from 'react';
export { default as CommandK } from './command-k';
It looks like swc-loader is somehow unable to import from inside of a Turborepo package. It works fine if I inline the contents of ./command-k into /packages/command-k/index.tsx, but swc-loader refuses to follow the import.

Firebase webpack+babel functions not deploying

Is it possible to make firebase functions work with webpack and babel?
We need to reuse existing ES6 classes on server side which we can't edit so we need to transpile them to make it work in node.
Spent two days on the related tutorials but I'm hitting the problem where firebase can't seem to see functions declared in index.js after they were wrapped by webpack in a function.
here is a part of the resulting index.js:
(function(module, exports, __webpack_require__) {
var functions = __webpack_require__(/*! firebase-functions */ "firebase-functions");
var admin = __webpack_require__(/*! firebase-admin */ "firebase-admin");
admin.initializeApp();
exports.api = functions.https.onRequest(function (req, res) {
res.send({
msg: "ok"
});
});
})
exports.api = functions.https.onRequest is not deploying in this case.
Is it ever possible to make firebase work with webpack and babel?
I had a similar challenge. I am not completely satisfied with how things are automated on the dev side (I will give more time on that during the next few days), but it is working indeed.
I will try to tell how I did it by changing code and instructions to remove unrelated complexity.
My main goal is not to manually maintain a "functions" folder with its own package.json as a separate project from my main one. Everything that resides in the root source code and some webpack magic should suffice.
1 - My entry point source code in a app.js file inside a /src/main folder. It reads like this:
import * as functions from 'firebase-functions';
import { someProcessedOutputThatDependsOnExternalLibraries } from './my-code';
export const hello = functions.https.onRequest((req, res) => {
functions.logger.info('Hello logs!', { structuredData: true });
const output = someProcessedOutputThatDependsOnExternalLibraries(req)
res.send(output).end();
});
2 - I want to export it to a /dist folder, so I have to set up that folder in the firebase.json file in the project root:
{
"functions": {
"source": "dist"
},
"emulators": {
"functions": {
"port": 5001
},
}
}
3 - The package.json file in the root holds all the information needed for the project, especially the dependencies and useful scripts. Here some of the file content to illustrate.
{
"scripts": {
"env:firebase": "firebase emulators:start",
"build:firebase": "webpack --config webpack.firebase.js",
},
"dependencies": {
"axios": "^0.21.0",
"core-js": "^3.8.1",
"firebase-admin": "^9.4.2",
"firebase-functions": "^3.13.1",
"inquirer": "^7.3.3",
"regenerator-runtime": "^0.13.7",
"rxjs": "^6.6.3",
"uuid": "^8.3.2",
"xstate": "^4.15.3"
},
"devDependencies": {
"generate-json-webpack-plugin": "^2.0.0",
"webpack": "^5.15.0",
"webpack-cli": "^4.3.1",
"webpack-node-externals": "^2.5.2"
}
}
4 - Webpack is used to build a dist folder compatible with firebase specs. The webpack file below is almost entirely copied from this blessed github gist.
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const GenerateJsonPlugin = require('generate-json-webpack-plugin');
const pkg = require('./package.json');
const genFirebaseFunctionsPackage = () => ({
name: 'functions',
private: true,
main: 'index.js',
license: 'MIT',
engines: {
node: '14'
},
dependencies: pkg.dependencies
});
module.exports = {
target: 'node',
mode: 'production',
entry: './src/main/functions.js',
externals: [nodeExternals()],
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs'
},
node: {
__dirname: false,
__filename: false
},
optimization: {
minimize: false
},
plugins: [new GenerateJsonPlugin('package.json', genFirebaseFunctionsPackage())]
};
5 - So, if I run npm run build:firebase, the dist folder is created with index.js and package.json files. The dist dir is now compatible with firebase CLI and emulator expectations.
But to run it in the local emulator, I still have to go to that folder and type "npm install" (that's the pain point I'm still trying to solve).
It's a good idea to bundle your functions app using webpack for alot of reasons:
access to webpack loaders/plugins
much better developer experience with HMR (that works better than the functions runtime's implementation)
better performance for deployment and runtime (one or a few optimized chunks vs hundreds/thousands of unoptimised/unused files)
Many of the requirements are covered in this answer, but rather than making it all yourself, you might have an easier time using webpack-cloud-functions (of which I'm the author). It abstracts away much of the configuration you need to do that - e.g. libraryTarget, some of the externals, etc, and also provides reliable HMR for development out of the box.

NextJS/Webpack does not build node_module dependency with internal css

I have a couple of issues with a NextJS project that I believe might be solvable with a well built webpack configuration (However I am fairly new to webpack).
I am using NextJS 8.0.3 with #zeit/next-css 1.0.2-canary in my local NextJS project, and I have a couple of npm installed dependencies that use css internally (styled reusable components).
The issue that I'm having is that I can't build or export my application because I get a CssSyntax error, and if I use next-plugin-transpile-modules it will build the installed node_modules dependencies but it won't load the css, because it does not build it.
This is the next.config.js file content, if you find the webpack part you will notice that it just uses the basic css-loader.
module.exports = withBundleAnalyzer(withCss({
poweredByHeader: false,
cssModules: false,
// assetPrefix: APP_PREFIX, // This actually sets the path for getting static files somewhere else?*
publicRuntimeConfig: { // Will be available on both server and client
// pathPrefix: APP_PREFIX,
cache: {
static: {
cdn: 3600,
browser: 3600
},
dynamic: {
cdn: 600,
browser: 0
}
}
},
webpack: (config, { defaultLoaders }) => {
// Fixes npm packages that depend on `fs` module
config.module.rules.push({
test: /\.css$/,
use: [
'css-loader',
'style-loader',
]
});
config.node = { fs: 'empty' }
// console.log(config)
return config
},
// bundle analyzer
analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE),
analyzeBrowser: ["browser", "both"].includes(process.env.BUNDLE_ANALYZE),
bundleAnalyzerConfig: {
server: {
analyzerMode: 'static',
reportFilename: '../bundles/server.html'
},
browser: {
analyzerMode: 'static',
reportFilename: '../bundles/client.html'
}
}
}))
My most immediate question is, what webpack loader or what pipeline configuration can I use so that webpack actually builds the css that is imported from the jsx dependency, and then build the component properly so that it's internal css and of course it's functionality are fully built.

.Net Core 2 Spa Template with Angular Material

Struggling trying to get Angular Material , or any 3rd party control set really, to work with this new template. In this new template, the webpack is broken into TreeShakable and NonTreeShakable. In addition the app.module is now app.module.shared, app.module.browser, app.module.server.
As I have attempted to get this to work, the app will only run with modules configured in app.module.browser, but the material tags are not getting processed. Trying something simple and trying the button. I don't get any errors but not does it work. I went to their example in Plunker, copied what it generated, and it displays right telling me I got the css in right, at least.
Including the webpack vendor configuration as a starting point, as this seems to be key because how it bundles the css and js.
TIA
Webpack.vendor
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const merge = require('webpack-merge');
const treeShakableModules = [
'#angular/animations',
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/forms',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'#angular/material',
'#angular/cdk',
'zone.js'
];
const nonTreeShakableModules = [
'bootstrap',
'jqwidgets-framework',
"#angular/material/prebuilt-themes/indigo-pink.css",
'bootstrap/dist/css/bootstrap.css',
'font-awesome/css/font-awesome.css',
'es6-promise',
'es6-shim',
'event-source-polyfill',
'jquery',
];
const allModules = treeShakableModules.concat(nonTreeShakableModules);
module.exports = (env) => {
const extractCSS = new ExtractTextPlugin('vendor.css');
const isDevBuild = !(env && env.prod);
const sharedConfig = {
stats: { modules: false },
resolve: { extensions: [ '.js' ] },
module: {
rules: [
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }
]
},
output: {
publicPath: 'dist/',
filename: '[name].js',
library: '[name]_[hash]'
},
plugins: [
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.ContextReplacementPlugin(/\#angular\b.*\b(bundles|linker)/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/11580
new webpack.ContextReplacementPlugin(/angular(\\|\/)core(\\|\/)#angular/, path.join(__dirname, './ClientApp')), // Workaround for https://github.com/angular/angular/issues/14898
new webpack.IgnorePlugin(/^vertx$/) // Workaround for https://github.com/stefanpenner/es6-promise/issues/100
]
};
const clientBundleConfig = merge(sharedConfig, {
entry: {
// To keep development builds fast, include all vendor dependencies in the vendor bundle.
// But for production builds, leave the tree-shakable ones out so the AOT compiler can produce a smaller bundle.
vendor: isDevBuild ? allModules : nonTreeShakableModules
},
output: { path: path.join(__dirname, 'wwwroot', 'dist') },
module: {
rules: [
{ test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) }
]
},
plugins: [
extractCSS,
new webpack.DllPlugin({
path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
name: '[name]_[hash]'
})
].concat(isDevBuild ? [] : [
new webpack.optimize.UglifyJsPlugin()
])
});
const serverBundleConfig = merge(sharedConfig, {
target: 'node',
resolve: { mainFields: ['main'] },
entry: { vendor: allModules.concat(['aspnet-prerendering']) },
output: {
path: path.join(__dirname, 'ClientApp', 'dist'),
libraryTarget: 'commonjs2',
},
module: {
rules: [ { test: /\.css(\?|$)/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] } ]
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, 'ClientApp', 'dist', '[name]-manifest.json'),
name: '[name]_[hash]'
})
]
});
return [clientBundleConfig, serverBundleConfig];
}
You need to include angular material and cdk in nonTreeShakableModules like:
const treeShakableModules = [
'#angular/animations',
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/forms',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
'#angular/router',
'zone.js',
];
const nonTreeShakableModules = [
'bootstrap',
'bootstrap/dist/css/bootstrap.css',
'#angular/material',
'#angular/material/prebuilt-themes/indigo-pink.css',
'#angular/cdk',
'es6-promise',
'es6-shim',
'event-source-polyfill',
'jquery',
];
Make sure you have installed both angular material and cdk modules from npm with the following 2 commands (animations module is optional):
npm install --save #angular/material #angular/cdk
npm install --save #angular/animations
This should add the following lines in package.json:
"#angular/animations": "https://registry.npmjs.org/#angular/animations/-/animations-4.2.5.tgz",
"#angular/cdk": "^2.0.0-beta.8",
"#angular/material": "^2.0.0-beta.8",
You now should try executing webpack build with following command in cmd or PowerShell:
webpack --config webpack.config.vendor.js
If there are no errors you can include the components you want to use in app.module.shared.ts:
// angular material modules
import {
MdAutocompleteModule,
MdButtonModule,
MdButtonToggleModule,
MdCardModule,
MdCheckboxModule,
MdChipsModule,
MdCoreModule,
MdDatepickerModule,
MdDialogModule,
MdExpansionModule,
MdGridListModule,
MdIconModule,
MdInputModule,
MdListModule,
MdMenuModule,
MdNativeDateModule,
MdPaginatorModule,
MdProgressBarModule,
MdProgressSpinnerModule,
MdRadioModule,
MdRippleModule,
MdSelectModule,
MdSidenavModule,
MdSliderModule,
MdSlideToggleModule,
MdSnackBarModule,
MdSortModule,
MdTableModule,
MdTabsModule,
MdToolbarModule,
MdTooltipModule,
} from '#angular/material';
import { CdkTableModule } from '#angular/cdk';
and add them to imports in #NgModule
There are still some components that are bugged until next fixes. Like the checkbox component which breaks server-side rendering when you refresh page. But it will be fixed in the next release (it has been already on master branch).
Using latest Angular Material in ASP.net Core 2.0 with default installed node packages is more difficult and time consuming for resolving package dependencies.
Use below version of angular material in package.json
"#angular/cdk": "^2.0.0-beta.12"
"#angular/material": "^2.0.0-beta.12"
followed by run below command to install it.
npm install --save

Resources