Adding External JS file to React JS Project

603 views Asked by At

I have gone through many answer but still unable to do it

This Works Perfectly fine when js is included in public folder but this doesn't work when route changes

<script src="%PUBLIC_URL%/JS/jQuery-2.1.4.min.js"></script>
<script src="%PUBLIC_URL%/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script src="%PUBLIC_URL%/JS/app.min.js"></script>

I included this code in my header file to add extrenal js file and works properly but each time the page changes script gets added. I am missing something in loadScript function.

export default class Header extends Component {
    componentDidMount() {
        var loadScript = function (src) {
            var tag = document.createElement('script');
            tag.type = "text/javascript";
            tag.async = false;
            tag.src = src;
            var body = document.getElementsByTagName('body')[0];
            body.appendChild(tag);
        }
        loadScript("/JS/jQuery-2.1.4.min.js");
        loadScript("/BOOTSTRAP-JS/bootstrap.min.js");
        loadScript("/JS/app.min.js");
    }

    render() {
        return (
            <header className="main-header">
                <a href="#" className="logo">
                    <span className="logo-mini"><img src={ImageSmall} /></span>
                    <span className="logo-lg">
                        <img src={RelconImage} style={{ width: '170px', height: 60 }} />
                    </span>
                </a>
                <nav className="navbar navbar-static-top" role="navigation">
                    <img src={menuIcon} className="sidebar-toggle" data-toggle="offcanvas" role="button" style={{ width: '55px' }} />
                    <label style={{ color: 'white', paddingTop: '18px' }} />
                    <div className="navbar-custom-menu">
                        <ul className="nav navbar-nav">
                            <li className="dropdown user user-menu">
                                <a href="#" className="dropdown-toggle" data-toggle="dropdown"> <img src={userIcon} className="user-image" alt="User Image" />
                                    <span className="hidden-xs" />
                                </a>
                                <ul className="dropdown-menu">
                                    <li className="user-header"><img src={userIcon} className="img-circle" alt="User Image" />
                                        <p>Relcon</p></li>
                                    <li className="user-footer">
                                        <div className="pull-right">
                                            <a className="btn btn-info">SIGN OUT</a>
                                        </div>
                                    </li>
                                </ul>
                            </li>
                            <li><a href="#" data-toggle="control-sidebar"><img src={VendorLogo} style={{ width: '200px', height: '50px', marginTop: '-10px' }} /></a></li>
                        </ul>
                    </div>
                </nav>
            </header>
        );
    }
}

to stop appending I used the following code but this does not work when menu changes

componentDidMount() {
    var loadScript = function (src, file_id) {
        var scriptexist = document.getElementById(file_id);
        if (!scriptexist) {
            var tag = document.createElement('script');
            tag.type = "text/javascript";
            tag.async = false;
            tag.src = src;
            tag.id = file_id;
            var body = document.getElementsByTagName('body')[0];
            body.appendChild(tag);
        }
    }
    loadScript("/JS/jQuery-2.1.4.min.js", 'jqjs');
    loadScript("/BOOTSTRAP-JS/bootstrap.min.js", 'bootsjs');
    loadScript("/JS/app.min.js", 'appjs');
}

this is how it gets append to body every time page changes

<script type="text/javascript" src="/JS/jQuery-2.1.4.min.js"></script>
<script type="text/javascript" src="/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script type="text/javascript" src="/JS/app.min.js"></script>
<script type="text/javascript" src="/JS/jQuery-2.1.4.min.js"></script>
<script type="text/javascript" src="/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script type="text/javascript" src="/JS/app.min.js"></script>
These are my other sub-page and ComponentWillMountFunction is in Header page.

class dashboard extends Component {
    render() {
        return (
            <div>
                <Header />
                <Sidebar />
                <div className="content-wrapper">
                    <section className="content-header" />
                    <section className="content">
                        {/* Page Content Here */}
                    </section>
                </div>
                <Footer />
            </div>
        );
    }
}
export { dashboard }

class transactions extends React.Component {
    render() {
        return (
            <div>
                <Header />
                <Sidebar />
                <div className="content-wrapper">
                    <section className="content-header" />
                    <section className="content">
                      This are transactions
                    </section>
                </div>
                <Footer />
            </div>
        );
    }
}
export { transactions }

this is my App file

import React from 'react';
import { history } from '../helpers';
import { login } from '../login';
import { dashboard } from '../dashboard';
import { transactions, inventorys } from '../reports';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
class App extends React.Component {
  render() {
    return (
      <Router history={history}>
        <Switch>
          <Route exact path="/" component={login} />
          <Route path="/dashboard" component={dashboard} />
          <Route path="/transaction" component={transactions} />
          <Route path="/inventory" component={inventorys} />
          <Redirect from="*" to="/" />
        </Switch>
      </Router>
    );
  }
}

export { App };

1

There are 1 answers

12
Tan Dat On

The scripts are going to run in the browser. So you have to use absolute paths. And the paths must be served in your server.

Normally, for express, there is a middleware for you to choose which locations static files should be served. https://expressjs.com/en/starter/static-files.html

Check your code, maybe there is

app.use(express.static('public'))

Now for your case, if you want to serve scripts file from src/component/ui. You may modify the code like this:

app.use(express.static('src/component/ui'))

And now your scripts will be like this:

<script src="/JS/jQuery-2.1.4.min.js" type="text/babel"></script>
<script src="/BOOTSTRAP-JS/bootstrap.min.js" type="text/babel"></script>
<script src="/JS/app.min.js" type="text/babel"></script>