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)
I adding unit tests to my Nuxt/Vue project and I'm using Jest for unit testing, I'm fetching data from the server-side using Apollo Client and I have a problem with importing .gql files inside test files.
here is the query file names.gql
{
names {
created_at
id
name
published_at
updated_at
}
}
I'm importing the query inside Vue component like this
import namesQuery from "#/queries/names";
Test file:
import { mount } from '#vue/test-utils';
import Names from '#/components/Names';
describe('Names', () => {
test('is a Vue instance', () => {
const wrapper = mount(Names)
expect(wrapper.vm).toBeTruthy()
})
})
When I run the tests, it says:
SyntaxError: Unexpected token '{'
Please advise.
According to the graphql-tag documentation you need to use jest-transform-graphql to handle imports.
Add this to your jest config file:
"transform": {
"\\.(gql|graphql)$": "jest-transform-graphql",
}
and then let the party begin 😎
import routes from "./src/router/routes";
module.exports = {
// routes
}
can not use es6 module here, it gives an error:
import routes from "./src/router/routes";
^^^^^^
SyntaxError: Unexpected identifier
also require does not work, as routes are ES6 modules (have import statements)
const routes = require("./src/router/routes");
You must enable the ES6 Modules in NodeJs.
Check this links for enable:
https://nodejs.org/api/esm.html
https://blog.logrocket.com/es-modules-in-node-js-12-from-experimental-to-release/
ATTENTION: This resource is experimental
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>')
...
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)',
]