add pagination for table angular5 - angular5

I want to add pagination for table i have tried ngx-pagination but it seems to be not working with angular5:
just an example
<table>
<tr *ngFor="let x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
have searched a lot but found this:
ngx-pagination
this package gives me the error while importing saying :
cannot resolve symbol NgxPaginationModule
I am using angular5
package.json
{
"name": "eci",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "node app.js",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"#angular/animations": "^5.2.0",
"#angular/common": "^5.2.0",
"#angular/compiler": "^5.2.0",
"#angular/core": "^5.2.0",
"#angular/forms": "^5.2.0",
"#angular/http": "^5.2.0",
"#angular/platform-browser": "^5.2.0",
"#angular/platform-browser-dynamic": "^5.2.0",
"#angular/router": "^5.2.0",
"angular-font-awesome": "^3.1.2",
"angular2-json2csv": "^1.1.2",
"angular5-csv": "^0.2.8",
"bootstrap": "^4.1.0",
"cfenv": "^1.0.4",
"core-js": "^2.4.1",
"express": "^4.15.0",
"font-awesome": "^4.7.0",
"ngx-pagination": "^3.1.1",
"rxjs": "^5.5.6",
"zone.js": "^0.8.19"
},
"devDependencies": {
"#angular/cli": "~1.7.2",
"#angular/compiler-cli": "^5.2.0",
"#angular/language-service": "^5.2.0",
"#types/jasmine": "~2.8.3",
"#types/jasminewd2": "~2.0.2",
"#types/node": "~6.0.60",
"codelyzer": "^4.0.1",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~2.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~4.1.0",
"tslint": "~5.9.1",
"typescript": "~2.5.3"
}
}

Try to import NgxPaginationModule in app.module.ts. Try this
// app.module.ts
import {NgModule} from '#angular/core';
import {BrowserModule} from '#angular/platform-browser';
import {NgxPaginationModule} from 'ngx-pagination'; // <-- import the module
import {MyComponent} from './my.component';
#NgModule({
imports: [BrowserModule, NgxPaginationModule], // <-- include it in your app module
declarations: [MyComponent],
bootstrap: [MyComponent]
})
export class MyAppModule {}

(at first sorry for my bad english)
For this to work you can do this:
( 1 ) add library with this command: npm install ngx-pagination#3.1.1 --save ( #3.1.1 -> just in case you must use this version)
and then
( 2 ) import this library to your app.module.ts (after doing this, your app.module looks like this):
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommonModule } from '#angular/common';
import { NgxPaginationModule } from 'ngx-pagination'; /* import NgxPaginationModule here */
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
CommonModule, /* always check has this line this */
NgxPaginationModule /* add NgxPaginationModule to your imports */
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
and add this to your component in which you want to use this module:(i add it to my app.component.ts):
page = 1;
and my app.component.ts after this change is:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
// Your Data
names: any = [
{
Name: 'frank',
Country: 'US'
},
{
Name: 'joe',
Country: 'fanland'
},
{
Name: 'mary',
Country: 'nourthAmerica'
},
{
Name: 'elina',
Country: 'US'
},
{
Name: 'emmi',
Country: 'Argentina'
},
{
Name: 'jully',
Country: 'Belize'
},
{
Name: 'mariana',
Country: 'Cameroun'
},
{
Name: 'shivana',
Country: 'Costa Rica'
},
{
Name: 'jullietta',
Country: 'Danemark'
}];
// number
page = 1; /* this show page in pagination controller after page load */
constructor() {}
}
Now how to use it?
Use this module like pipes and give it a pagination-controls tag in your template (I use it in app.component.html)
<table>
<tr *ngFor="let x of names | paginate: { itemsPerPage: 3, currentPage: page }">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
<pagination-controls (pageChange)="page = $event"></pagination-controls>
I hope this was helpful.

I solve this issue by following the steps below (Windows OS user):
Open your Angular project using VS Code as Administrator mode.
Run npm install in the Terminal and wait it to complete.
Close VS Code.
Re-open your Angular project using VS Code as Administrator mode.
The issue should be fixed.

Related

vue quasar JSX Failed to resolve component

I have the following code:
Tmp1Component.tsx
import { h, defineComponent } from 'vue'
export default defineComponent({
name: 'App',
setup () {
const x = "test"
},
render() {
return [<q-btn>Test</q-btn>,<div>Tes2</div>]
}}
)
Tmp1Page.vue
<template>
<tmp1-component />
<tmp2-component />
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import Tmp1Component from '../components/Tmp1Component.tsx'
import Tmp2Component from '../components/Tmp2Component.vue'
export default defineComponent({
name: 'Tmp1Page',
inheritAttrs: false,
components: { Tmp1Component, Tmp2Component },
setup () {
{}
}
});
</script>
babel.config.js
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset'
// '#quasar/babel-preset-app'
],
plugins: ["#vue/babel-plugin-jsx", "transform-vue-jsx"]
}
package.json
{
"name": "kitty",
"version": "0.0.1",
"private": true,
"description": "Kitty desc",
"author": "amirny2205 <*.ru>",
"scripts": {
"lint": "eslint --ext .js,.ts,.vue ./",
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
"#quasar/extras": "^1.0.0",
"#vitejs/plugin-vue-jsx": "^3.0.0",
"#vue/babel-plugin-jsx": "^1.1.1",
"#vue/cli-plugin-babel": "^5.0.8",
"axios": "^0.21.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"core-js": "^3.8.3",
"jquery": "^3.6.3",
"pinia": "^2.0.11",
"quasar": "^2.6.0",
"vue": "^3.0.0",
"vue-i18n": "^9.2.2",
"vue-router": "^4.0.0"
},
"devDependencies": {
"#intlify/vite-plugin-vue-i18n": "^3.3.1",
"#quasar/app-vite": "^1.0.0",
"#types/node": "^12.20.21",
"#typescript-eslint/eslint-plugin": "^5.10.0",
"#typescript-eslint/parser": "^5.10.0",
"autoprefixer": "^10.4.2",
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^9.0.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
"vite": "^3"
},
"engines": {
"node": "^18 || ^16 || ^14.19",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
},
"productName": "Kitty"
}
And I am getting "Failed to resolve component: q-btn"
screenshot
JSX works as you can see by the "test" string
Quasar components work as you can see by "BUTN"
I have found this: https://github.com/quasarframework/quasar/issues/7672
( https://codesandbox.io/s/magical-dew-mybq9?file=/package.json )
and this:
https://codesandbox.io/s/53ki6?file=/src/App.tsx
Both work in the sandbox though I cannot get them to work locally
The solution was to import the component in quasar.config.js

Angular 14: error NG8001: 'app-horizontal-bar-chart' is not a known element:

Can someone help me with this error? I have seen other possible solutions to solve this error but they have not worked.
Error: src/app/pages/home/home.component.html:5:9 - error NG8001: 'app-horizontal-bar-chart' is not a known element:
If 'app-horizontal-bar-chart' is an Angular component, then verify that it is part of this module.
If 'app-horizontal-bar-chart' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
5
~~~~~~~~~~~~~~~~~~~~~~~~~~
src/app/pages/home/home.component.ts:5:16
5 templateUrl: './home.component.html',
~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component HomeComponent.
package.json
{
"name": "goty",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"#angular/animations": "^14.0.0",
"#angular/common": "^14.0.0",
"#angular/compiler": "^14.0.0",
"#angular/core": "^14.0.0",
"#angular/forms": "^14.0.0",
"#angular/platform-browser": "^14.0.0",
"#angular/platform-browser-dynamic": "^14.0.0",
"#angular/router": "^14.0.0",
"#cds/core": "^6.1.4",
"#clr/angular": "^13.8.2",
"#clr/icons": "^13.0.2",
"#clr/ui": "^13.8.2",
"#swimlane/ngx-charts": "^20.1.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"#angular-devkit/build-angular": "^14.0.0",
"#angular/cli": "~14.0.0",
"#angular/compiler-cli": "^14.0.0",
"#types/jasmine": "~4.0.0",
"jasmine-core": "~4.1.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.7.2"
}
}
project structure
app.module.ts
**import { NgModule} from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ComponentsModule} from './components/components.module';
import { HomeComponent } from './pages/home/home.component';
import { VoteComponent } from './pages/vote/vote.component';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
VoteComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
ComponentsModule
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule { }**
home.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
home.component.html
<h2>Game of the year!!!</h2>
<hr>
<div class="row">
<div class="col">
<app-horizontal-bar-chart></app-horizontal-bar-chart>
</div>
</div>
app.component.html
<app-navbar></app-navbar>
<router-outlet></router-outlet>
components.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule } from '#angular/router';
import { NgxChartsModule } from '#swimlane/ngx-charts';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { NavbarComponent } from './navbar/navbar.component';
import { HorizontalBarChartComponent } from './horizontal-bar-chart/horizontal-bar-chart.component';
#NgModule({
declarations: [
NavbarComponent,
HorizontalBarChartComponent,
],
exports: [
NavbarComponent,
HorizontalBarChartComponent,
],
imports: [
CommonModule,
RouterModule,
NgxChartsModule,
BrowserAnimationsModule,
]
})
export class ComponentsModule { }
horizontal-bar-chart.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-horizontal-bar-chart',
templateUrl: './horizontal-bar-chart.component.html',
styleUrls: ['./horizontal-bar-chart.component.css']
})
export class HorizontalBarChartComponent {
results: any[]=[
{
"name": "Game 1",
"value": 25
},
{
"name": "Game 2",
"value": 37
},
{
"name": "Game 3",
"value": 42
}
];
// options
showXAxis = true;
showYAxis = true;
gradient = true;
showLegend = true;
showXAxisLabel = true;
xAxisLabel = 'Games';
showYAxisLabel = true;
yAxisLabel = 'Votes';
colorScheme = 'nightLights';
}
horizontal-bar-chart.component.html
<div class="chart-container">
<ngx-charts-bar-horizontal [scheme]="colorScheme" [results]="results" [gradient]="gradient" [xAxis]="showXAxis" [yAxis]="showYAxis" [legend]="showLegend" [showXAxisLabel]="showXAxisLabel" [showYAxisLabel]="showYAxisLabel" [xAxisLabel]="xAxisLabel" [yAxisLabel]="yAxisLabel"
style="fill: grey">
</ngx-charts-bar-horizontal>
</div>

I get Cannot use import statement outside a module error while unit testing with Jest in quasar

I want to test my quasar application with jest, when i run the test i get error
SyntaxError: Cannot use import statement outside a module
58 | </template>
59 | <script>
> 60 | import { QCalendarDay, today } from '#quasar/quasar-ui-qcalendar/src/index.js'
| ^
61 | import '#quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass'
62 | import '#quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass'
63 | import '#quasar/quasar-ui-qcalendar/src/QCalendarDay.sass'
root/src/components/calendars/daily-calendar
div(style="display: flex")
q-calendar-day.rounded-borders(ref="dailyCalendar" :locale="localeLanguage" :hour24-format="true" :interval-minutes="appointmentDuration" v-model="selectedDate" view="day" animated bordered transition-next="slide-left" transition-prev="slide-right" no-active-date :interval-start="24" :interval-count="68" :interval-height="28")
template(#head-day-event="{ scope: { timestamp } }")
div(style="display: flex; justify-content: center; flex-wrap: wrap; padding: 2px")
template(v-for="event in modelValueProxy[timestamp.date]" :key="event.id")
q-badge(v-if="!event.time" :class="badgeClasses(event, 'header')" :style="badgeStyles(event, 'header')" style="width: 100%; cursor: pointer; height: 12px; font-size: 10px; margin: 1px")
.title.q-calendar__ellipsis
| {{ event.title }}
daily calendar script
import { QCalendarDay, today } from '#quasar/quasar-ui-qcalendar/src/index.js'
import '#quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass'
import '#quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass'
import '#quasar/quasar-ui-qcalendar/src/QCalendarDay.sass'
import lookie from 'lookie'
import moment from 'moment'
import { date } from 'quasar'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'WeekSlotDayBody',
components: {
QCalendarDay
},
root/test/jest/tests/dailyCalendar.spec.ts
import { describe, expect, it } from '#jest/globals'
import { installQuasarPlugin } from '#quasar/quasar-app-extension-testing-unit-jest'
import { mount } from '#vue/test-utils'
import dailyCalendar from '#/components/calendars/daily-calendar.vue'
/*
* You can provide a config object as param like such:
*
* ```ts
* installQuasarPlugin({ plugins: { Dialog } });
* ```
*/
installQuasarPlugin()
describe('dailyCalendar', () => {
it('mounts without errors', () => {
const wrapper = mount(dailyCalendar)
expect(wrapper).toBeTruthy()
})
})
jest.config.js
const esModules = ['quasar', 'quasar/lang', 'lodash-es'].join('|')
/* eslint-env node */
module.exports = {
globals: {
__DEV__: true,
// TODO: Remove if resolved natively
// See https://github.com/vuejs/vue-jest/issues/175
'vue-jest': {
pug: { doctype: 'html' }
},
// Remove if using `const enums`
// See https://huafu.github.io/ts-jest/user/config/isolatedModules#example
'ts-jest': {
isolatedModules: true
}
},
roots: ['<rootDir>/../'],
modulePaths: ['<rootDir>/../'],
moduleDirectories: ['node_modules'],
// Jest assumes we are testing in node environment, specify jsdom environment instead
testEnvironment: 'jsdom',
// noStackTrace: true,
// bail: true,
// cache: false,
// verbose: true,
// watch: true,
collectCoverage: false,
coverageDirectory: '<rootDir>/test/jest/coverage',
coverageReporters: ['json-summary'],
collectCoverageFrom: [
'<rootDir>/src/**/*.vue',
'<rootDir>/src/**/*.js',
'<rootDir>/src/**/*.ts',
'<rootDir>/src/**/*.jsx',
'<rootDir>/src/**/*.tsx'
],
coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'],
coverageThreshold: {
global: {
// branches: 50,
// functions: 50,
// lines: 50,
// statements: 50
}
},
testMatch: [
// Matches tests in any subfolder of 'src' or into 'test/jest/__tests__'
// Matches all files with extension 'js', 'jsx', 'ts' and 'tsx'
'<rootDir>/test/jest/__tests__/**/*.(spec|test).+(ts|js)?(x)',
'<rootDir>/src/**/*.jest.(spec|test).+(ts|js)?(x)'
],
// Extension-less imports of components are resolved to .ts files by TS,
// grating correct type-checking in test files.
// Being 'vue' the first moduleFileExtension option, the very same imports
// will be resolved to .vue files by Jest, if both .vue and .ts files are
// in the same folder.
// This guarantee a great dev experience both for testing and type-checking.
// See https://github.com/vuejs/vue-jest/issues/188#issuecomment-620750728
moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'ts', 'tsx'],
moduleNameMapper: {
'^quasar$': 'quasar/dist/quasar.esm.prod.js',
'^~/(.*)$': '<rootDir>/$1',
'^src/(.*)$': '<rootDir>/src/$1',
'^app/(.*)$': '<rootDir>/$1',
'^components/(.*)$': '<rootDir>/src/components/$1',
'^layouts/(.*)$': '<rootDir>/src/layouts/$1',
'^pages/(.*)$': '<rootDir>/src/pages/$1',
'^assets/(.*)$': '<rootDir>/src/assets/$1',
'^boot/(.*)$': '<rootDir>/src/boot/$1',
'.*css$': '#quasar/quasar-app-extension-testing-unit-jest/stub.css'
},
transform: {
// See https://jestjs.io/docs/en/configuration.html#transformignorepatterns-array-string
[`^(${esModules}).+\\.js$`]: 'babel-jest',
'^.+\\.(ts|js|html)$': 'ts-jest',
// vue-jest uses find-babel-file, which searches by this order:
// (async) .babelrc, .babelrc.js, package.json, babel.config.js
// (sync) .babelrc, .babelrc.js, babel.config.js, package.json
// https://github.com/tleunen/find-babel-config/issues/33
'.*\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue']
}
Error
Cannot find module '#/components/calendars/daily-calendar.vue' from 'test/jest/__tests__/MyButton.spec.ts'
package.json
{
"private": true,
"scripts": {
"dev": "quasar dev",
"build": "quasar build",
"start": "node server.js",
"lint": "eslint --ext .js,.ts,.vue ./",
"format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
"heroku-postbuild": "yarn && yarn build",
"make-badges": "istanbul-badges-readme",
"test:unit:ui": "majestic",
"test:unit": "jest --updateSnapshot",
"test:unit:ci": "jest --ci",
"test:unit:coverage": "jest --coverage",
"test:unit:watch": "jest --watch",
"test:unit:watchAll": "jest --watchAll",
"serve:test:coverage": "quasar serve test/jest/coverage/lcov-report/ --port 8788",
"concurrently:dev:jest": "concurrently \"quasar dev\" \"jest --watch\""
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^6.1.1",
"#fortawesome/free-regular-svg-icons": "^6.1.1",
"#fortawesome/free-solid-svg-icons": "^6.1.1",
"#fortawesome/vue-fontawesome": "^3.0.0-5",
"#quasar/cli": "^1.3.2",
"#quasar/extras": "^1.13.6",
"#types/lodash-es": "^4.17.6",
"#vue/test-utils": "^2.0.0-rc.18",
"axios": "^0.27.2",
"connect-history-api-fallback": "^1.6.0",
"core-js": "^3.22.3",
"crypto": "^1.0.1",
"crypto-browserify": "^3.12.0",
"echarts": "^5.3.2",
"express": "^4.18.1",
"froala-editor": "^4.0.11",
"happy-dom": "^6.0.4",
"include-media": "^1.4.10",
"lodash-es": "^4.17.21",
"lookie": "^1.0.4",
"moment": "^2.29.3",
"moment-business-days": "^1.2.0",
"moment-timezone": "^0.5.34",
"quasar": "^2.7.5",
"reactive-state": "^3.7.2",
"sass": "^1.52.1",
"serve-static": "^1.15.0",
"stream-browserify": "^3.0.0",
"ui": "^0.2.4",
"vitest": "^0.18.1",
"vue": "^3.2.33",
"vue-echarts": "^6.0.2",
"vue-froala-wysiwyg": "^4.0.11",
"vue-i18n": "^9.2.0-beta.36",
"vue-jest": "^5.0.0-alpha.10",
"vue-moment-tz": "^2.1.1",
"vue-router": "^4.0.14",
"yarn": "^1.22.18"
},
"devDependencies": {
"#prettier/plugin-pug": "^2.0.0",
"#quasar/app-webpack": "^3.5.3",
"#quasar/quasar-app-extension-qcalendar": "^4.0.0-beta.15",
"#quasar/quasar-app-extension-testing": "^2.0.4",
"#quasar/quasar-app-extension-testing-unit-jest": "^3.0.0-alpha.10",
"#types/node": "^17.0.29",
"#typescript-eslint/eslint-plugin": "^5.21.0",
"#typescript-eslint/parser": "^5.21.0",
"eslint": "^8.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^25.2.2",
"eslint-plugin-vue": "^8.7.1",
"eslint-webpack-plugin": "^3.1.1",
"istanbul-badges-readme": "^1.8.2",
"majestic": "^1.7.0",
"prettier": "^2.6.2",
"pug": "^3.0.2",
"pug-plain-loader": "^1.1.0",
"workbox-webpack-plugin": "^6.5.3"
},
"browser": {
"crypto": false,
"stream": false
},
"browserslist": [
"last 10 Chrome versions",
"last 10 Firefox versions",
"last 4 Edge versions",
"last 7 Safari versions",
"last 8 Android versions",
"last 8 ChromeAndroid versions",
"last 8 FirefoxAndroid versions",
"last 10 iOS versions",
"last 5 Opera versions"
],
"engines": {
"node": ">= 12.22.1",
"npm": ">= 6.13.4",
"yarn": ">= 1.21.1"
},
"overrides": {
"#types/eslint": "8.4.3"
},
"resolutions": {
"#types/eslint": "8.4.3"
}
}
When I run the above gesture conf, I get module not found error. this config is actually the config that comes when loading jest with quasar. I don't understand why I am getting such an error.
Remove nonexistent /calendars folder from your import path:
import dailyCalendar from '#/components/calendars/daily-calendar.vue'
Should be updated to:
import dailyCalendar from '#/components/daily-calendar.vue'
The import is looking for a file path that doesn't exist, given that the actual file is at root/src/components/daily-calendar and #/ is mapped to root/src. If the actual file path was root/src/components/calendars/daily-calendar, the import would work.

Vue 3, Ionic 6 menu component shows black screen

Project was setup using Ionic's CLI, nothing custom, except some linter configs.
The problem: every time i try to use IonMenu, it just breaks the whole page.
Page Component:
<template>
<ion-page>
<ion-menu
side="start"
content-id="menuContent"
>
<ion-header>
<ion-toolbar color="secondary">
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-label>START MENU CONTENTS</ion-label>
</ion-content>
</ion-menu>
<ion-router-outlet id="menuContent" />
</ion-page>
</template>
<script>
import {
IonPage,
IonRouterOutlet,
IonContent,
IonHeader,
IonMenu,
IonTitle,
IonToolbar
} from '#ionic/vue';
import { defineComponent } from 'vue';
export default defineComponent({
name: 'index-page',
components: {
IonPage,
IonRouterOutlet,
IonContent,
IonHeader,
IonMenu,
IonTitle,
IonToolbar
}
});
</script>
Result (it's identical in browser and in emulator): nested menu content renders, but the page looks like this
If I remove <ion-menu> component, everything works just fine
My package.json
{
"name": "notes",
"version": "0.0.1",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint:eslint": "./node_modules/.bin/eslint -c .eslintrc.js .",
"lint:eslint:fix": "npm run lint:eslint -- --fix",
"lint:stylelint": "./node_modules/.bin/stylelint --config stylelint.config.js .",
"lint:stylelint:fix": "npm run lint:stylelint -- --fix"
},
"dependencies": {
"#capacitor/app": "1.1.1",
"#capacitor/core": "3.5.1",
"#capacitor/haptics": "1.1.4",
"#capacitor/keyboard": "1.2.2",
"#capacitor/status-bar": "1.0.8",
"#ionic/vue": "6.0.0",
"#ionic/vue-router": "6.0.0",
"core-js": "3.6.5",
"vue": "3.2.21",
"vue-router": "4.0.12"
},
"devDependencies": {
"#capacitor/cli": "3.5.1",
"#types/jest": "27.0.2",
"#typescript-eslint/eslint-plugin": "5.6.0",
"#typescript-eslint/parser": "5.6.0",
"#vue/cli-plugin-babel": "~5.0.0-rc.1",
"#vue/cli-plugin-e2e-cypress": "~5.0.0-rc.1",
"#vue/cli-plugin-eslint": "~5.0.0-rc.1",
"#vue/cli-plugin-router": "~5.0.0-rc.1",
"#vue/cli-plugin-typescript": "~5.0.0-rc.1",
"#vue/cli-plugin-unit-jest": "~5.0.0-rc.1",
"#vue/cli-service": "~5.0.0-rc.1",
"#vue/eslint-config-typescript": "9.1.0",
"#vue/test-utils": "2.0.0-rc.16",
"#vue/vue3-jest": "27.0.0-alpha.3",
"#vuebits/bem": "1.2.2",
"babel-jest": "27.3.1",
"cypress": "8.7.0",
"eslint": "8.4.1",
"eslint-config-airbnb-base": "15.0.0",
"eslint-plugin-unused-imports": "2.0.0",
"eslint-plugin-vue": "8.2.0",
"jest": "27.3.1",
"npm-run-all": "4.1.5",
"sass": "1.52.2",
"sass-loader": "13.0.0",
"stylelint": "13.13.1",
"stylelint-config-rational-order": "0.1.2",
"stylelint-config-standard": "22.0.0",
"stylelint-order": "4.1.0",
"stylelint-webpack-plugin": "2.1.1",
"ts-jest": "27.0.7",
"typescript": "4.3.5",
"vue-auto-routing": "1.0.1",
"vue-eslint-parser": "9.0.2"
},
"description": "An Ionic project"
}
My vue.config.js
const VueAutoRoutingPlugin = require('vue-auto-routing/lib/webpack-plugin');
const { definePlugin } = require('./config/webpack/define-plugin');
const { linterPlugins } = require('./config/webpack/linter-plugins');
const { getWebpackAliases } = require('./config/webpack/aliases');
module.exports = {
configureWebpack: config => {
config.stats = 'normal';
const routerPlugin = new VueAutoRoutingPlugin({
pages: 'src/pages',
importPrefix: '~/src/pages/'
});
config.plugins = config.plugins.concat([definePlugin, routerPlugin]);
if (process.env.LINT_ON_BUILD === 'true') {
plugins.push(...linterPlugins);
}
config.resolve.alias = { ...config.resolve.alias, ...getWebpackAliases() };
}
};

Rollup bundling peer dependencies / Multiple instances of MUI make the ThemeProvider not work

I have two different repos I'm working on, lib and apps.
lib has some React components made with MUI that I want to consume in apps, and that's built with Rollup.
apps is a Lerna monorepo with a Next.js app that imports lib as a dependency to consume its components, which can be customized wrapping them in a <ThemeProvider> with a custom theme.
However, that doesn't work because there are duplicated instances of MUI / ThemeProvider, which I was able to verify by adding this to lib's entry point:
if (process.browser) {
(window as any)._React = React;
(window as any)._ThemeProvider = ThemeProvider;
}
And then this into apps':
if (process.browser) {
const {
_React,
_ThemeProvider,
} = window as any;
console.log(_React ? (_React === React ? "✅ Unique React" : "❌ Duplicate React") : "-");
console.log(_ThemeProvider ? (_ThemeProvider === ThemeProvider ? "✅ Unique ThemeProvider" : "❌ Duplicate ThemeProvider") : "-");
}
Which prints:
✅ Unique React
❌ Duplicate ThemeProvider
lib's component usage in app looks like this:
<ThemeProvider theme={ MY_CUSTOM_THEME }>
<MyComponent{ ...myComponentProps } />
</ThemeProvider>
Where both MyComponent and MY_CUSTOM_THEME are imported from lib, while ThemeProvider is imported from #mui/material/styles, just like it is in lib.
However, all MUI components will be displayed with the default theme.
Here are some of the relevant build files for both repos:
lib > package.json:
{
"name": "#myscope/lib",
"version": "1.0.0-alpha",
"description": "",
"main": "dist/cjs/src/index.js",
"module": "dist/esm/src/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"private": true,
"scripts": {
"build": "rollup -c",
},
"dependencies": {
"#apollo/client": "^3.4.5",
"#apollo/link-context": "^2.0.0-beta.3",
"#hookform/resolvers": "^2.8.5",
"#mui/icons-material": "^5.0.4",
"#swyg/corre": "^1.0.1",
"apollo-upload-client": "^16.0.0",
"atob": "^2.1.2",
"axios": "^0.24.0",
"btoa": "^1.2.1",
"country-codes-list": "^1.6.8",
"country-region-data": "^1.6.0",
"next": "^11.0.1",
"next-images": "^1.8.2",
"openpgp": "^5.0.0",
"react-hook-form": "^7.22.0",
"react-payment-inputs": "^1.1.8",
"react-use-country-region": "^1.0.0",
"styled-components": "^5.3.0",
"use-callback-ref": "^1.2.5",
"uuidv4": "^6.2.12",
"yup": "^0.32.11"
},
"peerDependencies": {
"#mui/material": "^5.0.4",
"react-dom": "^17.0.2",
"react": "^17.0.2"
},
"devDependencies": {
"#auth0/auth0-react": "^1.6.0",
"#babel/preset-react": "^7.16.7",
"#emotion/react": "^11.5.0",
"#emotion/styled": "^11.3.0",
"#graphql-codegen/cli": "^1.21.5",
"#graphql-codegen/introspection": "^1.18.2",
"#graphql-codegen/typescript-operations": "^1.18.0",
"#graphql-codegen/typescript-react-apollo": "^2.2.5",
"#graphql-codegen/typescript": "^1.22.1",
"#mui/material": "^5.2.8",
"#rollup/plugin-babel": "^5.3.0",
"#rollup/plugin-commonjs": "^21.0.1",
"#rollup/plugin-node-resolve": "^13.1.2",
"#rollup/plugin-typescript": "^8.3.0",
"#testing-library/dom": "^8.1.0",
"#testing-library/jest-dom": "^5.14.1",
"#testing-library/react": "^12.0.0",
"#testing-library/user-event": "^13.2.1",
"#types/jest": "^26.0.24",
"#types/react-dom": "^17.0.11",
"#types/react": "^17.0.16",
"#types/styled-components": "^5.1.12",
"#typescript-eslint/eslint-plugin": "^4.29.0",
"#typescript-eslint/parser": "^4.29.0",
"babel-jest": "^27.0.6",
"babel-plugin-styled-components": "^2.0.2",
"eslint-config-next": "^11.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-unused-imports": "^1.1.2",
"eslint": "^7.32.0",
"graphql": "^16.2.0",
"jest": "^27.0.6",
"prettier": "^2.3.2",
"rollup-plugin-dts": "^4.1.0",
"rollup-plugin-node-externals": "^3.1.2",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-typescript2": "^0.31.1",
"rollup": "^2.63.0",
"ts-jest": "^27.0.4",
"typescript": "^4.3.5"
}
}
Note that #mui/material appears both in peerDependencies and devDependencies, but not react or rect-dom, which are only listed as peerDependencies. That's because there's #types/react and #types/react-dom, but nothing similar for MUI, so the Rollup build would fail if it can't find the right types.
lib > rollup.config.js:
import commonjs from '#rollup/plugin-commonjs';
import dts from 'rollup-plugin-dts'
import resolve from "#rollup/plugin-node-resolve";
import typescript from 'rollup-plugin-typescript2'
import babel from '#rollup/plugin-babel'
import pkg from "./package.json";
// Extensions handled by babel:
const EXTENSIONS = [".ts", ".tsx"];
// Exclude dev and peer dependencies:
const EXTERNAL = [
...Object.keys(pkg.devDependencies),
...Object.keys(pkg.peerDependencies),
];
export default [{
input: 'src/index.ts',
output: [{
dir: "dist/esm",
sourcemap: true,
format: "esm",
preserveModules: true,
globals: {
react: "React",
},
}, {
dir: "dist/cjs",
sourcemap: true,
format: "cjs",
preserveModules: true,
globals: {
react: "React",
},
}],
external: EXTERNAL,
plugins: [
resolve(),
commonjs({
exclude: "node_modules",
ignoreGlobal: true,
}),
typescript({
useTsconfigDeclarationDir: true,
tsconfig: "rollup.tsconfig.json",
}),
],
}, {
input: './dist/types/src/index.d.ts',
output: [{ file: './dist/index.d.ts', format: "esm" }],
external: EXTERNAL,
plugins: [dts()],
}];
apps > lerna.json:
{
"packages": ["apps/**/*", "packages/**/*"],
"version": "0.0.1",
"npmClient": "yarn",
"useWorkspaces": true
}
apps > package.json:
...
"dependencies": {
"#myscope/lib": "file:../lib"
},
...
Note this is a file: import just to make it easier to develop and test changes.
I've also tried adding resolutions to both apps > package.json and apps > app > package.json, but no luck with that either...:
"resolutions": {
"#mui/material": "5.2.8"
}
It might not be the best solution, but I fixed this by exporting the ThemeProvider from lib:
export { ThemeProvider as MyComponentThemeProvider } from "#mui/material/styles";
Now, when using this one in app:
<MyComponentThemeProvider theme={ MY_CUSTOM_THEME }>
<MyComponent{ ...myComponentProps } />
</MyComponentThemeProvider>
Everything works as expected:
✅ Unique React
✅ Unique ThemeProvider
Also, take a look at https://github.com/facebook/react/issues/19541