Microfrontend: cannot find module or its corresponding type declarations in dynamic import - micro-frontend

The TS compiler complains about the following code snippet:
import('HelloWorldApp/HelloWorldButton')
.then(HelloWorldButtonModule => {
const HelloWorldButton = HelloWorldButtonModule.default;
const helloWorldButton = new HelloWorldButton();
helloWorldButton.render();
});
this: Cannot find module 'HelloWorldApp/HelloWorldButton' or its corresponding type declarations.
Tried adding declare module 'HelloWorldApp/HelloWorldButton' to a declaration.d.ts file specified in tsconfig.json but to no avail.
How do I fix it?

//types.d.ts inside src folder
declare module 'host/NewComponent'
module type declaration problem solved by types.d.ts
Please take look properly on config file for host project .
I was facing same issues then I used -
optimization:{
splitChunks: false,
}
you will find optimization on vue.config.js file of host project
take a look into the config files -
//*vue.config.js* for host project
const { defineConfig } = require('#vue/cli-service')
const ModuleFederationPlugin =
require("webpack").container.ModuleFederationPlugin;
module.exports = defineConfig({
publicPath:"http://localhost:8000/",
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: "host",
filename: "remoteEntry.js",
exposes: {
"./NewComponent": "./src/components/NewComponent.vue",
},
}),
],
optimization:{
splitChunks: false,
}
},
devServer: {
port: 8000,
},
});
Though version doesn't matter here but I want to inform you that I'm using vue 3 .
//vue.config.js for consumer project
const { defineConfig } = require('#vue/cli-service')
const ModuleFederationPlugin =
require("webpack").container.ModuleFederationPlugin;
module.exports = defineConfig({
publicPath:"http://localhost:8001/",
configureWebpack: {
plugins: [
new ModuleFederationPlugin({
name: "consumer",
remotes: {
host: "host#http://localhost:8000/remoteEntry.js",
},
}),
],
},
devServer: {
port: 8001,
},
});
And Finally I used the component from host in consumer project.
//HelloWorld.vue component in consumer project
<template>
<div>
<otherComp></otherComp>
</div>
</template>
<script lang="ts">
import { defineAsyncComponent, defineComponent } from 'vue';
const otherComp = defineAsyncComponent(() => import("host/NewComponent"));
export default defineComponent({
name: 'HelloWorld',
components:{
otherComp,
},
props: {
msg: String,
}
});
</script>
****Everything is works fine for me .Hoping it will also solve your and others problem to build micro front end . Happy Coding ****

Related

testing a vue3 component with <router-link> with jest

I got this test from another site. They are injecting a mock route. I think I need to mock router itself or pass a real one into the test so the page can run. There is a way to do this in vue 2, but I haven't found an example for vue 3.
import { mount } from "#vue/test-utils";
import Nav from "./Nav.vue";
test("it displays a menu item", () => {
const mockRoute = {
params: {
id: 1,
},
};
const mockRouter = {
push: jest.fn(),
};
const wrapper = mount(Nav, {
props: {
isAuthenticated: true,
},
global: {
mocks: {
$route: mockRoute,
$router: mockRouter,
},
},
});
expect(wrapper.find("#navLabel_0").text()).toEqual("Appointments");
});
The component I'm testing has tags.
The test fails with:
Failed to resolve component: router-link
You have to pass the router-link as a stub: stubs: ['router-link'] when you mount the component:
const wrapper = mount(Nav, {
props: {
isAuthenticated: true,
},
global: {
mocks: {
$route: mockRoute,
$router: mockRouter,
},
},
stubs: ['router-link'] });

Unable to hide api key in angular10 environment variable

Im trying to hide api key in my angular project environment using #angular-builders/custom-webpack which will fetch value from system environment variable through process.env during build .
But after sucessful build , i'm still able to see the actual value in main.js file.
//custom.webapack.config
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
"nvar": {
ENVIRONMENT: JSON.stringify(process.env.ENVIRONMENT),
SomeAPIKey: JSON.stringify(process.env.DDSK),
SomeOtherAPIKey: JSON.stringify(process.env.SomeOtherAPIKey)
}
})
]
};
//typings.d.ts
declare var nvar: Env;
interface Env {
ENVIRONMENT: string;
SomeAPIKey: string;
SomeOtherAPIKey: string;
}
environment.ts
export const environment = {
production: true,
apiURL: 'some api url',
appUrl:''some url,
googleClientId:'client key',
__dds:nvar.SomeAPIKey
}
//angular.json
"builder":"#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path":"custom-webpack.config.js"
},
Output

Connecting and retrieving data from MongoDB doesn't work using nodemon (Mongoose + Typegoose)

[Contextualizing]
I have a simple NodeJS project using Mongodb, Mongoose (with Typegoose) and Nodemon.
In my package.json I have commands for developer and production environments.
...
"start-dev": "nodemon src/index.ts",
"start-prd": "node dist/index",
...
For the start-prd command, I am using webpack to generate the binaries.
This is my webpack.config.
const webpack = require("webpack");
const path = require("path");
const nodeExternals = require("webpack-node-externals");
module.exports = {
mode: "dsv",
entry: ["webpack/hot/poll?100", "./src/index.ts"],
watch: true,
target: "node",
externals: [
nodeExternals({
allowlist: ["webpack/hot/poll?100"]
})
],
module: {
rules: [
{
test: /.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
}
]
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
plugins: [new webpack.HotModuleReplacementPlugin()],
output: {
path: path.join(__dirname, "dist"),
filename: "index.js"
}
};
I have a Delivery model class mapped with Typegoose ...
import { prop } from '#typegoose/typegoose';
import { Typegoose } from 'typegoose';
export class Delivery extends Typegoose {
#prop()
name: string;
#prop()
description?: string;
#prop()
services: string[];
#prop()
rating?: number;
};
... and I define the repository like this.
import mongoose from 'mongoose';
import { Delivery } from '../entities/delivery';
export class DeliveryRepository {
async list(): Promise<Delivery[]> {
await mongoose.connect('mongodb://usr:passw#localhost:21017/my_db',
{
auth: {
user:"usr",
password:"passw"
},
useNewUrlParser: true,
useUnifiedTopology: true
});
const Model = new Delivery().getModelForClass(Delivery, {
existingMongoose: mongoose,
schemaOptions: {collection: 'deliveries'}
});
return Model.find({});
}
}
Calling the API with the get method.
...
app.route('/api/deliveries').get((req, res) => {
var repo = new DeliveryRepository();
repo.list().then((result) => {
res.status(200).send(result);
}).catch(r => console.log(r));
})
...
[Scenario]
If run prd script.
1. npm run webpack
2. npm run start-prd
It works perfectly! I call the api get method and list my objects.
When run dev script.
1. npm run start-dev
Nodemon starts normally, but when calling the api get method error occurs ...
TypeError: Cannot read property '_id' of undefined
at Schema.add (D:\pessoal\workspaces\omeurestaurante-api\node_modules\mongoose\lib\schema.js:462:11)
at _buildSchema (D:\pessoal\workspaces\omeurestaurante-api\node_modules\typegoose\src\typegoose.ts:134:9)
at Delivery.buildSchema (D:\pessoal\workspaces\omeurestaurante-api\node_modules\typegoose\src\typegoose.ts:109:13)
at Delivery.setModelForClass (D:\pessoal\workspaces\omeurestaurante-api\node_modules\typegoose\src\typegoose.ts:78:22)
at Delivery.getModelForClass (D:\pessoal\workspaces\omeurestaurante-api\node_modules\typegoose\src\typegoose.ts:52:12)
at SessionDb.getModel (D:\pessoal\workspaces\omeurestaurante-api\src\db\session-db.ts:29:24)
at DeliveryRepository.<anonymous> (D:\pessoal\workspaces\omeurestaurante-api\src\repositories\delivery.repository.ts:16:30)
at Generator.next (<anonymous>)
at D:\pessoal\workspaces\omeurestaurante-api\src\repositories\delivery.repository.js:8:71
at new Promise (<anonymous>)
at __awaiter (D:\pessoal\workspaces\omeurestaurante-api\src\repositories\delivery.repository.js:4:12)
at DeliveryRepository.list (D:\pessoal\workspaces\omeurestaurante-api\src\repositories\delivery.repository.js:22:16)
at app.route.get (D:\pessoal\workspaces\omeurestaurante-api\src\index.ts:40:8)
at Layer.handle [as handle_request] (D:\pessoal\workspaces\omeurestaurante-api\node_modules\express\lib\router\layer.js:95:5)
at next (D:\pessoal\workspaces\omeurestaurante-api\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\pessoal\workspaces\omeurestaurante-api\node_modules\express\lib\router\route.js:112:3)

Unable to acess links (copying and pasting) whitin my Site : Node.js - Express.js - Webpack - Vue.js - historymode

I recently created a website with base on Node.js, Express.js and Vue.js with router in history mode and Webpack.
Since is a Single Page Application, I installed express-history-api-fallback and it works quite fine so far but (as always there is a but) for some reasons that I'm not understanding for some urls, i get a white page and some errors like:
Uncaught SyntaxError: Unexpected token '<' ------ manifest.61d5cd8248647cdb144a.js:1
Uncaught SyntaxError: Unexpected token '<' ------ vendor.db7271094dc9fcde8b9f.js:1
Uncaught SyntaxError: Unexpected token '<' ------ app.3cfe27cef1608de00b06.js:1
I don't understand whether the problem is within my webpack conf file or withing my node.js (I guess is related to the front-end cause I'm not seeing any incoming request in the be) or in my vue-router.
The reason why I don't understand (apart of lack of knowledge) is that if I try to access to a page within my Vue app, clicking on a link (i.e. accessing to an user's profile page formatted as mywebsiteinexample.com/user/userId) it works but if i refresh the page I'm just able to see a white page and, inside the console, the errors I wrote about above.
The general architecture of my files:
here are some, I guess, useful peaces of code:
Server.js
const express = require('express')
const fallback = require('express-history-api-fallback')
const path = require('path')
const historyModeHandlerHTTP = express()
const root = `${__dirname}/../`
historyModeHandlerHTTP.use(express.static(root))
historyModeHandlerHTTP.use(fallback(path.join(__dirname + '/../index.html')))
historyModeHandlerHTTP.listen(80, () => {
console.log('HTTP Server on')
})
Webpack.prod.conf.js
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRootMain,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.ProgressPlugin(),
new CleanWebpackPlugin({
dry: false,
cleanOnceBeforeBuildPatterns: [config.build.assetsSubDirectory + '*/js/*', config.build.assetsSubDirectory + '*/css/*']
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
allChunks: true,
}),
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap ?
{
safe: true,
map: {
inline: false
}
} :
{
safe: true
}
}),
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'template.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: false,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks(module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
new CopyWebpackPlugin([{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
const config = require('../config')
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost',
port: 8080,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false,
devtool: 'cheap-module-eval-source-map',
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../../index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsRootMain: path.resolve(__dirname, '../../'),
assetsSubDirectory: 'front-end/static',
assetsPublicPath: '',
mainfile : 'front-end/src/main.js',
routerfile : 'front-end/src/router/index.js',
constantsFile : 'utils-bf/constants.js',
productionSourceMap: true,
devtool: '#source-map',
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
bundleAnalyzerReport: process.env.npm_config_report
}
}
[SOLUTION]
The Problem was related to the configuration of Webpack!
If anyone is facing the same problem, just set the PublicPath : '/'
output: {
publicPath: '/',
path: config.build.assetsRootMain,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},

Unable to use custom Componets in AdminBro

I am using admin-bro with express js and everything seemed to me be working fine until I tried to add custom component to change an input field of a resource. Following is the code I am using.
EditLogoField.jsx
const React = require('react');
class EditLogoField extends React.PureComponent {
render() {
return (
<input type='file'/>
);
}
}
module.exports = EditLogoField;
I am trying to use it like this
const AdminBro = require('admin-bro');
module.exports = {
properties: {
logo: {
type: 'string',
isVisible: {
list: false,
edit: true,
filter: false,
show: true,
},
components: {
edit: AdminBro.bundle('../components/serviceProviderCompany/EditLogoField')
}
},
},
};
All I get is this
Had the same issue. Spent whole day trying to solve it.
Build failed on both Windows and Ubuntu systems.
My path to the project folder had a '.' symbol in it 'C:\.code\Projects' which
also caused recently some issues with Unity project.
Solution:
move project into a folder that doesn't have a '.' symbol in its path.

Resources