Webpack treeshaking with ~/components/ui/index.js and Vue.js - javascript

Hello I have a index in a UI module within my components exporting all components in that folder like so:
~/components/ui/index.js:
import Button from './Button';
import Footer from './Footer';
export { Button, Footer }
And I use it in some page like so:
import { Button } from '~/components/ui';
export default {
components: {
Button,
Footer: () => import('~/components/ui/Footer')
}
}
Now ideally, the Footer component should be split in a different chunk, and only be loaded if needed. This works if I remove it from the exports of ~/components/ui/index.js, like so:
~/components/ui/index.js:
import Button from './Button';
//import Footer from './Footer';
export { Button, /*Footer*/ }
Now this works. But I would like to keep it in the index. And use webpack treeshaking to eliminate the Footer from the default bundle.
How can I achieve this?

Related

External javascripts stop working on vuejs route change

In my vuejs inertia app, external javascript files stop working on any route action like so.
This is code in home.vue:
import Sidebar from "../components/sidebar";
import Topbar from "../components/topbar";
import { Head } from "#inertiajs/inertia-vue3";
import { loadScript } from "vue-plugin-load-script"
export default {
name: "home",
components: {Topbar, Sidebar,Head},
mounted() {
//init menu
loadScript("js/template/jquery/jquery.min.js");
loadScript("js/template/bootstrap/js/bootstrap.bundle.min.js");
loadScript("js/template/metismenu/metisMenu.min.js");
loadScript("'js/template/simplebar/simplebar.min.js");
loadScript("js/template/node-waves/waves.min.js");
loadScript("https://unicons.iconscout.com/release/v2.0.1/script/monochrome/bundle.js");
loadScript("js/template/air-datepicker/js/datepicker.min.js");
loadScript("js/template/air-datepicker/js/i18n/datepicker.en.js");
loadScript("js/template/apexcharts/apexcharts.min.js");
loadScript("js/template/jquery-knob/jquery.knob.min.js");
loadScript("js/template/jqvmap/jquery.vmap.min.js");
loadScript("js/template/jqvmap/maps/jquery.vmap.usa.js");
loadScript("js/template/app.js");
loadScript("js/template/dashboard.init.js");
}
}
The same code is on inventory.vue, but on any route change, even if revisiting home.vue by inertia router, all javascripts being loaded stop working until page refresh. How can i fix this?

Building a Modal component in React without nesting it inside caller component

I'm trying to call a Modal from non-related component (without using any parent-child relationship).
In order to do that I'm trying to use React Redux (as the only way I've seen that can make a connection between two unrelated components). An example on CodeSandbox shows the bare minimum of what I'm trying to do.
My issue is that I don't want to include <Modal> inside the <Button> render function. I want to be able to simply flip the flag in Button.js and <Modal> would appear. This is, from what I understand, is suppose to be one of the advantages of Redux.
It may be look unimportant, but besides the fact that I understand that this is something that can be done and so I want to know how, it will be useful for me in a different piece of code in which if I include <Modal> in the component's render function it'll render the Modal multiple times (I render that component in a list).
Edit:
Just to be clear (as per the example on CodeSandbox), I'm using React classes and not functional components; so no hooks like useDispatch but rather functions like mapDispatchToProps are the way I want to go here.
I will Recommend using React Portal, this will inject it inside the given node, I found it to be the best solution for creating modals. I used same in dailylivedeals.com as a POC
import ReactDOM from "react-dom";
render() {
return ReactDOM.createPortal(
this.props.children,
Document.body
);
}
This is the simplest and cleanest using React's own feature.
Advantage:
Cleaner and simpler
Each modal instance can have its own modal
Multiple modals can be opened ( even from inside a modal)
Modal target can be dynamic (like modal inside modal)
Multiple modal can be controlled using code easily.
Update :
Eloborate code for modal
import React, {useEffect, useState} from "react";
import ReactDOM from "react-dom";
import {Link} from 'react-router-dom';
import "./modal.scss";
let Modal = ({visible, id, hideModal, children, ...props}) => {
let [show, setShow] = useState(false);
useEffect(() => {
setShow(visible);
console.log(visible);
}, [visible]);
let toggleVisibility = () => {
//hideModal();
setShow(!show);
}
useEffect(() => {
if (!show) {
hideModal();
}
}, [show]);
return <div className="modal-scratchpad">
{show ?
ReactDOM.createPortal(
<div id={`${id}-modal-wrapper`} className="sample-modal-wrapper">
<div id={`${id}-modal-backdrop`} className="sample-modal-backdrop">
</div>
<div id={`${id}-modal-container`} className="sample-modal-container">
<div id={`${id}-modal`} className="sample-modal">
{children}
<div onClick={toggleVisibility} className="sample-modal-cross-button">{'\u2716'}</div>
</div>
<style type="text/css">
{"body {" +
"overflow:hidden" +
"}"}
</style>
</div>
</div>
, document.body)
: <></>
}
</div>
};
export default Modal;

How to make a React Component change global CSS

I'm building a Chrome Extension with react-redux, and I want to inject CSS globally with logic.
I trying to do this by making a component import a global CSS file, but it's not working.
styler.js
import React, { Component } from 'react';
require('./styler.css');
class Styler extends Component {
render(){
return (
<div />
)
}
}
export default Styler;
styler.css
:global(.myclass) {
background-color: red;
}
I just get an import error. Is there a way for a react project (or component) to inject CSS globally?
You can use examples of the repo: https://github.com/orbitbot/chrome-extensions-examples also https://developer.chrome.com/extensions/samples
Example of changing css by js:
chrome.tabs.executeScript(null,
{code: "document.body.style.backgroundColor="'"red"'"});
Or using insertCSS: https://developer.chrome.com/extensions/tabs#method-insertCSS
example of usage: Insert CSS from Chrome Extension

React component not re rendering on window.location change

So, I have a react component for a main menu.
Its a list of react-router <Link/> which point to different pages. Each link checks the window.location.path to figure out if it is the active page so that the active menu item can render differently.
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import List from "#material-ui/core/List";
class MainMenu extends Component {
render() {
return (
<List>
<Link to="/products" className={window.location.pathname === "/products" ? "active" : null }>Products</Link>
<Link to="/sales" className={window.location.pathname === "/sales" ? "active" : null }>Sales</Link>
</List>
)
}
}
This was actually working fine, however I now want to connect this menu component to my redux store so that I can display some data from the store inside the menu, as soon as I add the connect function the menu breaks such that when changing pages the "active" class doesn't get applied.
i.e. the component does not update even though window.location.pathname has changed.
I haven't included my store code because I've tested it with dummy reducers that do nothing and also I haven't even used the data anywhere in the component yet.
export default connect(state => ({ foo: state.bar }))(MainMenu);
I'm still not sure whether this issue is to do with connect or if connect has just highlighted a problem with using window.location.pathname and react doesn't know when to update.
Any help is greatly appreciated!
React component won't rerender when you change window.location.pathname. Only state changes will cause component to rerender. You need to listen to window.pathname change and map it to state then only your component will rerender
For such things you can take a look at react-router. Add it your project and such things can be easily achieved.
https://reacttraining.com/react-router/core
The view changes when there's any change in this.state of the
component. I would suggest you to listen to changes in window.location
Here's the code
constructor(){
this.state = {currentPath:window.location.pathname}
window.onbeforeunload = function(e) {
this.setState({currentPath:window.location.pathname})
};
}
and in render()
render() {
return (
<List>
<Link to="/products" className={this.state.currentPath === "/products" ? "active" : null }>Products</Link>
<Link to="/sales" className={this.state.currentPath === "/sales" ? "active" : null }>Sales</Link>
</List>
)
}

react-s-alert, alerts won't popup

So i got a meteor setup with a trello like GUI, based on blaze but with react components and i want to use this library https://www.npmjs.com/package/react-s-alert for showing some popups (feel free to suggest react alternatives).
So i did this, inside a header bar inside client/components/main/header.js:
import React from 'react';
import Alert from 'react-s-alert';
import 'react-s-alert/dist/s-alert-default.css';
import 'react-s-alert/dist/s-alert-css-effects/slide.css';
...
Template.header.events({
'click .js-create-board': Popup.open('createBoard'),
'click .js-alert'() {
Alert.info('Test message')
},
});
But when the function is called, nothing happens..
Anyone can help?
I think you haven't added its initializer component in your main component.
Place sAlert component in your main app renderer component also.
<Alert stack={{limit: 3}} />

Categories

Resources