Modifying an existing file with Plop? - javascript

I’m using plop to generate components for a React-based component library. I have a directory full of Handlebars templates that are used to create new component directories, and all is working well. I also have this index.js file that acts as the entrypoint for my bundler. It’s just full of lots of imports and an export. It looks like this:
import { Badge } from './components/Badge';
import { Button, ButtonMemo } from './components/Button';
import { Column } from './components/Column';
import { ErrorBoundary } from './components/ErrorBoundary';
import { FormBasicInfo } from './components/FormBasicInfo';
import { FormLogin } from './components/FormLogin';
import { FormSignup } from './components/FormSignUp';
import { Icon } from './components/Icon';
import { Input } from './components/Input';
import { Link } from './components/Link';
import { Loader } from './components/Loader';
import { Logo } from './components/Logo';
import { Row } from './components/Row';
import { Select } from './components/Select';
import { SimpleMenu } from './components/SimpleMenu';
import { Slideshow } from './components/Slideshow';
import { Spinner } from './components/Spinner';
export {
Badge,
Button,
Column,
ErrorBoundary,
FormBasicInfo,
FormLogin,
FormSignup,
Icon,
Input,
Link,
Loader,
Logo,
Row,
Select,
SimpleMenu,
Slideshow,
Spinner,
};
When generating a new component, I would love to also add the new component to this entrypoint file. That would require adding an import line to the top block, and an export line to the bottom. Ideally it would still be alphabetically sorted, but that isn’t a hard requirement.
Is this possible?

This is how I ended up pulling it off:
In my index.js file (the one I want modified), I added two comments in the places where the inserts should take place:
…
import { PointAccountCard } from './components/PointAccountCard';
import { Card } from './components/Card';
import { SettingsPanelFooter } from './components/SettingsPanelFooter';
// COMPONENT IMPORTS
export {
…
PointAccountCard,
Card,
SettingsPanelFooter,
// COMPONENT EXPORTS
};
Then in my plopfile.js config, I added these two steps to my actions config:
module.exports = function (plop) {
plop.setGenerator('component', {
actions: [
…
{
path: '../../src/index.js',
pattern: /(\/\/ COMPONENT IMPORTS)/g,
template: 'import { {{name}} } from \'./components/{{name}}\';\n$1',
type: 'modify',
},
{
path: '../../src/index.js',
pattern: /(\/\/ COMPONENT EXPORTS)/g,
template: '\t{{name}},\n$1',
type: 'modify',
},
],
description: 'New React Component',
prompts: [
…
],
})
};
All new components are automatically added to the index.js file.

Related

Add element-ui components to element plus in main.js vue 3

I'm trying to figure out how to change elementu-ui components to element-plus. Part of my migration from vue 2 to vue 3. I find the documentation isn't clear how to register components in vue 3 in the main.js file.
This is the error I get
"export 'Tree' was not found in 'element-plus'
warning in ./src/main.js
"export 'default' (imported as 'Vue') was not found in 'vue'
Here's my main.js file
import Vue, { createApp, h } from 'vue'
import Vue, { createApp, h } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import {
Button,
Select,
Option,
Dropdown,
TableColumn,
Checkbox,
Badge,
Divider,
Tag,
DropdownItem,
Pagination,
Table,
DropdownMenu,
Tree,
Tooltip,
} from 'element-plus'
import lang from 'element-plus/lib/locale/lang/en'
import locale from 'element-plus/lib/locale'
const getCookieConsent = localStorage.getItem('Cookie acceptance')
if (typeof getCookieConsent !== 'undefined' && getCookieConsent === 'true') {
FullStory.init({ orgId: '14C6AX' })
Vue.prototype.$FullStory = FullStory
}
locale.use(lang)
Vue.component(Tree.name, Tree)
Vue.component(Button.name, Button)
Vue.component(Divider.name, Divider)
Vue.component(Checkbox.name, Checkbox)
Vue.component(Pagination.name, Pagination)
Vue.component(Tag.name, Tag)
Vue.component(Badge.name, Badge)
Vue.component(Table.name, Table)
Vue.component(TableColumn.name, TableColumn)
Vue.component(Select.name, Select)
Vue.component(Dropdown.name, Dropdown)
Vue.component(DropdownItem.name, DropdownItem)
Vue.component(DropdownMenu.name, DropdownMenu)
Vue.component(Tooltip.name, Tooltip)
Vue.component(Option.name, Option)
createApp({
render: () => h(App)
}).use(router).use(store).mount('#app')
In Vue 3, it is not possible (or at least it shouldn't be done that way) to register components globally. You have to create a Vue app using createApp, and then register components for this app.
Also, the element-plus documentation explains everything you need to know to import their components.
// main.js
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// Create your Vue 3 app
const app = createApp(App)
// Choice #1: register all components. Impacts global bundle size
app.use(ElementPlus, {
// options
})
app.mount('#app')
If you want to use treeshaking, just import the components when you need them:
// my-component.vue
// Choice #2: import and register components as you need them
import { ElTree } from 'element-plus'
export default {
components: {
ElTree
}
}
Try to import all components with the prefix El, they are exported this way apparently.
I update my package and the previous code not work any more. At last I modified some code and it works.
1, vite.config.js remove
{
libraryName: 'element-plus',
libraryDirectory: 'es',
style(name) {
return `element-plus/theme-chalk/${name}.css`;
},
}
])
2, main.js the past use(component) to remove. Change to:
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus, {
// options
})
app.component("ElSubmenu", ElMenu.SubMenu); // ElSubmenu seems special to register like this

How to make a component more readable if it has multiple props as arguments?

I have large component where I am passing data from parent via slots, everything works as expected but I have one big problem which is very irritating to me, How I can to destructure ({partDetails, setUniqValue, openModal, setData, setPrices, setBoxImages, setZoomImage, setSelectedPartDetails}) this arguments so that my component becomes slightly more attractive, I want to achieve this result using typescript, but I am not sure what is best practice for it.
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { MaterialIcons } from "#expo/vector-icons";
import { componentStyle } from '../styles';
import { PickOfferBoxHeader } from './PickOfferBoxHeader/PickOfferBoxHeader';
import { ConditionRow } from './Rows/ConditionRow';
import { WarrantyRow } from './Rows/WarrantyRow';
import { PriceRow } from './Rows/PriceRow';
import { GradeRow } from './Rows/GradeRow';
import { AntDesign } from "#expo/vector-icons";
import { IIIpartDetails } from '../../../controllers/offers/interfaces';
import { IPickpartDetails, IuniqueValue, IPickData, Imodal } from '../../../screens/offers/interfaces';
import { ImagesRow } from './ImageRow/ImageRow';
interface IPickOfferBoxProps {
partDetails: IPickpartDetails,
setUniqValue: React.Dispatch<React.SetStateAction<IuniqueValue>>,
openModal: () => void,
setData: React.Dispatch<React.SetStateAction<IPickData[]>>
setPrices: React.Dispatch<React.SetStateAction<number>>
setZoomImage: React.Dispatch<React.SetStateAction<Imodal>>,
setSelectedPartDetails:React.Dispatch<React.SetStateAction<IIIpartDetails | undefined>>
setBoxImages: any,
}
export const PickOfferBox: React.FC<IPickOfferBoxProps> = ({partDetails, setUniqValue, openModal, setData, setPrices, setBoxImages, setZoomImage, setSelectedPartDetails}) => {
return (
<p>
asdasdad
</p>
);
}
Consider component composition in react.
Or you might try something like effector in react to communicate between components, or create local store for this component and it will not need props, you gonna derive them from store.

How to use quill-image-drop-module in Vue 3?

I use vueup/vue-quill for Vue 3 and want to use kensnyder/quill-image-drop-module.
This is my code :
Main.js
import { QuillEditor } from '#vueup/vue-quill';
import '#vueup/vue-quill/dist/vue-quill.snow.css';
import Quill from 'quill';
import { ImageDrop } from 'quill-image-drop-module';
Quill.register('modules/imageDrop', ImageDrop)
createApp(App).component('QuillEditor', QuillEditor).mount('#app')
Editor.vue
<template>
<QuillEditor :modules="modules" theme="snow" />
</template>
<script>
import { QuillEditor } from '#vueup/vue-quill';
import '#vueup/vue-quill/dist/vue-quill.snow.css';
export default {
components: {
QuillEditor,
},
data() {
return {
modules: {
imageDrop: true,
},
};
}
}
</script>
If I run the code above, I got an error :
How to fix this error?
Are quill-image-drop-module works on Vue 3?
Provide to <QuillEditor> a prop called toolbar (ex. toolbar='minimal').
vue-quill is creating options for Quill and only when toolbar prop is present it creates an object key modules that it uses to register other modules.

Where to import other React component from if you are importing for Reacr component?

I have such folder hierarchy:
src/
components.tsx
components/
anyComponent.tsx
anyComponent1.tsx
components.tsx is the entry point:
export { Input } from './components/Input';
export { Label } from './components/Label';
export { Textarea } from './components/Textarea';
export { RadioButton } from './components/RadioButton';
export { ModernRadioButton } from './components/ModernRadioButton';
export { ModernRadioButtonGroup } from './components/ModernRadioButtonGroup';
What should I write in my anyComponent1.tsx that is located in the components folder?
import { anyComponent } from './anyComponent';
import { anyComponent } from '../components'; (entry point)
Result: Error. Dependency cycle detected.
Component1.tsx:
import { Button } from '../components';
components.tsx:
export { Button } from './components/Button';
export { Component1 } from './components/Component1.tsx
Result: Everything is fine.
components.tsx entry point is used for non-component files, for example App.tsx.
Component1.tsx:
import { Button } from './Button';
components.tsx:
export { Button } from './components/Button';
export { Component1 } from './components/Component1';

How to initialize NCForms library in VueJs

I'm new to Vue CLI, and I'm trying to build a small application. As part of this I want to generate some forms.
I've tested a few libraries, and NCForms seems to do all I need to do. (specifically, I need to handle capturing of multiple arrays).
I tried to initialize the library as described in the documentation - but it fails in the Template saying that it can't find some of the element-ui components.
I'm pretty sure that I've followed the instructions properly - but I must be missing something small.
My main.js file looks like this:
import 'ant-design-vue/lib/style/index.less' // antd core styles
import './#kit/vendors/antd/themes/default.less' // default theme antd components
import './#kit/vendors/antd/themes/dark.less' // dark theme antd components
import './global.scss' // app & third-party component styles
import Vue from 'vue'
import VuePageTitle from 'vue-page-title'
import NProgress from 'vue-nprogress'
import VueLayers from 'vuelayers'
import BootstrapVue from 'bootstrap-vue'
import VueFormulate from '#braid/vue-formulate'
// Form generator: Vue-Form-Generator: https://github.com/vue-generators/vue-form-generator
import VueFormGenerator from 'vue-form-generator'
import 'vue-form-generator/dist/vfg.css'
// Form generator: NCForms: https://github.com/ncform/ncform
import vueNcform from '#ncform/ncform'
// eslint-disable-next-line no-unused-vars
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import ncformStdComps from '#ncform/ncform-theme-elementui'
// REST Calls: Axios: https://github.com/axios/axios
import axios from 'axios'
// Local files
import App from './App.vue'
import router from './router'
import store from './store'
import { i18n } from './localization'
import './antd'
import './registerServiceWorker'
// mocking api
import './services/axios/fakeApi'
Vue.use(BootstrapVue)
Vue.use(VueLayers)
Vue.use(NProgress)
Vue.use(VuePageTitle, {
prefix: 'Nedbank PhishTank | ',
router,
})
// Form generator: Vue-Form-Generator
Vue.use(VueFormGenerator)
// Form generator: NCForms
Vue.use(vueNcform, { extComponents: ncformStdComps, lang: 'en' })
window.$http = Vue.prototype.$http = axios
Vue.use(VueFormulate)
Vue.config.productionTip = false
const nprogress = new NProgress({ parent: 'body' })
new Vue({
router,
store,
nprogress,
i18n,
render: h => h(App),
}).$mount('#app')
My template looks like this:
<template>
<div>
<ncform :form-schema="formSchema" form-name="settings-form" v-model="item" #submit="submit()"></ncform>
<el-button #click="submit()">Submit</el-button>
</div>
</template>
<script>
export default {
data() {
return {
formSchema: {
type: 'object',
properties: {
name: {
type: 'string',
},
},
},
item: {
name: 'Peter Pan',
},
}
},
methods: {
submit () {
this.$ncformValidate('settings-form').then(data => {
if (data.result) {
console.log(this.$data.formSchema.value)
// do what you like to do
alert('finally!!!')
}
})
},
},
}
</script>
The error is:
Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
Am I missing something like registering the individual components? I thought this line would take care of it: Vue.use(vueNcform, { extComponents: ncformStdComps, lang: 'en' })
It feels like I should put something into the "new Vue()" statement - but I'm not sure what....
In main.js, you need to specify: Vue.use(Element);

Categories