mochapack Cannot assign to read only property 'exports' of object - javascript

I would like to create a vuejs unit test for components.
I follow this official tutorial vuejs : Vuejs component unit test
I have created those file :
setup.js (main script for all test) :
require('jsdom-global')()
global.expect = require('expect')
// import jsdomGlobal from 'jsdom-global'
// export const jsdonGlobal = require('jsdom-global')
home.spec.js (unit test component file) :
import Vue from 'vue'
import { shallowMount } from '#vue/test-utils'
import Home from '../../src/page/Home.vue'
// import Home from '#/components/Home'
describe('Home.vue', () => {
it('test the test', async () => {
const wrapper = shallowMount(Home)
let divContainer = wrapper.find('div.container')
expect(divContainer.children()).to.have.length(12)
})
})
my babel.config.js :
module.exports = {
presets: [
'#vue/app',
'#babel/preset-env'
],
}
and this my 'npm run test' command :
"mochapack --webpack-config webpack.config.js --require test/setup.js test/**/*.spec.js"
All of this generate a 'Cannot assign to read only property 'exports' of object '#' error
others informations :
if a comment all line into setup.js and Home.spec.js file the behavior is identic (very strange behavior which difficult to understand where is the error)
I already try this preset Babel ('#babel/preset-env') for transpiling
I don't have a export instruction into my setup.js file and Home.spec.js file
Can you help me to understand why I have to error and how I can resolve this ?
The all others questions don't help me to resolve this because I don't have export instruction into my test code...

Related

How to use composable inside a component from the same npm module

I want to create a npm plugin that contains all the elements that I often use in my Nuxt projects.
I followed the instructions here : https://v3.nuxtjs.org/guide/going-further/modules/ and there : https://www.youtube.com/watch?v=7MBOOxUg1yM but I'm still experiencing an issue with the composables.
I added this in the setup function of my module.js :
const runtimeDir = fileURLToPath(new URL('./runtime', import.meta.url));
addImports({
name: 'useTheme',
as: 'useTheme',
from: resolve(runtimeDir, 'composables')
});
await addComponentsDir({
path: resolve(runtimeDir, 'components'),
prefix: 'my-project'
});
And here's my composables.js :
import { useState } from '#app';
export const useTheme = () => useState('theme', () => 'dark');
And when I try to use the useTheme in my ThemeToggle.vue, I have an error "useTheme is not defined"
<script setup>
const theme = useTheme();
</script>
I tried to add an import like this :
import { useTheme } from '#app';
But it throw me an other error __vite_ssr_import_0__.useTheme is not a function
Any idea ?

laravel-vue-pagination module not loading in app

After loading in the laravel-vue-pagination module, I added it to app.js and tried to use it. I was able to import the component and export as props with no issue, but using the element gives me this error:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '_c')
I also get a Vetur message in my app.js on hover.
Could not find a declaration file for module 'laravel-vue-pagination'. 'e:/Dev/repos/itgg-core/node_modules/laravel-vue-pagination/dist/laravel-vue-pagination.common.js' implicitly has an 'any' type.
Try `npm i --save-dev #types/laravel-vue-pagination` if it exists or add a new declaration (.d.ts) file containing `declare module 'laravel-vue-pagination';`Vetur(7016)
According to this, I added a laravel-vue-pagination.d.ts file at the root of my project:
declare module 'laravel-vue-pagination' { }
This doesn't seem to help in any way though.
app.js :
require('./bootstrap');
// Import modules...
import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
const el = document.getElementById('app');
createApp({
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
}),
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.mount(el);
InertiaProgress.init({ color: '#4B5563' });
require('chart.js');
require('laravel-vue-pagination');
I assume something is wrong with the require, or loading the module, but I am not sure. Any help is greatly appreciated.

How to construct js object in React

I have some problems with React and Advertisement.
Wanna use 'Coupang' Advertisement, but they support the script library only.
I can add it to 'index.html' in the public directory, but cannot customize the location.
here is the code,
<script src="https://ads-partners.coupang.com/g.js"></script>
<script>
new PartnersCoupang.G({"id":23232,"subId":null});
</script>
It's a dynamic advertisement.
How can I add it to the React functional component??
MB this will be helpful.
useScript will help you add script to your code dynamically.
and you custom hook (just create PartnersCoupang);
const usePartnersCoupang = () => {
const const [loaded, error] = useScript('https://ads-partners.coupang.com/g.js');
React.useEffect(() => {
if (loaded) {
new PartnersCoupang.G({"id":23232,"subId":null});
}
}, [loaded]);
React.useEffect(() => {
if (error) {
console.error('PartnersCoupang Failed.');
}
}, [error]);
}
Actually, you should eject from your create-react-app project by this command:
$ yarn eject
or:
$ npm run eject
Then you can see a folder that name is config, in this folder you can see all configuration of your project, especially your Webpack configs, then you should add your external library to the webpack as external key on the configuration of Webpack:
// webpack.config.js
...
module.exports = {
...
externals: {
PartnersCoupang: '[path-to]/g.js',
},
...
};
Then in your component import it easily:
import React, { Component } from 'react';
import PartnersCoupang from 'PartnersCoupang';
class YourComponent extends Component {
componentDidMount() {
new PartnersCoupang.G({"id":23232,"subId":null});
}
}

Error in Vue i18n with TypeScript: "Property '$t' does not exist on type 'VueConstructor'. " . How can I fix it?

In project some common function are in separate .ts files.
How can I use i18 in that cases:
// for i18n
import Vue from 'vue'
declare module 'vue/types/vue' {
interface VueConstructor {
$t: any
}
}
declare module 'vue/types/options' {
interface ComponentOptions<V extends Vue> {
t?: any
}
}
(()=>{
const test = Vue.$t('auth.title');
console.log( test )
})()
Return an error:
Property '$t' does not exist on type 'VueConstructor<Vue>"
How can I fix it?
we can achieve the same like below
Step 1: create a separate index.ts file inside a i18n folder (you can do it your own way - root level or any where in your app)
i18n/index.ts
import Vue from 'vue';
import VueI18n from 'vue-i18n';
// register i18n module
Vue.use(VueI18n);
const i18n = new VueI18n({
locale: 'nb-NO', //if you need get the browser language use following "window.navigator.language"
fallbackLocale: 'en',
messages: {en, no},
silentTranslationWarn: true
})
const translate = (key: string) => {
if (!key) {
return '';
}
return i18n.t(key);
};
export { i18n, translate}; //export above method
Step 2: make sure to use(import) above in main.ts
main.ts
import { i18n } from '#/i18n';
new Vue({ i18n, render: h => h(app) }).$mount('#app')
after above configuration we should be able to use translation in any place that we want in our application
Step 3: How to use it in .ts and .vue files
// first import it into the file
import { translate, i18n } from '#/i18n';
//this is how we can use translation inside a html if we need
<template>
<h1>{{'sample text' | translate}}</h1>
</template>
//this is how we can use translation inside a .ts or .vue files
<script lang='ts'>
//normal scenario
testFunc(){
let test = `${translate('sample text')}`;
console.log(test );
}
//in your case it should be like below
(()=>{
const test = `${translate('auth.title')}`;
console.log( test )
})()
</script>
I hope that this will help you to resolve your issue.

Cannot import SCSS file while running mocha test on isomorphic app

I'm trying to test a react component.
Foo.jsx
import * as React from 'react';
require('css/foo'); // foo.scss but using resolve in the webpack
...rest of code
Foo.spec.js (this is just a boiler place for test)
import * as React from 'react';
import * as TestUtils from 'react-addons-test-utils';
import Foo from '../src/js/Foo';
function setup() {
const renderer = TestUtils.createRenderer();
renderer.render(<Menu />);
const output = renderer.getRenderOutput();
return {
props: props,
output: output,
renderer: renderer
}
}
describe('Menu Component', () => {
it('should render', () => {
setup();
})
});
tests.js
function noop() {
return null;
}
require.extensions['.scss'] = noop;
When trying to load mocha from CLI
./node_modules/.bin/mocha tests.js ./test/**/*.spec.js
And I'm getting an error
Error: Cannot find module 'css/foo' ...
I tried:
Handle WebPack CSS imports when testing with Mocha
but it doesn't work either.
If I comment that line out, the test is executing.
I've found the solution.
https://github.com/darul75/web-react/blob/master/app/components/TodoSection/TodoItem.js#L13
When I'm running test on the server:
APP_ENV=SERVER ./node_modules/.bin/mocha tests.js ./test/**/*.spec.js
On the client I have to add a plugin to the webpack config:
plugins: [
new webpack.DefinePlugin({
'process.env': {
'APP_ENV': JSON.stringify('BROWSER'),
}
})
]
Assuming you're using Webpack for the test, you can use Sokra (the creator of Webpack)'s null-loader, to make sure that all SCSS requires/imports result in null, and thereby not causing any errors.
{test: /\.scss?$/, loader: 'null'}
https://github.com/webpack/null-loader

Categories