Quasar QSpinner module not found - quasar

Im getting the following error:
ERROR Failed to compile with 1 errors
This relative module was not found:
* ./QSpinner in ./node_modules/quasar-framework/src/components/spinner/index.js
Ive tried reinstalling quasar-cli and updating npm
im working with quasar-framework 0.15.8
and quasar-cli 0.15.12

Make sure you include QSpinner component.
Open quasar.conf.js file and look for framework components and add it there.
framework: {
components: [
'QSpinner',
'QLayout',
'QLayoutHeader',
'QLayoutDrawer',
'QPageContainer',
'QPage',
'QToolbar',
'QToolbarTitle',
'QBtn',
'QIcon',
'QList',
'QListHeader',
'QItem',
'QItemMain',
'QItemSide'
],
directives: [
'Ripple',
'TouchPan'
],
// Quasar plugins
plugins: [
'Notify'
]
},
If you already did so, try deleting node_modules and re-run 'npm install'

All of the quasar modules that you use in your project will be enabled if you set the all quasar.conf setting to "auto."
all to 'auto'
framework: {
iconSet: 'material-icons', // Quasar icon set
lang: 'en-us', // Quasar language pack
// Possible values for "all":
// * 'auto' - Auto-import needed Quasar components & directives
// (slightly higher compile time; next to minimum bundle size; most convenient)
// * false - Manually specify what to import
// (fastest compile time; minimum bundle size; most tedious)
// * true - Import everything from Quasar
// (not treeshaking Quasar; biggest bundle size; convenient)
all: 'auto',
components: [],
directives: [
'GoBack'
],
// Quasar plugins
plugins: [
'Loading',
'LocalStorage',
'SessionStorage',
'Notify'
]
},
So when you set property 'all' to 'auto', that means Auto-import needed Quasar components & directives

Include QSpinner component in quasar.conf.js file and look for framework components and in root directory there is a .quasar folder, inside it there are file import-quasar.js and quasar.js.
Vue.use(Quasar, {components: {QSpinner,QPagination,QChatMessage,QScrollArea,...
also import component at the beginning

Related

How do I limit the scope of `resolveJsonModule`?

I'm working on project that uses Typescript and webpack. I have to import json files, and I have to do it in two ways:
I have to import project's package.json as a module. This has already been implemented previously.
Have to import some json schemas as resources loadable by url. This is what I'm working on right now.
Using package.json (already implemented)
To import package.json, the tsconfig.json contains:
{
"compilerOptions": {
"resolveJsonModule": true,
"paths": {
"package.json": ["./package.json"]
}
},
}
And webpack config has:
/**
* Determine the array of extensions that should be used to resolve modules.
*/
resolve: {
extensions: [".js", ".ts", ".tsx", ".json"],
plugins: [
new TSConfigPathsPlugin({
configFile: path.join(__dirname, "../../tsconfig.json"),
logLevel: "info",
extensions: [".js", ".jsx", ".ts", ".tsx"],
mainFields: ["browser", "main"],
baseUrl: tsConfig.baseUrl,
}),
],
},
And this is how package.json is used:
import packageJson from "package.json";
//...
const release = `${packageJson.version}-${process.platform}`;
This is completely type-safe: ts checks that my package.json has version field. This is working as intended and I don't want to break it.
Using schema json files (what I'm implementing)
To add support for json schemas, I've added them with filenames matching .schema.json$ and have added this to webpack config:
module: {
rules: [
{
test: /\.schema.json$/,
type: "asset/resource",
},
],
},
And this to a global type declaration file:
declare module "*.schema.json" {
declare const uri: string;
export default uri;
}
I thought that by doing that, Typescript would interpret import such a file as a simple string. I've been following this example.
However, when I import the schema file in my project:
import someSchemaUri from "./schemas/some-name.schema.json";
// ...
uri = someSchemaUri;
I still get type error:
Type '{ ... }' is not assignable to type 'string'.
Changing resolveJsonModule
If I set resolveJsonModule option to false, this problem goes away, but importing package.json from the previous section starts giving an error:
Module 'package.json' was resolved to 'secret/path/package.json', but '--resolveJsonModule' is not used.
How do I configure my project so that Typescript would interpret these files as a string, but at the some don't lose type safety when I import package.json from the previous section?
As I know, there's no way to override json types once --resolveJsonModule was set.
May you consider to disable that flag and write types for package.json manually? It's not time-consuming since you use only one package.json field.
declare module '*.schema.json' {
const uri: string;
export default uri;
}
declare module '*package.json' {
const content: {
version: string;
};
export default content;
}

Webpack Pug/HTML loaders converts capital letters to lowercase on production mode

I am using both vue single-file components and separating of markup and logic to .pug and .ts files respectively. If you interesting why I don't unify is please see the comments section.
Problem
import template from "#UI_Framework/Components/Controls/InputFields/InputField.vue.pug";
import { Component, Vue } from "vue-property-decorator";
console.log(template);
#Component({
template,
components: {
CompoundControlBase
}
})
export default class InputField extends Vue {
// ...
}
In development building mode exported template is correct (I beautified it for readability):
<CompoundControlBase
:required="required"
:displayInputIsRequiredBadge="displayInputIsRequiredBadge"
<TextareaAutosize
v-if="multiline"
:value="value"
/><TextareaAutosize>
</CompoundControlBase>
In production mode, my markup has been lowercased. So, the console.log(template) outputs:
<compoundcontrolbase
:required=required
:displayinputisrequiredbadge=displayInputIsRequiredBadge
<textareaautosize
v-if=multiline
:value=value
></textareaautosize>
</compoundcontrolbase>
Off course, I got broken view.
Webpack config
const WebpackConfig = {
// ...
optimization: {
noEmitOnErrors: !isDevelopmentBuildingMode,
minimize: !isDevelopmentBuildingMode
},
module: {
rules: [
{
test: /\.vue$/u,
loader: "vue-loader"
},
{
test: /\.pug$/u,
oneOf: [
// for ".vue" files
{
resourceQuery: /^\?vue/u,
use: [ "pug-plain-loader" ]
},
// for ".pug" files
{
use: [ "html-loader", "pug-html-loader" ]
}
]
},
// ...
]
}
}
Comments
To be honest, I don't know why we need ? in resourceQuery: /^\?vue/u, (explanations are welcome).
However, in development building mode above config works property for both xxxx.vue and xxxx.vue.pug files.
I am using below files naming convention:
xxx.pug: pug file which will not be used as vue component template.
xxx.vue.pug: pug file which will be used as vue component template.
xxx.vue: single-file vue component.
xxx.vue.ts: the logic of vue component. Required exported template from xxx.vue.pug as in InputField case.
Why I need xxx.vue.ts? Because of this:
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
Neither public methods/fields nor non-default methods are visible for TypeScrpt xxx.vue files. For the common (non-applied) components, I can't accept it.
Repro
🌎 GitHub
Step 1: Install dependencies
npm i
Step 2: Let's check the development building first
npm run DevelopmentBuild
In line 156 of DevelopmentBuild\EntryPoint.js, you can check that below pug template:
Alpha
Bravo OK
has been compiled properly:
Step 3: Problem on production build
npm run ProuductionBuild
You can find the lowercased tags in the column 13:
You can also open index.html in your browser and check the console.log() output with compiled TestComponent.
The problem is the "html-loader". It has the option minimize set to true in production mode (html-loader/#minimize).
I had a similar problem in angular and had to unset some options like (see for reference html-minifier-terser#options-quick-reference).
// webpack.config.js
{
test: /\.pug$/u,
oneOf: [
// for ".vue" files
{
resourceQuery: /^\?vue/u,
use: [ "pug-plain-loader" ]
},
// for ".pug" files
{
use: [ "html-loader", "pug-html-loader" ]
}
],
options: {
minimize: { // <----
caseSensitive: false // <----
} // <----
}
},

Karma runner with Coverage - preprocessor not working on Javascript ES6 code

I just recently started working with Karma runner in our UI5 app. Wrote some unit tests, ran them... all worked fine so far.
However, now I´ve decided to track the code coverage. To measure it, I need to run preprocessor on my source code. And this is where I stumbled upon a problems - I am currently trying to make it work and both have some kind of problems
npm package karma-coverage as a preprocessor - after installing it, I set it up in karma.conf.js like this
preprocessors: {
"webapp/helpers/**/*.js": ['coverage'],
"webapp/controller/**/*.js": ['coverage'],
},
This works fine on helpers folder since it contains only one file with simple javascript. However, when it tries to process controller folder which has files with some ES6 code, each file fails with errors such as these
Unexpected token function
Unexpected token ...
As a second option, I tried to use karma-babel-preprocessor which should be able to handle also ES6 code. This is how my karma.conf.js file looks like
preprocessors: {
"webapp/helpers//.js": ['babel'],
"webapp/controller//.js": ['babel'],
},
babelPreprocessor: {
options: {
presets: ['#babel/preset-env'],
sourceMap: 'inline'
} ,
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
}
},
However, this one is not even able to find the js file (even though the address is the same as in the case of coverage preprocesor) and returns this error.
Error: failed to load 'sbn/portal/helpers/formatter.js' from .webapp/helpers/formatter.js: 404 - Not Found
at https://openui5.hana.ondemand.com/resources/sap-ui-core.js:86:37
Does someone have an idea how I can get the coverage data while using these packages or any other ones? There is a lots of conflicting info on the web, most of it several years old while various karma-related npm packages keep popping up each month so I am really not sure which one would be the best to use.
Thank a lot
We had the same problem and we managed to fix it integrating babel in a ui5-building-tool step.
This is how our package.json looks like:
{
"devDependencies": {
"babel-core": "6.26.3",
"babel-plugin-fast-async": "6.1.2",
"babel-preset-env": "1.7.0",
"karma": "^4.0.1",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.2",
"karma-ui5": "^1.0.0",
"karma-junit-reporter": "1.2.0",
"rimraf": "^2.6.2",
"start-server-and-test": "^1.4.1",
"#ui5/cli": "^1.5.5",
"#ui5/logger": "^1.0.0",
}
"scripts": {
"start": "ui5 serve -o index.html",
"lint": "eslint webapp",
"test": "karma start",
"build": "npm run test && rimraf dist && ui5 build --a --include-task=generateManifestBundle"
}
}
This is how the ui5.yaml is looking like
specVersion: '1.0'
metadata:
name: app-name
type: application
builder:
customTasks:
- name: transpile
afterTask: replaceVersion
---
specVersion: "1.0"
kind: extension
type: task
metadata:
name: transpile
task:
path: lib/transpile.js
This is how the transpile.js is looking like:
Be aware that this file should be placed in the root-dir/lib folder. root-dir is the folder where ui5.yaml is residing.
const path = require("path");
const babel = require("babel-core");
const log = require("#ui5/logger").getLogger("builder:customtask:transpile");
/**
* Task to transpiles ES6 code into ES5 code.
*
* #param {Object} parameters Parameters
* #param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* #param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
* #param {Object} parameters.options Options
* #param {string} parameters.options.projectName Project name
* #param {string} [parameters.options.configuration] Task configuration if given in ui5.yaml
* #returns {Promise<undefined>} Promise resolving with undefined once data has been written
*/
module.exports = function ({
workspace,
dependencies,
options
}) {
return workspace.byGlob("/**/*.js").then((resources) => {
return Promise.all(resources.map((resource) => {
return resource.getString().then((value) => {
log.info("Transpiling file " + resource.getPath());
return babel.transform(value, {
sourceMap: false,
presets: [
[
"env",
{
exclude: ["babel-plugin-transform-async-to-generator", "babel-plugin-transform-regenerator"]
}
]
],
plugins: [
[
"fast-async",
{
spec: true,
compiler: {
"promises": true,
"generators": false
}
}
]
]
});
}).then((result) => {
resource.setString(result.code);
workspace.write(resource);
});
}));
});
};
And finally this is the karma.conf.js setup:
module.exports = function (config) {
var ui5ResourcePath = "https:" + "//sapui5.hana.ondemand.com/resources/";
config.set({
// the time that karma waits for a response form the browser before closing it
browserNoActivityTimeout: 100000,
frameworks: ["ui5"],
// list of files / patterns to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
"root_to_to_files/**/*.js": ["coverage"],
},
// test results reporter to use
// possible values: "dots", "progress"
// available reporters: https://npmjs.org/browse/keyword/karma-reportery
reporters: ["progress", "coverage"],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ["Chrome"],
// Continuous Integration modey
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
// generates the coverage report
coverageReporter: {
type: "lcov", // the type of the coverage report
dir: "reports", // the path to the output directory where the coverage report is saved
subdir: "./coverage" // the name of the subdirectory in which the coverage report is saved
},
browserConsoleLogOptions: {
level: "error"
}
});
};
In our project this setup works fine with ES6 code and prints the coverage.
Hope this you help you. Please give me a feedback how this works.

How do I create a "fat" js file with rollup using esm?

I have the following code..
// ui.js (generated by rollup
import Vue from 'vue';
import VueRouter from 'vue-router';
(()=>{
console.log("Wow it actually works");
Vue.use(VueRouter);
const routes = [
{
path: '/',
component: Viewport
}
];
const router = new VueRouter({
mode: "history",
routes: routes
});
window.app = new Vue({ router });
window.app.$mount('#jg-app');
})();
<script src="ui.js" type="module"> </script>
The problem is when I run this I get...
Uncaught TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../".
This leads me to believe I need a "fat" js that includes dependencies.
I also want to keep everything in es6 modules and avoid introducing say babel.
Is there a way to do this using rollup?
Update
Tried this...
import Vue from "./vue";
But then I get...
Error: Could not resolve './vue' from src/index.js
As far as I can tell this is not possible. I instead had to move the import from the ui project to the server project and create a static js file that looked like this...
//client
import Vue from "./vue"
let app = new Vue(...);
app.$mount('#jg-app');
and import the esm.browser version
// server
app.use('/vue', express.static(__dirname + '/node_modules/vue/dist/vue.esm.browser.js'));
// template
script(src="/main.js" type="module")
Now Vue is working, however, dependencies like Vue-Router appear to not have this es.browser style file.
This is not a solution, it's a workaround
The below rollup config is not esm, it's just a way to create a bundle with dependencies included.
You get one minified browser-compatible JS file.
Here's my working example rollup.config.js (you should replace input: 'src/index.js' with your web app entry point and output.file with a location for the generated bundle):
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import builtins from 'rollup-plugin-node-builtins';
import babel from 'rollup-plugin-babel';
import visualizer from 'rollup-plugin-visualizer';
import { terser } from "rollup-plugin-terser";
const browserPlugins = [
resolve({browser: true}), // so Rollup can properly resolve cuid
babel({
exclude: 'node_modules/**',
babelrc: false,
presets: ['es2015-rollup'],
}),
// builtins(),
commonjs(),
visualizer(),
terser(),
]
export default [
// browser-friendly UMD build
{
// external: Object.keys(globals),
input: 'src/index.js',
output: {
name: 'thinflux',
file: './dist/browser/thinflux.min.js',
format: 'umd'
},
plugins: browserPlugins,
}
];
One more thing: express should statically serve the output.file path, not your source files

tell typescript to compile json files

The typescript compiler works fine when I import a json file using
const tasks = require('./tasks.json')
However, when I run tsc, the output directory does not contain no tasks.json file, causing a runtime error.
Is there a way to tell the compiler that it should copy all json files, or should I manually copy/paste all my json files into the dist directory ?
my tsc compilerOptions currently reads
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"noImplicitAny": true,
"removeComments": false,
"outDir": "./dist/",
"sourceMap": true,
"pretty": true,
"noImplicitThis": true,
"strictNullChecks": true,
"sourceMap": true
},
Thanks !
Problem
For people wanting to copy all JSON files, it's really difficult in TypeScript. Even with "resolveJsonModule": true, tsc will only copy .json files which are directly referenced by an import.
Here is some example code that wants to do a dynamic runtime require(). This can only work if all the JSON files have been copied into the dist/ folder, which tsc refuses to do.
// Works
import * as config from './config.default.json';
const env = process.env.NODE_ENV || 'development';
const envConfigFile = `./config.${env}.json`;
// Does not work, because the file was not copied over
if (fs.existsSync(envConfigFile)) {
const envConfig = require(envConfigFile);
Object.assign(config, envConfig);
}
Solution 1: Keep json files outside the src tree (recommended)
Assuming you have /src/ and /dist/ folders, you could keep your JSON files in the project's / folder. Then a script located at /src/config/load-config.ts could do this at runtime:
const envConfig = require(`../../config.${env}.json`);
// Or you could read manually without using require
const envConfigFile = path.join(__dirname, '..', '..', `config.${env}.json`);
const envConfig = JSON.parse(fs.readFileSync(envConfigFile, 'utf-8'));
This is the simplest solution. You just need to make sure the necessary config files will be in place in the production environment.
The remaining solutions will deal with the case when you really want to keep the config files in your src/ folder, and have them appear in your dist/ folder.
Solution 2: Manually import all possible files
For the above example we could do:
import * as config from './config.default.json';
import * as testingConfig from './config.testing.json';
import * as stagingConfig from './config.staging.json';
import * as productionConfig from './config.production.json';
This should cause the specified json files to be copied into the dist/ folder, so our require() should now work.
Disadvantage: If someone wants to add a new .json file, then they must also add a new import line.
Solution 3: Copy json files using tsc-hooks plugin (recommended)
The tsc-hooks plugin allows you to copy all files from the src tree to the dist tree, and optionally exclude some.
// Install it into your project
$ yarn add tsc-hooks --dev
// Configure your tsconfig.json
{
"compilerOptions": {
"outDir": "dist"
},
// This tells tsc to run the hook during/after building
"hooks": [ "copy-files" ]
// Process everything except .txt files
"include": [ "src/**/*" ],
"exclude": [ "src/**/*.txt" ],
// Alternatively, process only the specified filetypes
"include": [ "src/**/*.{ts,js,json}" ],
}
I found it tsc-hooks announced here.
Solution 4: Copy json files using an npm build script (recommended)
Before tsc-hooks, we could add a cpy-cli or copyfiles step to the npm build process to copy all .json files into the dist/ folder, after tsc has finished.
This assumes you do your builds with npm run build or something similar.
For example:
$ npm install --save-dev cpy-cli
// To copy just the json files, add this to package.json
"postbuild": "cpy --cwd=src --parents '**/*.json' ../dist/",
// Or to copy everything except TypeScript files
"postbuild": "cpy --cwd=src --parents '**/*' '!**/*.ts' ../dist/",
Now npm run build should run tsc, and afterwards run cpy.
Disadvantages: It requires an extra devDependency. And you must make this part of your build process.
Solution 5: Use js files instead of json files
Alternatively, don't use .json files. Move them into .js files instead, and enable "allowJs": true in your tsconfig.json. Then tsc will copy the files over for you.
Your new .js files will need to look like this: module.exports = { ... };
I found this idea recommended here.
Note: In order to enable "allowJs": true you might also need to add "esModuleInterop": true and "declaration": false, and maybe even "skipLibCheck": true. It depends on your existing setup.
And there is one other concern (sorry I didn't test this):
Will tsc transpile your config files if they are not all statically referenced by other files? Your files or their folders may need to be referenced explicitly in the files or include options of your tsconfig.json.
Solution 6: Use ts files instead of json files
Sounds easy, but there are still some concerns to consider:
Your config files will now look something like this: const config = { ... }; export default config;
See the note above about files / include options.
If you load the config files dynamically at runtime, don't forget they will have been transpiled into .js files. So don't go trying to require() .ts files because they won't be there!
If someone wants to change a config file, they should do a whole new tsc build. They could hack around with transpiled .js files in the dist folder, but this should be avoided because the changes may be overwritten by a future build.
Testing
When experimenting with this, please be sure to clear your dist/ folder and tsconfig.tsbuildinfo file between builds, in order to properly test the process.
(tsc does not always clean the dist/ folder, sometimes it just adds new files to it. So if you don't remove them, old files left over from earlier experiments may produce misleading results!)
In tsconfig.json, add
{
"compilerOptions": {
"resolveJsonModule": true,
},
"include": [
"src/config/*.json"
]
}
Notice that it won't copy those json files which are required. If you need to dynamically require some json files and need them to be copied to dist, then you need to change from, for example,
return require("some.json") as YourType
to
return (await import("some.json")) as YourType
.
In typescript 2.9+ you can use JSON files directly and it automatically copied to dist directories.
This is tsconfig.json with minimum needed configuration:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"esModuleInterop" : true,
"module" : "commonjs",
"outDir" : "./dist",
"resolveJsonModule" : true,
"target" : "es6"
},
"exclude" : [
"node_modules"
]
}
Then you can create a json file.
{
"address": "127.0.0.1",
"port" : 8080
}
Sample usage:
import config from './config.json';
class Main {
public someMethod(): void {
console.log(config.port);
}
}
new Main().someMethod();
If you don't use esModuleInterop property you should access your json properties encapsulated in default field. config.default.port.
The typescript compiler works fine when I import a json file using
const tasks = require('./tasks.json')
TypeScript wouldn't complain about this as long as you have a global require() function defined, for example using node.d.ts. With a vanilla setup you would actually get a compile error that require is not defined.
Even if you've told TypeScript about a global require function it just sees it as a function that's expected to return something, it doesn't make the compiler actually analyze what the function is requiring ("tasks.json") and do anything with that file. This is the job of a tool like Browserify or Webpack, which can parse your code base for require statements and load just about anything (JS, CSS, JSON, images, etc) into runtime bundles for distribution.
Taking this a little further, with TypeScript 2.0 you can even tell the TypeScript Compiler about module path patterns that will be resolved and loaded by a bundler (Browserify or Webpack) using wildcard (*) module name declarations:
declare module "*.json" {
const value: any;
export default value;
}
Now you can import your JSON in TypeScript using ES6 module syntax:
import tasks from "./tasks.json";
Which will not give any compile error and will transpile down to something like var tasks = require("./tasks.json"), and your bundler will be responsible for parsing out the require statements and building your bundle including the JSON contents.
you can include this into your build script && ncp src/res build/res, will copy the files directly to your outDir
You can always get an absolute path to your project, with typescript code. To do it just read the JSON file not by the required keyword but with the help of the fs module. In a path of file use process.cwd() to access typescript project directory:
import * as fs from 'fs';
const task: any = JSON.parse(fs.readFileSync(`${process.cwd()}/tasks.json`).toString());
To make it work correctly you may need to change your running script to node dist/src/index.js where you specify a dist folder in the path.