Could I use pinia without installing vue? - pinia

How could i use pinia without vue and vite?
"dependencies": {
"pinia": "^2.0.11",
"vite": "^2.7.13",
"vue": "^3.2.30"
}
I try to use pinia like this:
import { createApp } from 'vue';
import { useLoginStore } from './src/index.js';
import { createPinia } from 'pinia';
const pinia = createPinia();
const app = createApp({
data() {
return {};
}
});
app.use(pinia);
const useState = useLoginStore();
console.log(`<<<<01-24 08:52:27>>>>⬇️\n✨`, `useState`, useState);
and i use node to run it: node test
But it return error
Cannot find package '#vue/composition-api' imported from ...\node_modules\vue-demi\lib\index.mjs

Assume that your node test means running test.js, with the content in the file like what you mentioned in the question and no bugs happened in useLoginStore, your code should run fine since I can run your example functionally.
For the Cannot find package questions, I suggest you delete the node_modules directory and reinstall packages by typing npm install.
If you are asking if Pinia can run without installing Vue, the answer is simply no, since Pinia needs to be activated by Vue. You will face the following error if trying to run Pinia without Vue:
import { defineStore } from 'pinia'
const useLoginStore = defineStore('login', { /* Options */ });
const useState = useLoginStore();
console.log( useState );
Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
const pinia = createPinia()
app.use(pinia)
This will fail in production.
References:
https://vuejs.org/api/application.html#app-use
https://github.com/vuejs/pinia/discussions/664
https://github.com/vuejs/pinia/discussions/1238

Related

How to use Pinia outside a component in js file

I am migrating from vue 4.x to pinia, one of my file needs api key from store.
But I can't make it work even though I follow the Pinia documentation .
here is how I use pinia
// Repository.ts
import axios from "axios";
import { createPinia } from 'pinia'
import { useAuthStore } from '../stores/auth-store'
const pinia=createPinia();
let authStore = useAuthStore(pinia);
const baseURL = 'http://127.0.0.1:5678/res-api';
export default axios.create({
baseURL,
headers:{"Authorization":"Bearer " + authStore.getToken,
"Accept":"application/json"},
});
Expected result : to get the token from the store.
Console error
Uncaught ReferenceError: Cannot access 'useAuthStore' before initialization
at Repository.ts:6:17
Note: this working inside a component
You can solve this by importing the store inside the interceptors
import axios from "axios";
import { useAuthStore } from '../stores/auth-store';
const axiosClient = axios.create({
baseURL: 'http://127.0.0.1:5678/res-api'
});
axiosClient.interceptors.request.use((config) => {
const authStore = useAuthStore();
config.headers.Authorization = `Bearer ${authStore.getToken}`;
config.headers.Accept = "application/json";
return config
})
export default axiosClient;
This discussion may help you: Go to GitHub discussion
According to the documentation the pinia you created must go as a parameter to app.use. Not only that, but useAuthStore must be a store defined with defineStore and must not take a parameter. I'll leave a link that can help you, it doesn't create the store but you can browse the side menu to see several examples.
https://pinia.vuejs.org/core-concepts/outside-component-usage.html
Here is my sample project to demo the issue: https://codesandbox.io/s/infallible-shamir-sxrlb9.
The main cause here is that you cannot use Pinia's stores before passing it to the Vue's app. So given following code:
const pinia = createPinia(); // line 1
createApp(App).use(pinia).mount("#app"); // line 2
You cannot trigger any store in between line 1 and 2, but only after line 2.
In your code, likely you trigger an axios call before creating Vue app/add Pinia to Vue app. Please try to delay that axios call to trigger after Vue app's setup is complete.

How to use Quasar 2 with AWS Amplify?

I have created the following boot file for Quasar in src/boot/amplify.js and added 'amplify' to quasar.conf.js:
import Amplify from 'aws-amplify';
import awsconfig from '../aws-exports';
import {
applyPolyfills,
defineCustomElements,
} from '#aws-amplify/ui-components/loader';
applyPolyfills().then(() => {
defineCustomElements(window);
});
Amplify.configure(awsconfig);
But I get many import errors from the line import Amplify from 'aws-amplify';:
Module not found: Can't resolve imported dependency "./printError"
App • ERROR • UI in ./node_modules/graphql/error/GraphQLError.mjs
And more -- I've gotten passed them with npm install --save graphql, but I then found many more errors for the import. It is easy to setup following Amplify docs using Vue 3 CLI and not Quasar.
Anyone had luck using Quasar or know what a possible solution might be?
is a webpack issue, check this:
https://github.com/graphql/graphql-js/issues/2721#issuecomment-723008284
I solved it by adding to the quasar.conf.js
build: {
...
extendWebpack (cfg, {isServer, isClient}) {
cfg.module.rules.push ({
test: /\.m?js/,
resolve: {
fullySpecified: false,
fallback: {crypto: false}
}
})
}
}
}
the "fallback : {crypto: false}"
it is used to resolve the subsequent error about the missing dependency of crypto-js based on:
https://stackoverflow.com/a/67076572/1550140

Electron + Jest - ipcRenderer is undefined in unit tests

I am contributing to a project which is built with React (with webpack) running in Electron. When executing unit tests with Jest, it fails with the error TypeError: Cannot read property 'on' of undefined (and works fine when not testing, eg. run with Electron).
The code:
import React, { Component } from 'react';
import { ipcRenderer } from 'electron';
// some more imports
class Setup extends Component {
constructor(props) {
super(props);
this.state = {
// some state
};
ipcRenderer.on('open-file-reply', this.someMethod); // << fails on this line
}
// more class stuff
}
It took me a few days but finally, I found this answer in this great blog post. Quote:
Jest is called from Node and doesn't run test code through Webpack.
Instead, we have to use Jest's mocking functions to replace the import
with a stub file.
Jest has a helper method called moduleNameMapper [object<string, string>] . From jest documentation:
A map from regular expressions to module names that allow to stub out
resources, like images or styles with a single module.
It should be added in your package.json root object like this:
{
"name": "My awesome app",
"jest": {
"moduleNameMapper": {
"electron": "<rootDir>/src/components/tests/mock/electron.js"
}
}
}
and the mock file itself (/src/components/tests/mock/electron.js):
export const ipcRenderer = {
on: jest.fn()
};
This way you can stub other electron modules and methods (like remote which is shown in the blog above).
Another way is creating an electron.js file in __mocks__ in your root folder.
The electron.js should look something like
export const ipcRenderer = {
on: jest.fn(),
};
You can read more at https://jestjs.io/docs/en/manual-mocks#mocking-node-modules

Testing react-intl components with enzyme

I have looked into react-intl for suggestions but it doesn't leave any explicit documentation for enzyme.
This is how I have been trying to write my tests.
import {IntlProvider} from 'react-intl';
const intlProvider = new IntlProvider({locale: 'en'}, {});
const intl = intlProvider.getChildContext();
const customMessage = shallow(<CustomMessage />, { options: { context: intl } });
But I keep getting the error
Invariant Violation: [React Intl] Could not find required intl object. needs to exist in the component ancestry.
I looked into their repo and they seems to have made it work with 'react-addons-test-utils'.
Am I doing something wrong?
I've posted an answer to a similar question:
Injecting react-intl object into mounted Enzyme components for testing
You would be able to import { shallowWithIntl } from 'intl-helper' and then use shallowWithIntl() instead of Enzyme's shallow().
I got it working by using
const customMessage = shallow(<CustomMessage />, { context: intl });
instead.
Thats how I achieve the things:
import React from 'react';
import StandardFilterIntl, {StandardFilter} from 'bundles/components/Filter/StandardFilter';
import {mountWithIntl} from 'enzyme-react-intl';
const FilterComponent = mountWithIntl(<StandardFilterIntl {...standardFilterProps} />);
FilterComponent.find(StandardFilter).state()

Mocha testing failed due to css in webpack

I'm new to Mocha and I am trying to use it to test a simple React component. The test would pass if the react component doesn't have any CSS styling but throws a syntax error if the tag within the React component contains any className:
Testing.react.js
import React from 'react';
export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" />
</form>
</section>
);
}
}
testing.jsx
import {
React,
sinon,
assert,
expect,
TestUtils
} from '../../test_helper';
import TestingSample from '../../../app/components/Testing.react.js';
describe('TestingSample component', function(){
before('render and locate element', function(){
var renderedComponent = TestUtils.renderIntoDocument(
<TestingSample />
);
var inputComponent = TestUtils.findRenderedDOMComponentWithTag(
renderedComponent, 'input'
);
this.inputElement = inputComponent.getDOMNode();
});
it('<input> should be of type "text"', function () {
assert(this.inputElement.getAttribute('type') === 'text');
});
})
The test would pass:
> mocha --opts ./test/javascripts/mocha.opts --compilers js:babel/register --recursive test/javascripts/**/*.jsx
TestSample component
✓ <input> should be of type "text"
1 passing (44ms)
after I added the className inside of the input tag an error shows up:
import React from 'react';
import testingStyle from '../../scss/components/landing/testing.scss';
export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" className="testingStyle.color" placeholder="Where would you like to dine" />
</form>
</section>
);
}
}
Test result:
SyntaxError: /Users/../../../Documents/project/app/scss/components/landing/testing.scss: Unexpected token (1:0)
> 1 | .color {
| ^
2 | color: red;
3 | }
I've searched online but no luck so far. Am I missing something? Please help me out or point me to the right direction would be greatly appreciated.
I'm currently using:
Node Express Server
React
React-router
Webpack
Babel
Mocha
Chai
Sinon
Sinon-Chai
There is a babel/register style hook to ignore style imports:
https://www.npmjs.com/package/ignore-styles
Install it:
npm install --save-dev ignore-styles
Run tests without styles:
mocha --require ignore-styles
you can use a css compilers run mocha, the compiler js as follow:
css-dnt-compiler.js
function donothing() {
return null;
}
require.extensions['.css'] = donothing;
require.extensions['.less'] = donothing;
require.extensions['.scss'] = donothing;
// ..etc
and run the mocha command like this:
mocha --compilers js:babel-core/register,css:css-dnt-compiler.js --recursive
My same answer as here, this is what I used to get working on Babel 6
package.json
"scripts": {
"test": "mocha --compilers js:babel-core/register
--require ./tools/testHelper.js 'src/**/*-spec.#(js|jsx)'",
tools/testHelper.js
// Prevent mocha from interpreting CSS #import files
function noop() {
return null;
}
require.extensions['.css'] = noop;
This enables you to have your tests inside your src folder alongside your components. You can add as many extensions as you would like with require.extensions.
Since you're using webpack, use null-loader to load null when webpack encounters a required CSS/LESS/SASS/etc file in your components. Install via npm and then update your webpack config to include the loader:
{
test: /(\.css|\.less|.\scss)$/,
loader: 'null-loader'
}
Obviously this will prevent you from loading CSS in your actual application, so you'll want to have a separate webpack config for your test bundle that uses this loader.
For those looking how to handle this in jest - you just add a handler for style files:
// package.json
{
"jest": {
"moduleNameMapper": {
"\\.(css|less|scss|sass)$": "<rootDir>/__mocks__/styleMock.js"
}
}
}
// __mocks__/styleMock.js
module.exports = {};
More here.
None of these solutions worked for me, as I'm using mocha-webpack, and it doesn't accept the "--compilers" switch. I implemented the ignore-styles package, as described in the most popular answer, but it seemed inert, with no difference in my Istanbul coverage report (.less files still being tested).
The problem is the .less loader that I was using in my webpack.config.test.js file. Simply swapping less-loader for null-loader fixed my problem.
module: {
rules: [
{
test: /\.less$/,
use: ['null-loader']
}
]
}
For me, this is by far the simplest solution, and targets my testing configuration directly, rather than having to alter/add to the package.json scripts, or worse, add new .js files.
One simple way is to import 'ignore-styles'; in your test classes..
The code below works without any dependencies. Just add it to the top of the tests.
var Module = require('module');
var originalRequire = Module.prototype.require;
Module.prototype.require = function () {
if (arguments[0] && arguments[0].endsWith(".css"))
return;
return originalRequire.apply(this, arguments);
};
Although very old, this question is still relevant, so let me throw in another solution.
Use pirates, a package to add hooks to require() - if you use Babel, you already have it.
Example code:
// .test-init.js
const { addHook } = require('pirates');
const IGNORE_EXTENSIONS = ['.scss', '.svg', '.css'];
addHook((code, filename) => '', { exts: IGNORE_EXTENSIONS });
This way you can call mocha like so: mocha --require .test-init.js [whatever other parameters you use]
This is straightforward, elegant and unlike ignore-styles it doesn't imply you are ignoring styles only. Also, this is easily extendable if you need to apply some more trickery to your tests like mocking entire modules.