import vue-awesome icons error while jest testing with nuxt on node 13.9.0 - vue.js

I have followed the instructions on https://github.com/Justineo/vue-awesome
in my jest.config.js I add the following
transformIgnorePatterns: [
'/node_modules(?![\\\\/]vue-awesome[\\\\/])/'
]
my nuxt.config.js
build: {
transpile: [/^vue-awesome/] // enable font-awesome integration.
},
The icons work just fine when I'm running the dev box, but I get the following when I run yarn test:
[path/to/project]/node_modules/vue-awesome/icons/building.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Icon from '../components/Icon.vue'
^^^^^^
SyntaxError: Cannot use import statement outside a module
explicitly, the issue seems to be something to do with how babel reads (or overlooks) the imports above the Icon component import. So, for example, given the building.js in the error log above, here is how the import looks in the vuejs file:
<script>
import 'vue-awesome/icons/building'
import Icon from 'vue-awesome/components/Icon'
export default {
componentes: {
'v-icon': Icon
}
...
}
</script>

It looks like I have to explicitly mock the component and its imports at the top of the file (below the imports)
the following works for my test.
import { shallowMount, createLocalVue } from '#vue/test-utils'
import Vuex from 'vuex'
import { AxiosSpy, MockNuxt } from 'jest-nuxt-helper'
import index from '#/pages/courses/index'
// MOCKS:
jest.mock('vue-awesome/icons/building', () => '')
jest.mock('vue-awesome/components/Icon', () => '<div></div>')
...

Related

How to make create-vue parse JSX without problems (as VueCLI does)

I use JSX extensively to customize Naive-UI library elements. But after migrating from VueCLI to create-vue, I noticed it looks like create-vue doesn't understand JSX in .vue file at all. For example it throws Uncaught SyntaxError: Unexpected token '<' for this:
const x = <div>Hi all</div>;
But VueCLI does understand... So the question is:
How to make create-vue parse JSX without problems (as VueCLI does)?
PS. Here is vite.config.js
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
import vueJsx from "#vitejs/plugin-vue-jsx";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
resolve: {
alias: {
"#": fileURLToPath(new URL("./src", import.meta.url)),
},
},
});
To use JSX in .vue files, make sure to use <script lang="jsx"> (or "tsx" if using TypeScript)

The requested module '/node_modules/.vite/deps/vue.js' does not provide an export named 'default'

The following is my problem.
I packaged my project through vite in library mode. The error occurs whenever my library includes any third party UI library (e.g vue-loading-overlay). But other libraries like moment.js will have no problem.
This is my vite.config.js, Is there any problem with my configuration?
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
export default defineConfig({
plugins: [vue()],
build: {
lib: {
entry: resolve(__dirname, "src/lib.ts"),
name: "my-ui-lib",
fileName: "my-ui-lib",
},
rollupOptions: {
external: ["vue"],
output: [
{
format: "es",
exports: "named",
globals: { vue: "vue" },
},
],
},
},
});
Finally I resolved my problem, Adding the following in vite.config.js. It works for me.
build: {
/** If you set esmExternals to true, this plugins assumes that
all external dependencies are ES modules */
commonjsOptions: {
esmExternals: true
},
}
Original Answer
"Chart.js V3 is treeshakable so you need to import and register everything or if you want everything you need to import the chart from the auto import like so:
change
import Chart from 'chart.js'
to ->
import Chart from 'chart.js/auto';
For more information about the different ways of importing and using chart.js you can read the integration page in the docs.
Since you are upgrading from Chart.js V2 you might also want to read the migration guide since there are some major breaking changes between V2 and V3"
/* Adding the following in vite.config.js. Just copy and paste all these code. It works for me. */
import { defineConfig } from "vite";
import react from "#vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
commonjsOptions: {
esmExternals: true,
},
});
react-pdf v6 has a pretty clever solution for this, look at their entry files. I think the point is to link to the correct file, somehow there's no need to "actually" import the worker (it doesn't run on main thread anyway I guess? New to worker and pdfjs).
import * as pdfjs from 'pdfjs-dist/build/pdf';
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.js', import.meta.url);
import.meta availability.
Refer to vuejs 3 documentation to import vue.

Loading vuetify in a package that i use in a vuetify project

What is the correct way of loading vuetify into a package that i use in a vuetify project?
When serving projects it all seems to work fine but when i build the project i've got some issues with the css/sass
things i've tried:
With vuetify loader: the css is loaded twice so i can't overwrite sass variables
Without vuetify loader: the package doesn't have the vuetify css, so it looks horrible
Without vuetify loader with vuetify.min.css: the css is loaded twice so i can't overwrite sass variables, and the loaded css is all the css so it's huge
My package is called vuetify-resource, and this is the source code of the index.js (without the vuetify loader) At this point everything works on npm run serve But when i build the package doesn't have "access" to the vuetify css.
import Vue from 'vue';
import Vuetify from 'vuetify';
import VuetifyResourceComponent from './VuetifyResource.vue';
Vue.use(Vuetify);
const VuetifyResource = {
install(Vue, options) {
Vue.component('vuetify-resource', VuetifyResourceComponent);
},
};
export default VuetifyResource;
To solve my issue i had to do a couple of things.
Make peer dependencies of vuetify and vue
add vuetify to the webpack externals, so when someone uses the package, the package uses that projects vuetify
not longer import vue and vuetify in the index.js it's not needed, the project that uses the package imports that
import the specific components that you use in every .vue file
for example:
Vue.config.js
module.exports = {
configureWebpack: {
externals: {'vuetify/lib': 'vuetify/lib'},
},
};
index.js
import VuetifyResourceComponent from './VuetifyResource.vue';
const VuetifyResource = {
install(Vue, options) {
Vue.component('vuetify-resource', VuetifyResourceComponent);
},
};
export default VuetifyResource;
part of the component.vue
import { VDataTable } from 'vuetify/lib';
export default {
name: 'vuetify-resource',
components: {
VDataTable
},
Step 4 in Ricardo's answer is not needed if you use vuetify-loader, it will do the job for you.
And I would modify step 2 to also exclude Vuetify's styles/css from your bundle. If you don't exclude them you can run into styling issues when the Vuetify version differ between your library and your application.
Use a regular expression in vue.config.js like this: configureWebpack: { externals: /^vuetify\// }. That way, only your own styles are included in the library bundle.

SyntaxError: Unexpected identifier - Nonsensical error in React Enzyme testing

I'm developing in React Native and trying to set up jest testing by following the directions at https://airbnb.io/enzyme/docs/guides/react-native.html.
I think I've set everything up correctly. Here's my config:
//setup-tests.js
import "react-native";
import "jest-enzyme";
import Adapter from "enzyme-adapter-react-16";
import Enzyme from "enzyme";
// Set up DOM in node.js environment for Enzyme to mount to
const { JSDOM } = require("jsdom");
const jsdom = new JSDOM("<!doctype html><html><body></body></html>");
const { window } = jsdom;
function copyProps(src, target) {
Object.defineProperties(target, {
...Object.getOwnPropertyDescriptors(src),
...Object.getOwnPropertyDescriptors(target)
});
}
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: "node.js"
};
copyProps(window, global);
// Set up Enzyme to mount to DOM, simulate events, and inspect the DOM in tests.
Enzyme.configure({ adapter: new Adapter() });
/* Ignore some expected warnings
* see: https://jestjs.io/docs/en/tutorial-react.html#snapshot-testing-with-mocks-enzyme-and-react-16
* see https://github.com/Root-App/react-native-mock-render/issues/6
*/
const originalConsoleError = console.error;
console.error = message => {
if (message.startsWith("Warning:")) {
return;
}
originalConsoleError(message);
};
// jest.config.js
module.exports = {
setupFilesAfterEnv: "<rootDir>setup-tests.js"
};
// Test.test.js
import React from "react";
import renderer from "react-test-renderer";
import { mount, ReactWrapper } from "enzyme";
import { Provider } from "react-redux";
import { Text } from "react-native";
import LoginView from '../js/LoginView'
You'll see the top of LoginView in a moment.
You'll notice that I haven't even written any tests in the test file, I'm just trying to get jest running to the point where it can evaluate a test.
Without the import LoginView, jest runs and "fails" because my test suite must contain at least one test. Sounds good.
Adding in the import LoginView, I get this error (which shows the import statements at the top of LoginView:
import Button from './buttons/Button';
^^^^^^
SyntaxError: Unexpected identifier
1 | import React, { Component } from "react";
> 2 | import { Input, Button, Image } from "react-native-elements";
| ^
3 | import { Text, View } from "react-native";
4 | import { connect } from "react-redux";
5 | import F8StyleSheet from "./F8StyleSheet";
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
at Object.<anonymous> (js/LoginView.js:2:1)
So this doesn't make sense to me for a number of reasons.
LoginView renders fine in the actual app, with no "Unexpected identifier" crashes or warnings or anything
The lower arrows in the error on line 2 point to import, which of course shouldn't be unexpected.
Then there's the upper arrows that indicate a line from react-native-elements, so, I don't know about that.
Now, it does occur to me that the jest.config.js file did require me to use module.exports, and fails/crashes when I tried using export default { setupFiles } (or however I tried to do it, allowing VS Code to update it to ES6 syntax). So maybe that's why it's not liking import.
Even if that's the case, I don't know what the heck to do next.
Update
I put in the code suggested in Brian's answer, and I'm now getting all new errors. Even though the errors suggest fixes, it doesn't seem to help –- I've added the following to my package.json under jest. I'm not sure where Dimensions.js is anyway; plus, I would assume that all this setup I'm doing for React Native in particular would know how to identify the convention of having file.ios.js and file.android.js be equivalent to file.
Here's my "fix" following the instructions, which doesn't help at all.
"moduleFileExtensions": [
"js",
"json",
"jsx",
"ts",
"tsx",
"node",
"ios.js",
"android.js"
]
And here's the new errors.
FAIL tests/Test.test.js
● Test suite failed to run
Cannot find module './Platform' from 'Dimensions.js'
However, Jest was able to find:
'./Platform.android.js'
'./Platform.ios.js'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].
See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string
However, Jest was able to find:
'../Utilities/Dimensions.js'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].
See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string
However, Jest was able to find:
'buttons/Button.js'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].
See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string
However, Jest was able to find:
'../js/LoginView.js'
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].
See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:229:17)
at Object.require (node_modules/react-native/Libraries/Utilities/Dimensions.js:14:18)
react-native-elements contains ES6 code.
ES6 code needs to be compiled before it can be run by Jest.
By default Jest doesn't compile anything in node_modules, but react-native has a jest-preset that tells Jest to compile react-native and #react-native-community modules.
To include react-native-elements you will need to tell Jest to compile it as well by adding the following to your Jest config:
transformIgnorePatterns: [
'node_modules/(?!(jest-)?react-native|#react-native-community|react-native-elements)',
]

Type 'SQLiteOriginal' is not assignable to type 'Provider'

I'm new to Ionic 4 and am trying to get SQLite working. I have added the cordova plugin and the ionic native sqlite but when I try and set it up in the app module I get the above error. Here is my app,module.ts
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { IonicStorageModule } from '#ionic/storage';
import { SQLite } from '#ionic-native/sqlite';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), IonicStorageModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
SQLite,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
Can anyone help?
You have to import from '#ionic-native/sqlite/ngx'
https://ionicframework.com/docs/native
It looks like this has to do with the recent release of Ionic 4. I ran into this issue with #ionic-native/file within my app. If you installed after the release without specifying the version you wanted, you probably got the latest or beta version.
I was able to fix it by rolling back to an earlier version by modifying my package.json to reflect the version required -- I had 5.0.0 installed and rolled back to 4.20.0. If you have VersionLens for VSCode it will show you the minimum and the latest versions.
Then, clear your node modules, and reinstall:
rm -rf node_modules/
npm install
There is another post open this, available here:
Type HTTPOriginal is not assignable to type Provider, ionic error after plugin installation
It happens because of the new update of ionic 4.
You have to add /ngx to your plugin's import. Like this:
import { PluginName} from '#ionic-native/pluginName/ngx';
Otherwise fallback to ionic v4.
More info here
Everywhere where native plugins are imported, you need to add /ngx/.
Moreover, this must be done throughout the project, otherwise the error will still appear.
Error example:
import {Market} from '#ionic-native/market';
True example:
import {Market} from '#ionic-native/market/ngx';
Import:
import { SQLitePorter } from '#ionic-native/sqlite-porter/ngx';
import { SQLite } from '#ionic-native/sqlite/ngx';
And add into provider:
providers: [
SQLite,
SQLitePorter
]
This usually happens if you import them from different path.
You have to import '#ionic-native/sqlite/ngx' at both app.module.ts and the page you want to use it.