nuxt + mdi/js tree shaking not working. how to fix? - icons

package.json
"dependencies": {
"nuxt": "^2.15.7",
},
"devDependencies": {
"#mdi/js": "^5.9.55",
}
use
import {mdiPencil} from '#mdi/js'
export default {
data: () => ({
mdiPencil
}),
}
I see the whole list in the bundle
/_nuxt/vendors/pages/index.js
exports provided: mdiAbTesting, mdiAbacus, mdiAbjadArabic, mdiAbjadHebrew, mdiAbugidaDevanagari, mdiAbugidaThai, mdiAccessPoint, mdiAccessPointCheck, mdiAccessPointMinus, mdiAccessPointNetwork, mdiAccessPointNetworkOff, mdiAccessPointOff, mdiAccessPointPlus ... with svg
project: https://github.com/IceRD/nuxt
Here is the bundlephobia of it: https://bundlephobia.com/package/#mdi/js#5.9.55

Related

How to import an object in Next.js that requires the document object? [duplicate]

I have a simple project
import Music from '../components/music';
export default function Home() {
return (
<Music></Music>
)
}
import dynamic from 'next/dynamic';
const abcjs = dynamic(import('abcjs'), { ssr: false });
export default function Music({note}) {
return (
<>
<div id="paper"></div>
{abcjs.renderAbc("paper", "X:1\nK:D\nDDAA|BBA2|\n")}
</>
)
}
my package.json is
{
"name": "music-quiz",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "cross-env NODE_OPTIONS='--inspect' next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"abcjs": "^5.12.0",
"next": "10.2.0",
"react": "17.0.2",
"react-dom": "17.0.2",
},
"devDependencies": {
"cross-env": "^7.0.3"
}
}
However, the browser tells me abcjs.renderAbc is not a function and as far as I can tell this should work.
If it makes any difference I'm running next.js with npm run dev.
If I try to log abcjs I appear to get sort of an empty object. vscode tells me that there is it cannot find a declaration type for abcjs, but that shouldn't matter.
Clearly the library isn't being imported correctly but I have no idea why this is.
EDIT: I should add that I found this example and are adapting it to next.
There is also something in the FAQ about this, but it doesn't solve the issue
next/dynamic is used to dynamically import React components.
To dynamically import regular JavaScript libraries you can simply use ES2020 dynamic import().
import { useEffect } from "react";
export default function Music({ note }) {
useEffect(() => {
const abcjsInit = async () => {
const abcjs = await import("abcjs");
abcjs.renderAbc("paper", "X:1\nK:D\nDDAA|BBA2|\n")
};
abcjsInit();
}, []);
return (
<div id="paper"></div>
)
}

Vuetify 3 and storybook 6 - styles and components do not work

I´ve been researching a lot about Vuetify + Storybook integration.
I installed Vuetify using Vite and then installed the storybook/vue3 plugin using:
npx sb init --builder storybook-builder-vite
The problem is that every component that I created is not using the Vuetify styles. I read here that I need to extend the Storybook app so my preview.js looks like:
// .storybook/preview.js
import { app } from '#storybook/vue3';
import vuetify from '../src/plugins/vuetify'
app.use(vuetify);
export const decorators = [
(story) => ({
components: { story },
template: '<v-app><story /></v-app>',
}),
];
But this doesn't seem to work. It doesn't throw any errors in the terminal and not in the browser but the vuetify styles and components do not work. My components are being render normally with Vuetify if I try to run the app itself.
Any ideas? I´m totally lost. Maybe there´s no support since Vuetify 3 is on alpha? Or this is a storybook issue?
Here´s my repo if you want to check it out https://github.com/heyimnowi/vue-ui-library
OMG I cannot believe I solve it by just doing this:
const path = require('path')
const vuetify = require('#vuetify/vite-plugin'); // THIS
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
"#storybook/addon-links",
"#storybook/addon-essentials"
],
"framework": "#storybook/vue3",
"core": {
"builder": "storybook-builder-vite"
},
async viteFinal(config, { configType }) {
config.resolve.alias['~storybook'] = path.resolve(__dirname)
config.resolve.alias['#'] = path.resolve(__dirname, '..', 'src')
config.css = {
preprocessorOptions: {
scss: { additionalData: `#import "src/styles/application.scss";` },
},
};
config.plugins = [
...config.plugins,
vuetify() // THIS
];
return config;
}
}

How to setup storybook at root level lerna monorepo

I am working on a project which is set up with lerna mono repo, we have multiple stencilJS projects for an individual component inside packages of monorepo.
My project sructure is:
I am new to the storybook, now I have to set up the storybook at the root level which all the packages storybook.
I followed an article on the internet and I have set up something which works only for a single package component, due to the current style of setup.
Due to defineCUstomElements in preview.js it is loading the first project package loader I am able to see only the first project stories. Css is not loading for second project stories.
Can someone help me to set up a storybook at the root level which works for all packages?
My example
storybook/main.js
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../packages/plugin-*/src/components/plugin-*/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
'#storybook/addon-links',
'#storybook/addon-essentials',
'#storybook/addon-viewport',
'#storybook/addon-notes',
'#storybook/addon-docs'
]
}
storybook/preview.js
import { defineCustomElements } from '../packages/stencilProj1/loader';;
defineCustomElements();
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
};
package/stencilProj1/component1.stories.ts
import readme from './readme.md'
import React from 'react';
import ComponentButton from '../../../dist/collection/components/ComponentButton /ComponentButton';
export default {
title: 'Button',
component: ComponentButton,
argTypes: {
label: { control: 'text' },
type: { type: 'select', options: ['primary'] },
disabled: { control: 'boolean' }
},
parameters: {
markdown: readme
},
};
const Template = ({ label, type, disabled = false }) => {
return <component-button type={type} disabled={disabled}>{label}</component-button>;
};
export const Primary = Template.bind({});
Primary.args = {
type: 'primary',
label: 'Primary Button',
};
After a couple of months of attempts, I finally solved this puzzle :) And want to share my solution with community
I have a lerna v4 monorepo for react v17 + mui v5 components written in typescript and flavored with storybook v6 and webpack v5
mui has its wrappers in preview.js, that's why I added the path to .storybook in babel-loader
module.exports = {
core: {
builder: "webpack5",
},
framework: "#storybook/react",
stories: ["../components/**/*.stories.#(ts|tsx)"],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
{
name: "#storybook/preset-create-react-app",
options: {
craOverrides: {
fileLoaderExcludes: ["less"],
},
},
},
],
webpackFinal: config => {
const {
module: {
rules: [, , , , , { oneOf }],
},
} = config;
const babelLoader = oneOf.find(({ test }) => new RegExp(test).test(".ts"));
babelLoader.include = [/components\/(.*)\/src/, /.storybook/];
babelLoader.options.sourceType = "unambiguous";
return config;
},
};
it is also worth to mention my tsconfig has these lines
"rootDirs": [
"./src",
],
Have you tried to import project 2's defineCustomElement with "as" to rename it and use it?
(something along the line of following inside preview.js)
import { defineCustomElements } from '../packages/stencilProj1/loader';
import { defineCustomElements as defineSecondProject } from '../packages/stencilProj2/loader';
defineCustomElements();
defineSecondProject();
This is very manual and even if this works, if you have many repo might not be good solution but I've done something similar to load multiple component loaders and that seem to work OK for my use case in the past.

Import SQLite db using expo

I’m a newbie to React Native and Expo and I want to implement an SQLite database from “/assets/test.db” as you can see on sqlitebrowser:
sqlitebrowser sreenshot
I tried many ways but it never work so I based my code on the most popular way I found : https://forums.expo.io/t/solved-import-asset-db/11469
These things been sayed, here’s my code:
//App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import * as FileSystem from 'expo-file-system'
import * as SQLite from 'expo-sqlite'
import { Asset } from 'expo-asset'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
item: null
}
}
componentDidMount() {
this.makeSQLiteDirAsync()
FileSystem.downloadAsync(
Asset.fromModule(require("./assets/test.db")).uri,
`${FileSystem.documentDirectory}SQLite/test.db`
)
.then(function(){
const db = SQLite.openDatabase('test.db');
console.log(db);
db.transaction(tx => {
tx.executeSql('SELECT * FROM User;',
[],
(_, {rows}) => console.log(rows))
},
);
});
}
makeSQLiteDirAsync = async() => {
const dbTest = SQLite.openDatabase('dummy.db');
try {
await dbTest.transaction(tx => tx.executeSql(''));
} catch(e) {
if (this.state.debugEnabled) console.log('error while executing SQL in dummy DB');
}
}
render() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
And here’s the result on terminal:
WebSQLDatabase {
"_currentTask": null,
"_db": SQLiteDatabase {
"_closed": false,
"_name": "test.db",
},
"_running": false,
"_txnQueue": Queue {
"length": 0,
},
"exec": [Function anonymous],
"version": "1.0",
}
Many peoples also advised to change ‘app.json’ and ‘metro.config.js’ the following way:
//app.json
{
"expo": {
"name": "Test: server",
"slug": "snack-42ed5540-be82-47b4-898a-d9acb300c559",
"privacy": "public",
"sdkVersion": "35.0.0",
"platforms": [
"ios",
"android",
"web"
],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/settings.png",
"splash": {
"image": "./assets/settings.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"packagerOpts": {
"assetExts": ["db"]
}
}
}
//metro.config.js
module.exports = {
resolver: {
assetExts: ["db", "mp3", "ttf"]
}
}
I didn’t find anything really different on the other topics or forums so there must be something I did wrong but I don’t see anything I can do to manage it. If you have any question or solution I’ll be there !
The makeSQLiteDirAsync function is to just ensure the SQLite folder is created in the device. Anyway the issue here is that react native will ignore the test.db file when bundling the assets like json, images, etc.
We need to instruct the metro bundler to allow the packaging of the SQLite .db file present in the assets folder. Code should work file if you add your additional assets extensions to the set of default assets already supported.
//metro.config.js
const defaultAssetExts = require("metro-config/src/defaults/defaults").assetExts;
module.exports = {
resolver: {
assetExts: [
...defaultAssetExts,
"db",
"sqlite"
]
}
};
You can check metro-config folder in node_modules and also check the file in node_modules/metro-config/src/defaults/defaults.js to see the list of default assets.
Also, another thing to note is that expo does not recognize below option in app.json. Best to remove this.
"packagerOpts": {
"assetExts": ["db"]
}

Imported styles object is empty in Jest

I have a component:
import React from 'react';
import * as styles from './RedComponent.css';
class RedComponent extends React.Component {
render () {
return <div className={ styles.red }></div>;
}
}
This is the test case:
describe('Test suite', () => {
test('RedComponent tests', () => {
const wrapper = shallow(<RedComponent />);
});
console.log(wrapper.debug());
gives
<div className={[undefined]}></div>
instead of
<div className="RedComponent__red"></div>
If I console the imported styles I get
console.log(styles); // {default: {}}
This is only in Jest test cases. Style is not undefined when the app renders in browser.
My jest config:
{
"moduleFileExtensions": [
"js"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
},
"setupFiles": [
"./test-setup.js"
],
"collectCoverageFrom": [
"src/**/*.{js}",
"!**/node_modules/**"
],
"testEnvironment": "node",
"transform": {
"^.+\\.js$": "babel-jest",
"\\.(md|ttf|txt|eot|ico|otf|svg|png|gif|woff2|woff|jpeg)$": "./file-transformer.js"
}
}
Using jest v21.2.1, identity-obj-proxy v3.0.0 and React v16.0.0.
You have to change this line
import * as styles from './RedComponent.css';
to this:
import styles from './RedComponent.css';
I assume that you are using css-loader or similar and this is just how the loader works.
Maybe worths to check the example:
https://github.com/keyanzhang/jest-css-modules-example/
I think your moduleNameMapper should be like this:
"^.+\\.(css|less)$": "identity-obj-proxy"
Create a jest/identity-obj-proxy-esm.js file with the following content:
// This works around the fact we use ES named exports for styles, e.g.:
// import * as styles from './styles.scss'.
// https://github.com/keyanzhang/identity-obj-proxy/issues/8
module.exports = new Proxy(
{},
{
get: function getter(target, key) {
if (key === '__esModule') {
// True instead of false to pretend we're an ES module.
return true;
}
return key;
},
},
);
Edit jest.config.js:
// jest.config.js
module.exports = {
...
moduleNameMapper: {
...
'\\.(css|scss)$': '<rootDir>/jest/identity-obj-proxy-esm.js',
}
};
🏆 João Vieira and https://github.com/keyz/identity-obj-proxy/issues/8#issuecomment-430241345

Resources