how does webpack import from external url - reactjs

I am using webpack to manage my react application. Now I want to import a dependency from this url:
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=gNO2wKVBNupZfafi0bl0sW3dIKqAHn4l">
traditionally I just put above code on my index.html file. But now how can I let webpack to load this url? And how my react js use that dependency?
when I launch webpack-dev-server, I will get below error:
ERROR in Entry module not found: Error: Cannot resolve module 'http://api.map.baidu.com/api'
Then I use little loader to load the url. Below is the javascript code to use loader:
import $ from 'jquery'
import React from 'react';
import ReactDOM from 'react-dom';
import load from 'little-loader';
import './main.css';
import './component';
import Search from './search/search'
load('http://api.map.baidu.com/api?v=2.0&ak=gNO2wKVBNupZfafi0bl0sW3dIKqAHn4l', function(err){
console.log('err:', err);
});
// document.body.appendChild(component());
ReactDOM.render(<Search />, document.getElementById('search'));
but I still got below error when launch webpack:
ERROR in Entry module not found: Error: Cannot resolve module 'http://api.map.baidu.com/api' in /Users/yzzhao/dev/react-demo/webpack_demo

In the future you should be able to use dynamic requires via System.import.
Webpack 2 will support them natively.
System.import('<url>')
.then(function() {
console.log('Loaded!');
});
If you don't want to wait for it, you could use a script loading library.
Example:
Install:
npm install little-loader --save
Use:
import load from 'little-loader';
load('<url>', (err) => {
})
Or do it manually
function load(url) {
return new Promise((resolve, reject) => {
var script = document.createElement('script')
script.type = 'text/javascript';
script.async = true;
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
})
}
load('<url>')
.then(() => {
console.log('Loaded!');
})
.catch((err) => {
console.error('Something went wrong!', err);
})

Related

Problem with the build in react js, can't find the build folder

I'm trying to use react, serverless and SSR please don't ask me why I don't use next.js, anyway.
i got the next error ERROR in unable to locate '/home/franklinserif/proyects/ssr-develop/build' glob
here is my server index.js code
// index.js
import serverless from "serverless-http";
import express from "express";
import path from "path";
// import middleware
import renderer from "./middleware/renderer";
const app = express();
// root (/) should always serve our server rendered page
app.use("^/$", renderer);
// serve static assets
console.log(path.join(__dirname, "./client", "./build"));
app.use(express.static(path.join(__dirname, "./client", "./build")));
// handler
export const handler = serverless(app);
and this is my renderer file
// renderer.js
import fs from "fs";
import path from "path";
import React from "react";
import ReactDOMServer from "react-dom/server";
// import main App component
import App from "../client/src/App";
export default (req, res, next) => {
// point build index.html
console.log(path.resolve("../client", "./build", "index.html"));
const filePath = path.resolve("../client", "./build", "index.html");
// read in html file
fs.readFile(filePath, "utf8", (err, htmlData) => {
if (err) {
return res.send(err).end();
}
// render the app as a string
const html = ReactDOMServer.renderToString(<App />);
// inject the rendered app into our html and send it
return res.send(
// replace default html with rendered html
htmlData.replace('<div id="root"></div>', `<div id="root">${html}</div>`)
);
});
};
I don't know why I can find the build folder

'Module parse failed' error while lazy loading after react-scripts 3.0.0 update

I am lazy loading components in my React app, and it was working all fine. However, after the react-scripts 3.0.0 update, I keep getting the 'Module Parse failed: Unexpected token' error as follows:
./src/routes/App.js 22:9
Module parse failed: Unexpected token (22:9)
You may need an appropriate loader to handle this file type.
| import { Loader } from '../components/Preloaders/Loader';
| var ClippedDrawer = lazy(function () {
> return import('../components/Drawer');
| });
| var Settings = lazy(function () {
Here is the beginning of the file App.js:
import React, { lazy, Suspense } from 'react';
import {
Router,
Route,
Switch
} from 'react-router-dom';
import { Loader } from '../components/Preloaders/Loader';
const ClippedDrawer = lazy(() => import('../components/Drawer'));
const Settings = lazy(() => import('../containers/Settings/Settings'));
const NotFound = lazy(() => import('../containers/NotFound'));
What is wrong with this and how do I fix it?
Found the solution: (But, please make a backup of your project in case it fails for you).
Delete node_modules
Delete package-lock.json (NOT package.json)
In the terminal:
Run npm install react-scripts#latest
Run npm install
Visit https://github.com/facebook/create-react-app/issues/6673 for more details.

Invariant Violation: Browser history needs a DOM

For the server side, the BrowserRouter will not work and thus StaticRouter is to be used as per documentation. I am doing same but I am still getting the error. Following is my setup
Invariant Violation: Browser history needs a DOM
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter as Router } from 'react-router';
// import our main App component
import App from '../src/App';
const path = require('path');
const fs = require('fs');
export default (req, res) => {
// get the html file created by CRA's build tool
console.log('url : ', req.baseUrl);
const filePath = path.resolve(__dirname, '..', '..', 'build', 'index.html');
fs.readFile(filePath, 'utf8', (err, htmlData) => {
if (err) {
console.error('err', err);
return res.status(404).end();
}
// render the app as a string
const html = ReactDOMServer
.renderToString(<Router location={req.baseUrl}>
<App />
</Router>);
// now inject the rendered app into our html and send it
return res.send(htmlData
.replace('<div id="root"></div>', `<div id="root">${html}</div>`));
});
};

Using webpack to create angular1 and angular2 hybrid app throw upgrade static error

I am trying to use angular upgrade path to use angular1 and angular2 using webpack loader. When I take angular1 and just load angular2 it all works fine and the reason is upgrade static file error which is mentioned below
my angular bootstrap file is as following:
import 'angular2-universal-polyfills/browser';
import { enableProdMode } from '#angular/core';
import { platformUniversalDynamic } from 'angular2-universal';
import { AppModule } from './app/app.module';
import 'bootstrap';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { UpgradeModule } from '#angular/upgrade/static';
// Enable either Hot Module Reloading or production mode
if (module['hot']) {
module['hot'].accept();
module['hot'].dispose(() => { platform.destroy(); });
} else {
enableProdMode();
}
// Boot the application, either now or when the DOM content is loaded
const platform = platformUniversalDynamic();
const bootApplication = () => {
//platform.bootstrapModule(AppModule);
platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
console.info("Angular 2 bootstrapping");
const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap(document.documentElement, ["app"], { strictDi: true });
});
};
if (document.readyState === 'complete') {
bootApplication();
} else {
document.addEventListener('DOMContentLoaded', bootApplication);
}
And the error I am getting is below
Error in ./~/#angular/upgrade/static.js
Module parse failed: C:\TFS\PostAnything\Postanything.Web.Client\node_modules\#angular\upgrade\static.js Line 8: Unexpected token
You may need an appropriate loader to handle this file type.
| * found in the LICENSE file at https://angular.io/license
| */
| export { downgradeComponent } from './src/aot/downgrade_component';
| export { downgradeInjectable } from './src/aot/downgrade_injectable';
| export { UpgradeComponent } from './src/aot/upgrade_component';
# ./ClientApp/boot-client.ts 9:15-49
I have resolved this issue finally by taking guidance from other GitHub repo and created my own to have Angular1 and Angular hybrid app with Webpack.
Click here for Github repo link

create-react-app for server-side rendering

Im using create-react-app tool for building my first react application with react-routes and now I would like to use server side rendering to avoid loading all pages at once.
I followed guides and installed express.js, separated client-side and server-side with .js files and run it with
NODE_ENV=production babel-node --presets 'react,es2015' src/server.js
But I get an error when app is trying to compile sass #import statements. I think I have to serve assets first, but I don't know how to insert webpack functions in server.js logic
create-react-app also has npm run build command for production build and create js and css files, so maybe there is some way to skip assets parts while compiling server.js ?
Server.js file contents
import path from 'path';
import { Server } from 'http';
import Express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import routes from './routes';
import NoMatch from './pages/NoMatch';
// initialize the server and configure support for ejs templates
const app = new Express();
const server = new Server(app);
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// define the folder that will be used for static assets
app.use(Express.static(path.join(__dirname, 'static')));
// universal routing and rendering
app.get('*', (req, res) => {
match(
{ routes, location: req.url },
(err, redirectLocation, renderProps) => {
// in case of error display the error message
if (err) {
return res.status(500).send(err.message);
}
// in case of redirect propagate the redirect to the browser
if (redirectLocation) {
return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
}
// generate the React markup for the current route
let markup;
if (renderProps) {
// if the current route matched we have renderProps
markup = renderToString(<RouterContext {...renderProps}/>);
} else {
// otherwise we can render a 404 page
markup = renderToString(<NoMatch/>);
res.status(404);
}
// render the index template with the embedded React markup
return res.render('index', { markup });
}
);
});
// start the server
const port = process.env.PORT || 3000;
const env = process.env.NODE_ENV || 'production';
server.listen(port, err => {
if (err) {
return console.error(err);
}
console.info(`Server running on http://localhost:${port} [${env}]`);
});
Try installing node-sass and following the official guide
https://create-react-app.dev/docs/adding-a-sass-stylesheet/

Resources